Automate SSH Hardening with Ansible

Automate SSH Hardening with Ansible

In this lightning fast tutorial we’ll go through automating SSH server hardening using Ansible. This tutorial should work with either debain or fedora based systems, the installation process may differ based on distro. It requires that you have a remote sudo user on a remote machine with SSH Keys configured. You can see my tutorial here on configuring SSH Keys: https://phoenixignited.tech/setup-ssh-keys/

This tutorial aims to be beginner friendly without being an Intro to Ansible.

LINKS: 

Official Ansible Site: https://www.ansible.com/

Ansible Docs: https://docs.ansible.com/

Installing Ansible

Installing Ansible on Ubuntu is as easy as:

							
							
					sudo apt update
sudo apt install software-properties-common
sudo add-apt-repository --yes --update ppa:ansible/ansible
sudo apt install ansible				
			

And on Fedora / RHEL based systems: 

							
							
					sudo dnf install ansible				
			

Creating Our Ansible Playbook

Next we will setup our environment and create the necessary files:

							
							
					mkdir Ansible-SSH-Harden && cd Ansible-SSH-Harden && touch inventory.ini && touch ansibleplay.yaml && touch Hardened-SSHD-CONFIG				
			

Next we will add our host(s) in the inventory.ini file, these are the remote machines that Ansible will control, open the inventory.ini file with vim, nano, etc. and add: 

							
							
					[myhosts]
Server_Name ansible_host=<server_ip> ansible_user=<username> ansible_connection=ssh ansible_ssh_private_key_file=/path/to/private/ssh/key				
			

Replace all of the variables with your desired values, and repeat for as many hosts as needed.

Next open the ansibleplay.yaml file and enter:

							
							
					- name: Copy the hardened SSHD_CONFIG file to the remote server
  hosts: myhosts
  become: yes
  tasks:
   - name: Copy the hardened SSHD_CONFIG file to the remote server
     ansible.builtin.copy:
        src: ./Hardened-SSHD-CONFIG  # Path to your local sshd_config
        dest: /etc/ssh/sshd_config      # Destination path on the remote system
        owner: root
        group: root
        mode: '0600'                    # Secure permissions
     notify:
        - Restart sshd
  handlers:
    - name: Restart sshd
      service:
        name: sshd
        state: restarted				
			

This is our playbook, it includes the tasks to copy the hardened sshd_config file to the remote server, instructs ansible which hosts to apply the playbook to, etc.

Finally we will edit our Hardened-SSHD-CONFIG file. This file is a hardened sshd_config file, be sure to change the Port and AllowUsers values to your required values and change any other settings according to your setup.

							
							
					Port <custom_port>
PermitRootLogin no
MaxAuthTries 3
MaxSessions 10
PubkeyAuthentication yes
PasswordAuthentication no
PermitEmptyPasswords no
KbdInteractiveAuthentication no
UsePAM yes
AllowAgentForwarding no
AllowTcpForwarding no
X11Forwarding no
PrintMotd no
ClientAliveInterval 600
ClientAliveCountMax 3
LoginGraceTime 30s
UseDNS no
MaxStartups 10:30:60
AllowUsers <your_username>

# Optional hardening settings
#ChallengeResponseAuthentication no
#KerberosAuthentication no
#GSSAPIAuthentication no
#HostKeyAlgorithms ecdsa-sha2-nistp256,ssh-ed25519,rsa-sha2-512,rsa-sha2-256
#Ciphers aes256-gcm@openssh.com,aes256-ctr
#MACs hmac-sha2-512,hmac-sha2-256
#Banner /etc/issue.net				
			

Once we have created and configured the above files we can run the ansible playbook with:

							
							
					ansible-playbook -i inventory.ini ansibleplay.yaml -K				
			

Ansible will ask you for the BECOME password, this is the sudo password for the user on the remote machine that Ansible is using. 

You should see:

							
							
					ansible-playbook -i inventory.ini ansibleplay.yaml -K 
BECOME password: 

PLAY [Copy the hardened SSHD_CONFIG file to the remote server] *****************

TASK [Gathering Facts] *********************************************************
[WARNING]: Platform linux on host Server-Name is using the discovered Python
interpreter at /usr/bin/python3.10, but future installation of another Python
interpreter could change the meaning of that path. See
https://docs.ansible.com/ansible-
core/2.17/reference_appendices/interpreter_discovery.html for more information.
ok: [Server-Name]

TASK [Copy the hardened SSHD_CONFIG file to the remote server] *****************
ok: [Server-Name]

PLAY RECAP *********************************************************************
Server-Name                : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

				
			

That’s a wrap! 

Walter Miely is a tech entrepreneur and CEO of Phoenix Ignited Tech You can find him on Linkedin. This material is licensed under the CC BY 4.0 License LEGAL DISCLAIMER: The content provided here is provided AS IS, and part of, or the entirety of this content may be incorrect. Please read the entireLegal Disclaimer here.