Securing SSH Service


SSH service is very widely used in the open source infrastructure setups. Due to its small footprint on network, as well as ease of installation and maintenance, SSH replaces many remote shells in the modern data centers.

Though SSH stands for Secure Shell, it is found to be highly vulnerable to security attacks if sufficient care is not taken by system administrators, during the installation and configuration. This article talks about such challenges and solutions.


HOW SSH WORKS

Before we talk about securing SSH, it is imperative to understand how the protocol works and the bells and whistles provided for security configurations. Please refer to Fig1 which shows protocol stack which forms the SSH services. Similar to Telnet, the Secure Shell (SSH) protocol runs as a daemon service on Linux servers, while the client uses an SSH client utility such as putty to connect to the server. SSH is available on Windows as well as Unix platforms, and is widely used one Linux infrastructures. By default it uses TCP port 22 for communication. Unlike telnet, SSH uses cryptography for authenticating client and server, and also for the data transfer purposes, thus ensuring data confidentiality and data integrity. Its communication has three basic steps, client-server handshake, and authentication and secures data exchange. During handshake phase, both the sides exchange information about SSH protocol version and the cipher algorithms they support (which are typically the combinations of asymmetric, symmetric encryption and hashing algorithms) and compression algorithms. Unlike SSL, in SSH the server sends the first data block to the client.

As for authentication, the server is authenticated using host key, whereas the client typically stores the key fingerprint at some predefined location and validates it later in the process. Please see the table below which show supported client authentication methods.


Client Authentication Method Description
Public Authentication Client and Server has key pairs and exchange public keys during authentication process
Password Authentication Plain text password for the given login user is used for authentication
Host based Authentication Limits client access to a particular host/hosts
Keyboard Authentication Works on the basis of pre-stored security question challenge and answer
Server configuration file /etc/ssh/sshd_config
Client configuration file /etc/ssh/ssh_config
Lists all hosts to be allowed to connect /etc/hosts.allow
Lists all hosts to be denied /etc/hosts.deny
Presence of this file refuses all users to connect except root /etc/nologin

As for the SSH configuration, the following files and their paths are important to be remembered.


Securing SSH Service

Now let's see how we can use configuration information above, to secure the daemon service. We will go through each relevant setting and its value to be set, to achieve the desired security.

Targeting defaults is the first line of defense. It is a common practice to change default SSH port, this makes it hard for attackers to guess the port on which service is running. Though it doesn't necessarily stop attacks, it simply makes attackers life difficult and hence acts as an important config setting. Disabling root access using passwords should be avoided, instead the root user should be configured to accept cryptographic authentication only. Similarly, disabling access to all users by default and only allowing SSH protocol version 2 should be configured. Following settings in the sshd_config file perform these settings.

# only use protocol version 2

Protocol 2

# Listen on port 88000 instead of default 22

Port 88000

# Whitelist only the allowed users

AllowUsers prashant rajesh

#Optionally deny specific users

DenyUsers mayur

# No root login

PermitRootLogin no

Once these defaults are setup, the next step is to lock down SSH service at network level. The correct thing to do is to allow SSH service listen to only a particular IP address or a range in terms of subnet. It is also advisable to set which IP of the machine the SSH service should be bound to. So in short, we are setting up the "to" address and "from" address for SSH service network traffic, to ensure no other IP addresses should participate in the secure shell communication process. The former setting is to be done in sshd_config file, while the later in hosts.allow file, and is also called as TCP wrapping.

#Listen only on 1.5 local ip address

ListenAddress 192.168.1.5

#Allow connections only from these ip

sshd : 10.0.0.1

Once the network boundaries are set, the next step is to control hosts and authentication methods. We need to ensure those empty passwords are not allowed for any user. In case of better security setup, the password authentication should be disabled altogether, and only public and private key pair based authentication scheme should be in place. Depending on the security situation, it is often desired to disable host based authentication and the remote hosts. Besides, when the users login, they should be presented with a text banner which is usually done from compliance policy enforcement. Prior to the user login, it is possible to setup a time limit, for which the SSHD service should wait for user to actually login. Also if the user is leaving SSH session idle after logging in, there is a mechanism to log the session out. This is important to avoid idle session which the attackers typically look for. For a given connection, SSH can be instructed to shut down connection if a certain number of un-successful attempts are made. This is helpful to thwart brute forcing to some extent. SSH daemon can also be instructed to perform a sanity check on the keyfiles and SSH directories to ensure those are not tampered with.

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

PermitEmptyPasswords no

# Disable the use of passwords completly, only use public/private keys

PasswordAuthentication no

#Ignore remote hosts

IgnoreRhosts yes

#Ensure that a banner shows up

Banner /etc/issue

#Wait for user to login for 60seconds

LoginGraceTime 60

#Set idle timeout to 4minutes and

ClientAliveInterval 240

ClientAliveCountMax 0

#Set maximum auth attempts for a connection

MaxAuthTries 4

# Force permissions checks on keyfiles and directories

StrictModes yes

At this point we have secured the SSH service to a great extent. However it is very essential to configure the monitoring and logging of service, which gives the administrators a visibility into the operations of SSHD service. Following settings are self explanatory and should be tweaked as per the need. The log level can be tuned from Info to Debug 1,2,3 in order to debug a particular SSHD service related problem or intrusion attack.

# Syslog Logging

SyslogFacility AUTH

# set log level

LogLevel INFO

# Print most recent user login time

PrintLastLog yes

Besides above settings, there are configuration tweaks available for advanced SSH setup such as key based authentication, password based authentication etc. It is important to note that while most of the SSHD settings follow standards, few distros follow different configuration keywords and the help manual should be referred to, in such case.

As seen above, while the SSH service offers many important setting by default, those may not be enough for advanced IT infrastructures. Introducing two factor authentication, host based private and public key pair based security, higher encryption standards for data in transit between server and client, are few examples of security mechanisms to be considered. Having a firewall and intrusion prevention system is also advised for mission critical data centers running SSH service on servers that carry important business data or applications. Open source utilities such as fail2ban or DenyHosts should be used to deal with SSH brute force attacks. Regular operating system level patching and SSH service version patching is extremely important for maximum security.