Maximizing SSH Security Service in the Cloud
SSH service running on port 22 is one of the most widely used services on the Internet. There are numerous reasons for its widespread use, among which is direct access to the remote system over a security encrypted communication channel. SSH service distinguishes among lesser used SSH-1 and most common SSH-2 versions. SSH was developed to replace insecure protocols like Telnet and rsh/rexec, which communicate over unencrypted communication channels by sending messages in plaintext.
Configuration Options
Despite SSH being very secure by itself, there are still various configuration options that can be used to harden SSH security. Most common security options related to the sshd2 daemon running on port 22 are read from /etc/sshd/sshd_config and are presented in the table below.
Learn Cloud Security
Table 1: Configuration options in /etc/ssh/sshd_config
Harden SSH Access
Systems in the public cloud are usually accessible from anywhere on the Internet. When SSH access is enabled (most of the time it is), an attacker might use a dictionary or bruteforce attack to try to get access to the system. Most of the time, there aren't any security measures in place that would limit the number of connection attempts or allow only certain IPs from reaching the server. Therefore, attackers might use a botnet to bruteforce the SSH password, which results in gaining faster access to the system.
In order to protect against such attacks, we can use various security implications that harden the security of SSH servers.
TCP Wrappers
TCP wrappers can be used to specify which IPs are allowed/denied access to the SSH server by utilizing the /etc/hosts.allow and /etc/hosts.deny files. To check whether the sshd daemon was compiled with TCP wrappers, we can issue the ldd command to check whether the libwrap is one of the shared libraries of the executable.
An example of good security is adding your own IP address into /etc/hosts.allow to prevent locking yourself out of the server. By specifying your IP address as allowed, that IP will not be blocked even if you issue a bruteforce attack against one of the users.
DenyHosts
We've already presented that attackers are often trying to bruteforce the password used by users that have access to the SSH server. There are multiple solutions available, but a widely used option is DenyHosts, which will be described here.
DenyHosts monitors invalid login attempts and blocks the originating IP from where the authentication requests are coming from. To enable the protection, we basically have to install the denyhosts package by using our package manager like apt-get. Then we have to edit the /etc/denyhosts.conf configuration file and change the SMTP settings to allow sending emails to the administrator upon blocking a certain IP. After editing the configuration file, we only have to restart the denyhosts service.
Port Knocking and Single Packet Authorization
Port knocking is a technique used together with a firewall to open specific ports upon receiving a port knock. We've already said that SSH is often enabled in cloud servers, because of a need for remote administration, but in such cases port 22 needs to be open in order for clients to be able to connect to the server. With port knocking this needn't be the case –most of the time, ports to access the SSH server can be closed and can open only on a specific port knock.
Port knocking is a technique which uses packet headers to communicate secret information to the server in order to open specific port. Secret information transferred to the server to open specific ports can be encoded by using different techniques:
- Port Knocking using Port Sequence: the secret knock can be embedded as an ordered sequence of ports for which SYN packets need to be received in order for secret knock to be valid. When the correct sequence of SYN packets to correct ports is received, a client will be allowed to access the port. This method is basically quite limited, as it implements security through obscurity, because an attacker can still bruteforce the order of ports for which SYN packets needs to be sent. Other attacks, such as packet relaying attack, are also possible and defeat the port sequence port knocking security measure: this is because packets needed to be sent to the remote server are always the same and do not change, which makes them easy to sniff and replay.
- Single Packet Authorization using Packet Payload: by using this technique, the secret information is not embedded in packet headers, but rather in a packet payload. Prior to issuing a port knocking sequence, a secure encrypted communication channel is established with the server, which prevents replay attacks, because packets are never the same, since a proper measure of randomness is achieved during the connection establishment. Therefore, even if the attacker is able to sniff every packet exchanged during port knocking, he will not be able to replay them. This option is also safer to use, because the usual packets sent during port knocking don't look like port scanning attacks, so the firewall won't block them.
The packet payload port knocking technique can be used by installing and configuring fwknop client/server. First we have to install the fwknop-server by using the apt-get:
[plain]
# apt-get install fwknop-server
First, we have to edit the /etc/fwknop/fwknop.conf configuration file and change the appropriate configuration option. We shouldn't change much really; we should set our email address in the EMAIL_ADDRESSES variable and set the interface network card on which SSH is listening to PCAP_INTF (usually the default 'eth0' value is correct). The PCAP_FILTER directive should be set to the UDP port where the fwknop will be listening for the knock.
Edit the /etc/fwknop/access.conf configuration file to set the IP addresses the fwknop is allowed to open – the OPEN_PORTS directive. The KEY specifies the key that must be shared between the client and the server in order for the port knocking to be successful. Note that the KEY needn't be comprised of numbers only, but letters and special characters can also be used.
Then we need to edit iptables rules to deny access to the SSH server, by REJECTing connections to destination port 22 as presented below. Note that the first iptables rule will lock you out of the server if you're running it over SSH, so you first need to add a rule to temporarily allow your IP no matter what. The iptables-save command saves the current iptables rules to a file, which is important so we can restore from it later on upon booting the computer – otherwise access to the SSH server won't be rejected. The last command saves the iptables-restore command to the /etc/rc.local, which will be called upon boot to restore the current iptables rules.
[plain]
# iptables -A INPUT -i ppp0 -p tcp -dport 22 -j REJECT
# iptables-save > /root/firewall-config
# echo "iptables-restore < /root/firewall-config" >> /etc/rc.local
Let's now scan the server by using the nmap command. Below we can see the picture when the server was scanned prior to running fwknopd.
Next we can start fwknopd by running a simple command as presented below.
[plain]
# fwknopd
Afterwards access to the SSH server will be prohibited. If we scan port 22 again, we'll see it's filtered.
To instruct fwknop to add appropriate iptables rules to allow access to the server, we have to execute the command below, where the must be substituted with the server's IP address and needs to be substituted with PCAL_FILTER port where the knock will be sent to.
[plain]
# fwknop --server-port <port> --access 'tcp/22' --source-ip --destination <ip>
After running the command, we'll have to provide the KEY secret key, which was set in the /etc/fwknop/access.conf configuration file. Entering the password to the fwknop command every time before gaining access to the server would be tedious, which is why we can save the password to .knock-keyfile and it will be automatically applied to the fwknop command. To do that we first have to save the password to the .knock-keyfile in our home directory, where the needs to be substituted with the IP of the server and the with the actual secret knock key.
[plain]
# cat "<ip>: <key>" >> ~.knock-keyfile
When running the fwknop command, we should use an additional --get-key parameter to instruct fwknop to read the .knock-keyfile, which contains the secret key.
[plain]
# fwknop --server-port <port> --access 'tcp/22' --source-ip --destination <IP> --get-key ~/.knock-keyfile
Conclusion
In this article we've presented different ways of protecting and hardening our SSH server. Since the SSH server is quite often one of the few services available in a public cloud environment, it's important to properly secure it by using different security implications. By following the tutorial above, attackers won't be able to determine whether the SSH server is present or not, let alone bruteforcing the password or using any other attack vector to cause harm or possibly gain access to the system.
Learn Cloud Security
References
[1] sshd_config - OpenSSH SSH daemon configuration file,
http://unixhelp.ed.ac.uk/CGI/man-cgi?sshd_config+5.