SSH is often required to access Linux machines that run on the Cloud infrastructure. SSH is perfect to keep confidentiality and integrity of data exchanged between two networks and systems. However, this service exposes a new attack surface that could be exploited by a threat agent. The aim of this post is to provide tips on how to reduce the above-mentioned risks by performing hardening of the OpenSSH server. It provides you with a few recommendations on things to tweak to improve security of your OpenSSH server. You will also find some suggestions on how to improve cryptography. (Thanks to Jean-Philippe Aumasson for his help with this part of the blog post. Specialy the Crypto Section).
- #1: Only Use SSH Protocol 2
Disable legacy protocol version 1. SSH-1 is obsolete and should be avoided. SSH-1 has man-in-the-middle attacks problems and security vulnerabilities.
- #2: Change the port number and limit IP binding
To avoid robots and standard scan to your OpenSSH server it’s a good idea to change the port number. To something above 10,000. To bind to 172.20.16.89 and 18.104.22.168 IPs add or correct the following to sshd_config (in etc/ssh/):
Port=22666 ListenAddress 172.20.16.89 ListenAddress 22.214.171.124
If you use use IPv4 only:
- #3: Limit Users’ SSH Access
By default all accounts can login via SSH using their password or a public key. As example allows only sma, sysadm and jpa user to use the system via SSH. Add the following to sshd_config:
AllowUsers sma sysadmin jpa
- #4: Configure Idle Log Out Timeout
Set an idle timeout to avoid unattended ssh session. For example, to 15 minutes. This is up to you! (900 secs = 15 minutes).
Open sshd_config and make sure following values are configured:
ClientAliveInterval 900 ClientAliveCountMax 0
- #5: Disable root login via SSH
The login as root via ssh over a network is not really necessary. Typically, users can use su or sudo to gain root level access. That gives full auditing information about who ran the privileged commands on the system and avoids brute force on the root account. To disable root login via SSH, update sshd_config with the following line:
- #6: Display a “legal notice” (Warning) Banner
Add a warning banner by updating sshd_config with the following line:
An example of /etc/issue file:
Unauthorized access to this system is forbidden and will be prosecuted by law. By accessing this system, you agree that your actions may be monitored if unauthorized usage is suspected.
Ask your legal team for the exact user agreement and legal notice details. You can refer to this whitepaper for more information: Login Warning Banners
- #7: Chroot SSHD (Lock Down Users To Their Home Directories)
By default users are allowed to browse the server directories such as /etc/, /sbin and so on. More information on this, refer to the blog post about the ChrootDirectory directive to create a “Jail”.
- #8: Disable Empty Passwords
- #9: Improve system audit – Logs
Add more information in your logs. Check if LogLevel is set to INFO or DEBUG in sshd_config:
Note: Using the syslog-ng protocole is a good approach to export the events to a secure log collector.
- #10: Patch OpenSSH on regular basis
Keep you OpenSSH server, if possible, up-to-date with the latest security patches. It is recommended using the last stable OpenSSH version.
- #11: Disable Host-Based Authentication
Disable host-based authentication (IP Trust). By updating sshd_config with the following option:
HostbasedAuthentication no IgnoreUserKnownHosts yes IgnoreRhosts yes
- #12: Do not Use anymore Passwords
Consider using 2-Factors AuthN (One Time Password – Cryptographic Token ) or an SSH Public Key.
Refer to OATH standards for One Time Password (2FA). A next post will explain how to integrate OpenSSH with an OTP technology.
To block password authentication, set this directive in sshd_config:
Note: Be carrefull: Keep a copy of your Crypt keys and/or have a way to use a password in case of Crypto Keys lost.
- #13: Improve Cryptography
By default, a key size of 768 bits is used. Current recommendations is 2048 bits. In order to activate the new key delete your current host keys and restart OpenSSH.
Specifies the maximum amount of data that may be transmitted before the session key is renegotiated. (Not supported yet in Debian an need OpenSSH 6.3 min) As example every 256MB, set this directive in sshd_config:
Specifies the available MAC (message authentication code) algorithms. The MAC algorithm is used for data integrity protection. Multiple algorithms must be comma-separated.
Specifies the available KEX (Key Exchange) algorithms. Multiple algorithms must be comma-separated.
Specifies the ciphers allowed for the protocol version 2. Multiple ciphers must be separated by comma.
- #14: Minimize your attack surface:
By default OpenSSH gives 2 minutes to allow a user to authenticate and allows him up to 6 authentication attempts. To minimize the attack surface you can reduce these values. By updating sshd_config with the following option:
LoginGraceTime 30 MaxAuthTries 3
- #15: Mitigate a privileges elevation
Prevent users from being able to set environment options through a SSH connection and potentially break some access restrictions. Set this directive in sshd_config:
The goal of privilege separation is to prevent privilege escalation by containing any corruption within the unprivileged processes. Set this directive in sshd_config:
With this option file permissions and ownerships of user files are checked before accepting a connection. This is normally desirable because novices sometimes accidentally leave their directory or files world-writable. If any check fails, the user will not be able to login. Set this directive in sshd_config:
- #16: Block Forwarding
If you do not use SSH tunneling, you should disable it. By updating sshd_config with the following option:
X11Forwarding no AllowTcpForwarding no GatewayPorts no PermitTunnel no
- # 17: Limit the amount of SSH connections
Specify the maximum number of concurrent unauthenticated connections to the SSH daemon to limit attackers. Adding the following to your sshd_config file will allow 2 unauthenticated connections to your server at the same time.
MaxStartups 2 MaxSessions 3
- …and if you want more security (!)…
You can hide your OpenSSH server port using Port Knocking. Port knocking is a method of externally opening ports by generating a connection attempt on a set of prespecified closed ports.
- Final thoughts
The above are just suggestions, and over time they may change to better suit your needs. You can always do more but all-in-all these settings will help you mitigate risks in order to limit an intrusion into your SSH server. Most of the determined attacks on your server will be based on zero-day vulnerabilities and/or a known OpenSSH vulnerability (OpenSSH Security). Ensure your server is brought up-to-date regularly, and always audit your logs to detect break-ins. Feel free to submit any suggestions.
# Update 1: 2014-01-14 / sma
Thanks to Sébastien Andrivet for the Review / sma – 2014-01 – 14
Thanks Sylvain for the write-up, here’s a possible addition:
OpenSSH 6.2 can now handle multi factor authentication (e.g. require both a public key AND a password). Further details can be found here:
The option ServerKeyBits only affects ephemeral keys when using SSH version 1
Setting this option does not affect SSHv2 at all