Ansible playbook to create a baseline configuration after provisioning a new VM
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
Linus Sehn 635902bb5b updated README 3 weeks ago
group_vars make firewall setup more visible and add update README 3 weeks ago
inventory@bb87ca892a bump inventory 4 weeks ago
roles added 'roles/ansible-fsfe-monitoring' 3 weeks ago
.gitignore Initial commit 3 months ago
.gitmodules added 'roles/ansible-fail2ban' 3 weeks ago
Pipfile switched to pipenv to manage ansible version 4 weeks ago
Pipfile.lock switched to pipenv to manage ansible version 4 weeks ago
README.md updated README 3 weeks ago
ansible.cfg added ability to store secrets in vault 3 weeks ago
open_the_vault.sh added ability to store secrets in vault 3 weeks ago
playbook.yml added roles/ansible-fsfe-backup 3 weeks ago
vault_passphrase.gpg added ability to store secrets in vault 3 weeks ago

README.md

Baseline Configuration

The aim of this repository is to organise the baseline configuration to be deployed on all of our host machines.

Usage

First, clone the repository:

git clone --recurse-submodules git@git.fsfe.org:fsfe-system-hackers/baseline.git

To use this repository to provision a new host, you need to activate the virtual environment using pipenv which you can install via pip or your favourite package manager. Then, simply run

pipenv install --dev # install the project's dependencies
pipenv shell         # launch a subshell in the virtual environment

Note that if you run this for multiple servers at once, please add -f 1 as a parameter. Otherwise, rewriting the authorized_keys file that happens during backup initialisation on the remote storage might cause issues if accessed by multiple processes at once.

Roles

The roles used in this playbook are:

Important files

To configure ansible-hardening, ansible-fail2ban or ansible-unattended-upgrades take a look at group_vars/all.yml. This file specifies the default configuration for our hosts and looks as follows:

---
##########################################################################################
# hardening | sshd
##########################################################################################
sshd_accept_env: LANG LC_*
sshd_allow_agent_forwarding: "no"
sshd_allow_tcp_forwarding: "no"
sshd_authentication_methods: any
sshd_banner: /etc/issue.net
sshd_challenge_response_authentication: "no"
sshd_ciphers: chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes256-ctr
sshd_client_alive_count_max: 1
sshd_client_alive_interval: 200
sshd_compression: "no"
sshd_gssapi_authentication: "no"
sshd_hostbased_authentication: "no"
sshd_ignore_user_known_hosts: "yes"
sshd_kerberos_authentication: "no"
sshd_kex_algorithms: curve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group-exchange-sha256
sshd_log_level: VERBOSE
sshd_login_grace_time: 20
sshd_macs: hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512,hmac-sha2-256
sshd_max_auth_tries: 3
sshd_max_sessions: 3
sshd_max_startups: 10:30:60
sshd_password_authentication: "no"
sshd_permit_empty_passwords: "no"
sshd_permit_root_login: "yes"
sshd_permit_user_environment: "no"
sshd_port: 22
sshd_print_last_log: "yes"
sshd_print_motd: "no"
sshd_rekey_limit: 512M 1h
sshd_strict_modes: "yes"
sshd_subsystem: sftp internal-sftp
sshd_tcp_keep_alive: "no"
sshd_use_dns: "no"
sshd_use_pam: "yes"
sshd_x11_forwarding: "no"
##########################################################################################
# hardening | firewall
##########################################################################################
ufw_outgoing_traffic:
  - 22
  - 53
  - 80
  - 123
  - 443
  - 853
ufw_incoming_traffic:
  - 80
  - 443
##########################################################################################
# fail2ban
##########################################################################################
fail2ban_loglevel: INFO
fail2ban_logtarget: /var/log/fail2ban.log
fail2ban_ignoreself: "true"
fail2ban_ignoreips: "127.0.0.1/8 ::1"
fail2ban_bantime: 600
fail2ban_findtime: 600
fail2ban_maxretry: 5
fail2ban_destemail: "system-monitoring@lists.fsfe.org"
fail2ban_sender: root@{{ ansible_fqdn }}
fail2ban_jail_configuration:
  - option: enabled
    value: "true"
    section: sshd
  - option: mode
    value: "aggressive"
    section: sshd
##########################################################################################
# unattended-upgrades
##########################################################################################
unattended_origins_patterns:
  # security updates
  - "origin=Debian,codename=${distro_codename},label=Debian-Security"
  # updates including non-security updates
  - "origin=Debian,codename=${distro_codename},label=Debian"
unattended_autoclean_interval: 21
unattended_download_upgradeable: 1
unattended_automatic_reboot: true
unattended_verbose: 1
unattended_mail: "system-monitoring@lists.fsfe.org"
unattended_mail_only_on_error: true

Obviously, if you want to configure a new host, say example.fsfeurope.org, simply add a file called example.fsfeurope.org.yml to the host_vars directory and overwrite the configuration above as you see fit. For more information on which variables take precedence over others, refer to the Ansible documentation

Testing

This is work in progress.

Further Information

General Hardening Setup

This guideline by the InfoSec team at Mozilla was used to decide which algorithms to allow. They were further pruned with the help of ssh-audit from the Debian repositories.

fail2ban Setup

unattended-upgrades Setup

Firewalls in Debian with Docker

This is only an issue when Docker is run with root privileges as it then patches itself into iptables. See this article for mitigating that.