Monday 1 August 2016

Hardening ssh

SSH is designed to be a secure encrypted communication method by default.
But here are a few ways to increase the security provided by ssh.

Given below are a few directives present in the /etc/ssh/sshd_config file which can be tweaked to enhance security:

  • Port (the default port is 22. We can modify it so that ssh listens for incoming connections on a different port)
  • PermitRootLogin (disallow direct root login if set to no)
  • ListenAddress (For servers with multiple IP addresses, this limits the ssh connectivity to one address only)
  • Protocol (value can be 1 or 2. Its 1 by default but 2 is more secure)
  • AllowUsers (With this extreme directive set only the users part of this directive will be allowed to login to the server via ssh denying access to any other users)
  • DenyUsers (Users added to this directive will be denied ssh login access even if they have a fully functional account existing on the server)
  • PermitTTY (If this is set to no then a user will not get a shell on login but will be able to run command remotely via ssh. I'll be demonstrating its usage later in this tutorial)
  • ForceCommand ( allow a user to only run a specified command remotely)

Here is a sample of the tweaks that I did in the sshd_config file:


Once the directives are set you need to restart the ssh service so that the config file is read.

With these directives in place only the sa user can login to the server via port 876.


To take things further if we want to disable the use of password all together & rely on ssh keys only then we can set the PasswordAuthentication directive to no followed by a restart of the ssh service.
With this directive set to no, only those users will be allowed access whose public keys are available on the destination server:



In the above example when I try to login as test user I'm denied access because there are not keys on the destination server. On the other hand I had exchanged the keys for sa user earlier so its allowed access.
To add another layer of security we can also modify the authorized keys file on the destination server to specify that a key pair will be accepted & authenticated only if the connection request comes from a specific host. To do this add from "hostname", before the public key in the authorized_keys file.
Given below is an example:


Now, to go a step even further we can actually change the default file that ssh uses to run.
This is slightly tricky & should be preferably done from the server's console.

Match Address & Match User stanzas:

To allow custom directives to be implemented for connections originating from a specific network or user we apply the Match Address 7 Match User stanzas.

Here is an example of a Match Address stanza:


The result of this stanza is the following for any ssh connections originating from IP address 192.168.44.134:

Only sa user can access the server via ssh
sa user cannot login directly but can only run commands remotely.

Here what happened when I tested the settings:


So from the above screen shot we can understand that the user sa was denied direct login but could run commands remotely.

Now for a quick demo of the Match User stanza.

I created the following Match User stanza in my sshd_config file:


This will allow user sa to only run the script /tmp/test.sh remotely if the user tries to gain access to the server via ssh. I tried it & here's the result:


Please note that adding or updating the stanzas requires a restart of the ssh service.

So, stop the ssh service & run the command /usr/sbin/sshd -f <config file name> to start the service & direct it to use the config file that you've mentioned. For example, I used the file my_sshd_config to configure ssh & the same can be verified by looking for the sshd process in ps -ef output:


For the purposes of this tutorial I had disabled the firewall & selinux. I know it's sounds weird disabling these security measures in a tutorial aimed at hardening. But I wanted the focus here to be solely on hardening of the ssh service. I hope this has been an informative read for you.

You can also allow or deny ssh access to a server for a single node or an entire network as a whole using TCP wrappers i.e, editing the /etc/hosts.allow or /etc/hosts.deny file.

No comments:

Post a Comment

Using capture groups in grep in Linux

Introduction Let me start by saying that this article isn't about capture groups in grep per se. What we are going to do here with gr...