Securing SSH

Keeping in line with not using the root account on Debian/Ubuntu machines, let’s remove the ability to login via root without a lot of inconvenience. We’ll do this by disabling the ability to log in as root via SSH with a password and removing the SSH directory so we can’t login with a key pair either.

Removing the SSH Directory

Here’s the task to remove root’s SSH directory and any configuration or authorized key pairs contained within. You might already be running this as root if you put it early enough in your playbook. Otherwise, be sure to add sudo like below:

- name: Remove Root SSH Configuration
  file: path=/root/.ssh state=absent
  sudo: yes

Locking Down the SSH Service

The following task copies a file. In this case, we’re editing the “/etc/ssh/sshd_config” file. We’re going to change three things in this file, then upload it and replace the existing file. I’ve included the default file below so you can make the edits. Where should you store the file? There’s a specific way to structure files in Ansible, but for now, just make a directory on your local machine named “files” and Ansible will automatically pick it up during the “copy” module. First the task:

- name: Copy Secured SSHD Configuration
  copy: src=sshd_config_secured dest=/etc/ssh/sshd_config owner=root group=root mode=0644
  sudo: yes

Now, for the edits. Let’s begin at line 28 and change “PermitRootLogin” to “no”

# Authentication:
PermitRootLogin no

Then, we move down to line 52 to disable password logins for all users. Instead, you’ll authenticate with the SSH key pairs like we set up in a previous lesson.

PasswordAuthentication no

Finally, we disable X11 window forwarding. For those that don’t know about X11, it’s the main Linux windowing library. IT can run graphical programs on the server, and then relay the visual interface to your computer using the “forwarding” feature. It’s a great idea, but not useful in most day to day operations in my experience unless you have a program you just need to keep. We go to line 64 to make this edit:

X11Forwarding no

Restarting the SSH Service

In order to apply the changes in the configuration, we need to restart SSH. Here’s a task that does just that. Be careful where you put this because it may result in a connection break since Ansible runs over SSH. Most of the time, it won’t be an issue.

- name: SSHD Restart
  service: name=sshd state=restarted enabled=yes
  sudo: yes

That’s all there is to it. You’re now unable to login as root or log in with a password, even as another user.

Final Playbook and SSH Files

Playbook:

---
- name: Secure the SSH Service
  hosts: all
  tasks:

    - name: Remove Root SSH Configuration
      file: path=/root/.ssh state=absent
      sudo: yes

    - name: Copy Secured SSHD Configuration
      copy: src=sshd_config_secured dest=/etc/ssh/sshd_config owner=root group=root mode=0644
      sudo: yes

    - name: SSHD Restart
      service: name=sshd state=restarted enabled=yes
      sudo: yes

SSH:

# Package generated configuration file
# See the sshd_config(5) manpage for details

# What ports, IPs and protocols we listen for
Port 22
# Use these options to restrict which interfaces/protocols sshd will bind to
#ListenAddress ::
#ListenAddress 0.0.0.0
Protocol 2
# HostKeys for protocol version 2
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_dsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_ed25519_key
#Privilege Separation is turned on for security
UsePrivilegeSeparation yes

# Lifetime and size of ephemeral version 1 server key
KeyRegenerationInterval 3600
ServerKeyBits 1024

# Logging
SyslogFacility AUTH
LogLevel INFO

# Authentication:
LoginGraceTime 120
PermitRootLogin no
StrictModes yes

RSAAuthentication yes
PubkeyAuthentication yes
#AuthorizedKeysFile %h/.ssh/authorized_keys

# Don't read the user's ~/.rhosts and ~/.shosts files
IgnoreRhosts yes
# For this to work you will also need host keys in /etc/ssh_known_hosts
RhostsRSAAuthentication no
# similar for protocol version 2
HostbasedAuthentication no
# Uncomment if you don't trust ~/.ssh/known_hosts for RhostsRSAAuthentication
#IgnoreUserKnownHosts yes

# To enable empty passwords, change to yes (NOT RECOMMENDED)
PermitEmptyPasswords no

# Change to yes to enable challenge-response passwords (beware issues with
# some PAM modules and threads)
ChallengeResponseAuthentication no

# Change to no to disable tunnelled clear text passwords
PasswordAuthentication no

# Kerberos options
#KerberosAuthentication no
#KerberosGetAFSToken no
#KerberosOrLocalPasswd yes
#KerberosTicketCleanup yes

# GSSAPI options
#GSSAPIAuthentication no
#GSSAPICleanupCredentials yes

X11Forwarding no
X11DisplayOffset 10
PrintMotd no
PrintLastLog yes
TCPKeepAlive yes
#UseLogin no

#MaxStartups 10:30:60
#Banner /etc/issue.net

# Allow client to pass locale environment variables
AcceptEnv LANG LC_*

Subsystem sftp /usr/lib/openssh/sftp-server

# Set this to 'yes' to enable PAM authentication, account processing,
# and session processing. If this is enabled, PAM authentication will
# be allowed through the ChallengeResponseAuthentication and
# PasswordAuthentication.  Depending on your PAM configuration,
# PAM authentication via ChallengeResponseAuthentication may bypass
# the setting of "PermitRootLogin without-password".
# If you just want the PAM account and session checks to run without
# PAM authentication, then enable this but set PasswordAuthentication
# and ChallengeResponseAuthentication to 'no'.
UsePAM yes