commit 5b331363e90816a60531122461b99e6ed7628208 Author: Jordan Atwood Date: Sun Apr 17 22:14:14 2022 -0700 Add server setup playbook diff --git a/server-setup/group_vars/all b/server-setup/group_vars/all new file mode 100644 index 0000000..31a0be4 --- /dev/null +++ b/server-setup/group_vars/all @@ -0,0 +1,4 @@ +--- +# Variables listed here are applicable to all host groups + +username: "{{ lookup('env', 'USER') }}" diff --git a/server-setup/roles/fail2ban/tasks/main.yml b/server-setup/roles/fail2ban/tasks/main.yml new file mode 100644 index 0000000..288ec6a --- /dev/null +++ b/server-setup/roles/fail2ban/tasks/main.yml @@ -0,0 +1,7 @@ +--- +# This playbook installs and enables fail2ban with its default config. + +- name: Install fail2ban + ansible.builtin.apt: + name: fail2ban + state: present diff --git a/server-setup/roles/harden-openssh/files/harden.conf b/server-setup/roles/harden-openssh/files/harden.conf new file mode 100644 index 0000000..51b3649 --- /dev/null +++ b/server-setup/roles/harden-openssh/files/harden.conf @@ -0,0 +1,74 @@ +# Hardened SSHD config +# Reference: https://www.digitalocean.com/community/tutorials/how-to-harden-openssh-on-ubuntu-20-04 +# See the sshd_config(5) manpage for details + + +## Authentication + +# Enable public key authentication +PubkeyAuthentication yes + +# Disable PAM (when enabled, it can improperly allow access to locked accounts) +# For more info, see https://arlimus.github.io/articles/usepam/ +UsePAM no + +# Disable password authentication +PasswordAuthentication no + +# Disable rhosts authentication +IgnoreRhosts yes + +# Disable challenge-response authentication +ChallengeResponseAuthentication no + +# Disable kerberos authentication +KerberosAuthentication no + + +## Login + +# Disable root login +PermitRootLogin no + +# Disallow empty passwords +PermitEmptyPasswords no + +# Set maximum authentication attempts, prevent brute-force attacks +MaxAuthTries 3 + +# Restrict authentication time between connect and auth +LoginGraceTime 20 + +# Use DNS hostname checking +UseDNS yes + + +## Security + +# Disable X11 forwarding +X11Forwarding no + +# Disable environment variable passing +PermitUserEnvironment no + +# Disable forwarding/tunneling +AllowAgentForwarding no +AllowTcpForwarding no +PermitTunnel no + +# Deny vulnerable SSH protocol 1 +Protocol 2 + +# Disable verbose ssh banner +DebianBanner no + +## Other features + +# Print motd after interactive login +PrintMotd yes + + +## Notes + +# Restricting user shell: https://www.digitalocean.com/community/tutorials/how-to-harden-openssh-on-ubuntu-20-04#step-3-restricting-the-shell-of-a-user +# User-specific hardening: https://www.digitalocean.com/community/tutorials/how-to-harden-openssh-on-ubuntu-20-04#step-4-advanced-hardening diff --git a/server-setup/roles/harden-openssh/handlers/main.yml b/server-setup/roles/harden-openssh/handlers/main.yml new file mode 100644 index 0000000..e1cfb2f --- /dev/null +++ b/server-setup/roles/harden-openssh/handlers/main.yml @@ -0,0 +1,12 @@ +--- +# OpenSSH hardening handlers. + +- name: validate sshd config + ansible.builtin.command: "sshd -t" + listen: "reload sshd config" + +- name: restart sshd + ansible.builtin.service: + name: sshd + state: restarted + listen: "reload sshd config" diff --git a/server-setup/roles/harden-openssh/tasks/main.yml b/server-setup/roles/harden-openssh/tasks/main.yml new file mode 100644 index 0000000..78b465f --- /dev/null +++ b/server-setup/roles/harden-openssh/tasks/main.yml @@ -0,0 +1,9 @@ +--- +# This playbook installs a hardened OpenSSH server configuration and restarts +# the service. + +- name: install hardened OpenSSH server config + ansible.builtin.copy: + src: harden.conf + dest: /etc/ssh/sshd_config.d/harden.conf + notify: reload sshd config diff --git a/server-setup/roles/ufw/tasks/main.yml b/server-setup/roles/ufw/tasks/main.yml new file mode 100644 index 0000000..587e698 --- /dev/null +++ b/server-setup/roles/ufw/tasks/main.yml @@ -0,0 +1,17 @@ +--- +# This playbook installs ufw, allows the OpenSSH profile, then starts the +# service. + +- name: install ufw + ansible.builtin.apt: + name: ufw + state: present + +- name: enable OpenSSH ufw profile + community.general.ufw: + rule: allow + name: OpenSSH + +- name: enable ufw + community.general.ufw: + state: enabled diff --git a/server-setup/roles/user/tasks/create-user.yml b/server-setup/roles/user/tasks/create-user.yml new file mode 100644 index 0000000..769cfff --- /dev/null +++ b/server-setup/roles/user/tasks/create-user.yml @@ -0,0 +1,18 @@ +--- +# This playbook creates a sudo-enabled user matching the execution user's name. + +- name: create new user + ansible.builtin.user: + name: "{{ username }}" + groups: + - sudo + append: yes + +# Required to prevent user lockout because PAM will be disabled +- name: set impossible password for user + ansible.builtin.command: "usermod -p '*' {{ username }}" + +- name: copy ssh public key from host + ansible.posix.authorized_key: + user: "{{ username }}" + key: "{{ lookup('file', '/home/{{username}}/.ssh/id_rsa.pub') }}" diff --git a/server-setup/roles/user/tasks/main.yml b/server-setup/roles/user/tasks/main.yml new file mode 100644 index 0000000..925a88d --- /dev/null +++ b/server-setup/roles/user/tasks/main.yml @@ -0,0 +1,9 @@ +--- +# Create new user (with username matching host's username) and allow sudo +# escalation without password. (because this new user will not have a password) + +- name: Include create user tasks + include_tasks: create-user.yml + +- name: Include passwordless sudo tasks + include_tasks: passwordless-sudo.yml diff --git a/server-setup/roles/user/tasks/passwordless-sudo.yml b/server-setup/roles/user/tasks/passwordless-sudo.yml new file mode 100644 index 0000000..bbffe08 --- /dev/null +++ b/server-setup/roles/user/tasks/passwordless-sudo.yml @@ -0,0 +1,9 @@ +--- +# This playbook modifies the sudoers config to allow passwordless sudo. + +- name: allow passwordless sudo for sudo group users + ansible.builtin.lineinfile: + path: /etc/sudoers + regexp: "^%sudo" + line: "%sudo\tALL=(ALL:ALL) NOPASSWD: ALL" + validate: "visudo -cf %s" diff --git a/server-setup/setup-and-harden.yml b/server-setup/setup-and-harden.yml new file mode 100644 index 0000000..7c7fa8f --- /dev/null +++ b/server-setup/setup-and-harden.yml @@ -0,0 +1,34 @@ +--- +# This playbook sets up a new server by creating your user account, hardening +# OpenSSH's configuration, and installing ufw and fail2ban. + +- name: create user + hosts: all + remote_user: root + + roles: + - user + +- name: harden OpenSSH + hosts: all + remote_user: "{{ username }}" + become: yes + + roles: + - harden-openssh + +- name: install ufw + hosts: all + remote_user: "{{ username }}" + become: yes + + roles: + - ufw + +- name: install fail2ban + hosts: all + remote_user: "{{ username }}" + become: yes + + roles: + - fail2ban