2 min read

Setting up a full Erigon Ethereum node on AWS - Part 2/4 Linux Security hardening with Ansible

Setting up a full Erigon Ethereum node on AWS - Part 2/4 Linux Security hardening with Ansible

This post is part of a multi-series write-up about setting up Erigon on AWS. Here we are focusing on securing the Linux boxes using a set of Ansible roles from DevSec - an open source project that compiles best-known guides for security like the NSA hardening guide or Deutsche Telekom Privacy and Security Assessment process.

Table of contents

  1. Terraforming AWS
  2. Linux Security hardening with Ansible (this guide)
  3. Erigon and RPC Daemon
  4. Metrics and monitoring with Prometheus and Grafana

We are going to use a Server Hardening Automation tool from dev-sec.io. This includes a few baseline Ansible roles that provide some super secure defaults we can run against our servers.

In order to use the hardening roles, we first install them via ansible-galaxy:

ansible-galaxy collection install devsec.hardening

Bastion Server

Here is the minimal playbook setup and folder structure I have for my bastion server.

.
├── bastion.yml
├── production
├── roles
│   └── users
│       └── tasks
│           └── main.yml
└── templates
    └── users
        └── raz
            └── key.pub
~/ethereum_node/ansible

The production file is our manifest and contains the list of servers and IP addresses:

[bastion]
3.xxx.xxx.xxx

[eth_node]
10.0.0.84

[metrics_node]
10.0.0.117

Next up, we create a super simple role called users

---
  - name: Add or update user and set password
    action: user name={{ item.name }}
                  password={{ item.password }}
                  shell=/bin/bash
                  groups=sudo
    with_items: '{{ users }}'

  - name: Change user directory permissions to 750
    file: path=/home/{{ item.name }} state=directory mode=750
    with_items: '{{ users }}'

  - name: Add or update authorized key
    action: authorized_key user={{ item.0.name }} key={{ lookup('file', item.1) }}
    with_subelements:
      - '{{ users }}'
      - pub_keys

This will allow us to define our bastion.yml playbook like so:

---
- hosts: bastion
  become: true
  collections:
    - devsec.hardening
  vars:
    users:
      - name: raz
        # generated using openssl passwd -salt <salt> -1 <plaintext>
        password: '$1$salty$BnuYTcuR3sS3eurvygJ.H1'
        pub_keys:
          - templates/users/raz/key.pub
    sysctl_overwrite:
      # Enable IPv4 traffic forwarding.
      net.ipv4.ip_forward: 1
  roles:
    - users
    - devsec.hardening.os_hardening

Now we can run our command to create our main user and run the os_hardening task (this will take a few minutes):

$ ansible-playbook -i production bastion.yml

If for some reason, this command doesn't work for you (maybe your SSH agent is not configured correctly) you can explicitly pass the user and private key locations:

$ ansible-playbook -i production bastion.yml -u ubuntu --private-key ~/.ssh/aws_cert.cer

Continue

Part 3 of this series is out.