Securing SSH with Publicly Accessible Servers

Securing SSH with Publicly Accessible Servers

Just about every IT environment has some sort of remotely managed environment which requires that they have SSH open to the Internet.  Perhaps this is a VPS, dedicated server, or colocation.  Regardless of your reason, the fact is that there is just some times where you need to have SSH open to the internet.

However regardless of if it is necessary doesn’t mean that you should just do it…  One look at your auth.log will reveal that.

 # tail /var/log/auth.log
Feb  5 21:12:32 mail sshd[3105]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser=
Feb  5 21:12:34 mail sshd[3105]: Failed password for invalid user admin from port 1714 ssh2
Feb  5 21:12:35 mail sshd[3107]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser=  user=root
Feb  5 21:12:38 mail sshd[3107]: Failed password for root from port 1817 ssh2

The fact of that matter is that once you have SSH open folks will try and hit it and brute force there way in.  Now there are many ways around this.

1) Move SSH to a non-standard port number.
2) Disable Root Logins over SSH and use non-standard usernames.
3) Use fail2ban to proactively disconnect users who are attempting to brute force your server.
4) Use SSH keys to secure your logins, and disable all password authentication.

Now options 1 and 2 are really just garbage.  They don’t actually do anything with regards to security, they simply obfuscate your environment in the hopes that your attacker will give up and go home.  Option 3 is good, and option 4 is a sledge hammer which is crude in its implementation.

Instead I will be implementing a modified version of option 4.  What we will be doing is allowing Public Key authentication from the entire internet while allowing Password authentication from trusted IP space, this can be an entire IP block, or single IPs.  This relies on the match directive in ssh, so please make sure your version of ssh supports this before attempting.

Configure SSH Keys

# ssh-keygen -t rsa

Copy SSH Keys to your Server

# ssh-copy-id root@yourserver.domain

Validate SSH Key Authentication

If you did it properly then you will not be asked for a password.

# ssh root@yourserver.domain

Secure SSH to Only Allow Password Auth from Trusted Networks

Before you mess with this part ensure you have an alternate way of getting into the system in case you make a mistake which keeps you from using SSH.

In the /etc/ssh/sshd_config disable Password Authentication

# cat /etc/ssh/sshd_config
PasswordAuthentication no

Then add the following to the end of the file, where x.x.x.x and y.y.y.y are your trusted IP addresses, and /32 is used to represent a single IP address.

# cat /etc/ssh/sshd_config
Match Address x.x.x.x/24,y.y.y.y/32
Password Authentication yes

Validate your Configuration

Once everything is configured you can restart ssh and test.

# /etc/init.d/ssh restart