Securing SSH on Linux Servers
OpenSSH (or Secure SHell) has become a de facto standard for remote access replacing the telnet protocol. SSH has made protocols such as telnet redundant due, in most part, to the fact that the connection is encrypted and passwords are no longer sent in plain text for all to see. However, a default installation of ssh isn't perfect, and when running an ssh server there are a few simple steps that can dramatically harden an installation.
1. Use Strong Usernames and Passwords
One of the first things you'll notice if you have ssh running and exposed to the outside world is that you'll probably log attempts by hackers to guess your username/password. Typically a hacker will scan for TCP port 22 (the default port on which ssh listens) to find machines with ssh running, and then attempt a brute-force attack against it. With strong passwords in place, hopefully any attack will be logged and noticed before it can succeed.
Hopefully you already use strong passwords, but if you are not then try to choose passwords that contains:
- Minimum of 8 characters
- Mix of upper and lower case letters
- Mix of letters and numbers
- Non alphanumeric characters (e.g. special characters such as ! " £ $ % ^ etc)
The benefits of strong passwords aren't specific to ssh, but have an impact on all aspects of systems security. If you absolutely can't prevent your users choosing weak passwords, then consider using randomly generated or difficult to guess usernames for your user accounts. Additionally, usernames such as administrator or admin are typically common targets. If the bad guys can't guess the username then they can't brute force the password. However, this is still security through obscurity and be aware of information leakage of usernames from things such as email sent from user accounts.
2. Disable Root Logins
SSH server settings are stored in the /etc/ssh/sshd_config file. To disable root logins, make sure you have the following entry:
PermitRootLogin no
and restart the sshd service:
service sshd restart
If you need root access, login as a normal user an use the su or sudo commands.
3. Limit User Logins
SSH logins can be limited to only certain users who need remote access. If you have many user accounts on the system then it makes sense to limit remote access to only those that really need it thus limiting the impact of a casual user having a weak password. Add an AllowUsers line followed by a space separated list of usernames to /etc/ssh/sshd_config. For example:
AllowUsers alice bob
4. Disable Protocol 1
SSH has two protocols it may use, protocol 1 and protocol 2. The older protocol 1 is less secure and should be disabled unless you know that you specifically require it. Look for the following line in the /etc/ssh/sshd_config file, uncomment it and amend as shown:
# Protocol 2,1
Protocol 2
and restart the sshd service.
5. Disable .rhosts Files
SSH can emulate the behavior of the obsolete rsh command. To disable possible insecure access via RSH, update the /etc/ssh/sshd_config file with the following setting:
IgnoreRhosts yes
6. Disable Host-based Authentication
Host-based authentication allows hosts to authenticate on behalf of all or some of the system's users. This type of authentication can be useful for managing computing clusters and other fairly homogeneous pools of machines. However, if this type of authentication method is not needed, it is recommended to disable it. To do so, update the /etc/ssh/sshd_config file with the following setting:
HostbasedAuthentication no
7. Disable Empty Passwords
By default, SSH is typically set to allow authentication for accounts with empty passwords. In addition to ensuring that all user accounts are configured with strong passwords, it is recommended to disable the option in your /etc/ssh/sshd_config file by disabling the PermitEmptyPasswords option, as shown below:
PermitEmptyPasswords no
8. Use a Non-Standard TCP Port
By default, ssh listens for incoming connections on port 22. For a hacker to determine ssh is running on your machine, he'll most likely scan port 22 to determine this. An effective method is to run ssh on a non-standard port. Any unused port will do, although one above 1024 is preferable. Many people choose 2222 as an alternative port (as it's easy to remember), just as 8080 is often known as the alternative HTTP port. For this very reason, it's probably not the best choice, as any hacker scanning port 22 will likely also be scanning port 2222 just for good measure. It's better to pick some random high port that's not used for any known services. To make the change, modify or add the Port line your /etc/ssh/sshd_config file with something similar to the following:
Port 2345
and restart the sshd service. Don't forget to then make any necessary changes to your access lists on your perimeter firewall (Cisco ASA or Sentry Firewall) or in the local iptables.
9. Filter SSH at the Firewall
If you only need remote access from static IP address, then consider filtering connections at your firewall by either adding a firewall rule on Sentry Firewall or your Cisco ASA or in the local iptables to limit access on the SSH port to only specific IP addresses. For example, in iptables this could be achieved with the following type of rule:
iptables -A INPUT -p tcp -s 100.200.30.40 --dport 22 -j ACCEPT
Don't forget to change the port as appropriate if you are running ssh on a non-standard port and remove or modify any other iptables rules that would allow open access to your SSH port. Where possible, filtering at the firewall is an extremely effective method of securing access to an ssh server.
SSH also natively supports TCP wrappers and access to the ssh service may be similarly controlled using hosts.allow and hosts.deny.
If you are unable to limit source IP addresses, and must open the ssh port globally, then local iptables can still help prevent brute-force attacks by logging and blocking repeated attempts to login from the same IP address. For example,
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --set --name ssh --rsource
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent ! --rcheck --seconds 60 --hitcount 4 --name ssh --rsource -j ACCEPT
The first rule records the IP address of each new attempt to access port 22 using the recent module. The second rule checks to see if that IP address has attempted to connect 4 or more times within the last 60 seconds, and if not then the packet is accepted. Note this rule would require a default policy of DROP on the input chain.
Alternatively, you can employ a solution such as fail2ban (through Plesk or as a third-party installation in Linux) or cphulk (through CPanel/WHM) to aid in preventing brute-force attacks.
10. Use Public/Private Key Authentication
Using encrypted keys for authentication offers two main benefits. Firstly, it is convenient as you no longer need to enter a password (unless you encrypt your keys with password protection) if you use public/private keys. Secondly, once public/private key pair authentication has been set up on the server, you can disable password authentication completely meaning that without an authorized key you can't gain access - so no more password cracking attempts.
It's a relatively simple process to create a public/private key pair and install them for use on your ssh server.