There is nothing quite like reading your (ssh) logs to instil a healthy dose of paranoia. While ssh is a powerful tool, it is a common target for “script kiddies” .
In this tutorial I will show you several methods to help increase the security of your ssh server. My preference is to start with tools already available with a default installation and I personally tend to avoid additional services, such as denyhosts or fail2ban.
I advise you start with proper configuration of the ssh server (sshd_config) and next take a look at ssh key authentication, TCPWrapper, and use of a firewall.
I will cover additional services (denyhosts/fail2ban) last.
IMHO the single most important change you can make is to use ssh key authentication and disable password authentication. Use of ssh keys is more detail here
If you do not have physical access to your ssh server, take care you do not lock yourself out using these methods (not that I have ever locked myself out mind you).
Configuration of the server is done by editing /etc/ssh/sshd_config and then restarting the ssh server. The following options are available:
AllowUsers / AllowGroups / DenyUsers / DenyGroups
By default, any user on the system is allowed to log in via ssh. By specifying a limited group of users allowed to log in (via ssh) you increase security by preventing a cracker to log in under a misconfigured system user.
You can specify which users or groups are allowed to access ssh. The (general) syntax is:
AllowUsers user1 user2 user3
You may specify a user@client by IP address or hostname:
AllowUsers email@example.com/24 firstname.lastname@example.org
See also : Restricting User Logins
Change the default listening port
This piece of advice is, IMO, security through obscurity. Changing the default port will certainly quiet the logs, but is unlikely to deter a determined cracker. Changing the default port has the disadvantage of then having to configure your ssh clients to use a non-default port.
To change to an alternate port, edit /etc/ssh/sshd_config and change the Line “Port 22” to your preferred port.
Use key authentication
Assuming you are using ssh keys, disable login via password authentication.
IMHO, this is the single most important configuration option.
# Change to no to disable tunnelled clear text passwords
# Specifies whether password authentication is allowed. The default is “yes”.
Reduce the number of login attempts per connection
This specifies the number of attempts a user has to enter a password (for each authentication method) per connection attempt. Once the number of failures reaches half this value, additional failures are logged. The default is 6. If you set iptables to block an ip address after 3 failed attempts to connect , a cracker would have 18 attempts to enter a password (3 new connections X 6 login attempts per connection).
Limit the login grace time
The grace time is the amount of time one has to enter a password and establish a connection. The server disconnects after this time if the user has not successfully logged in. The default is 120 (seconds). Take care in reducing this time below 30 seconds or so, especially with the use of long or complex passwords.
If the value is 0, there is no time limit.
This option as you might guess increases the information sshd sends to the logs (log file varies with distro). From the man page – Gives the verbosity level that is used when logging messages from sshd. The possible values are: QUIET, FATAL, ERROR, INFO, VERBOSE, DEBUG, DEBUG1, DEBUG2 and DEBUG3. The default is INFO. DEBUG and DEBUG1 are equivalent. DEBUG2 and DEBUG3 each specify higher levels of debugging output. Logging with a DEBUG level violates the privacy of users and is not recommended.
Restrict X forwarding
Do you tunnel X (graphical) applications? If not, disable this option.
# X11Forwarding yes
Restrict port forwarding
Restrict root login
Root login is a script kiddie / cracker Holy Grail and IMO should be either disabled or at a minimum root login via a password should be rejected.
Or force root to use a key:
“without-password” here is a bit confusing and means root is restricted and can not log in using password authentication. From the man page – If this option is set to ”without-password” password authentication is disabled for root.
Root would be permitted to log in via alternate methods (ssh keys or Kerberos for example).
Changes to the /etc/ssh/sshd_config file take effect when the ssh server is restarted.
sudo service ssh restart
su -c “service sshd restart”
See also man sshd config
TCP Wrapper is often over looked, but easy learn and deploy. TCP Wrapper is an ACL (Access Control List) and can be used to limit access to the SSH (and other services).
The configuration files are /etc/hosts.allow and /etc/hosts.deny
Changes to these configuration files take effect immediately (no need to restart the ssh server).
hosts.allow takes precedence over hosts.deny. If a host is listed in both hosts.allow and hosts.deny , ssh access will be granted.
You may use wildcards for matches or even external files.
The major disadvantage of TCPWrapper is you would need to know where uses are expecting to connect from. TCPWrapper does not work as well if the user is mobile and without a known ip address or hostname.
One has several options with firewall configuration. A detailed discussion of Firewalls and iptables is beyond this page. I will, however, list a few common tools and options to get you started. If you are new to iptables, you could start with My iptables page, Linux Firewalls Using iptables, orFedora Solved iptables Howto.
Uncomplicated FireWall (UFW) is available on Debian/Ubuntu and in fact UFW is “the default” tool used to configure iptables in Ubuntu. UseGUFW if you wish a graphical front end.
Basic syntax of UFW would be:
sudo ufw enable
sudo ufw allow 22/tcp
sudo ufw default deny
Or to limit by ipaddress:
sudo ufw allow proto tcp from 192.168.1.0/24 to 192.168.1.10 port 22
See also: Ubuntu sever guide UFW
Fedora graphical firewall configuration tool
In Fedora use the graphical firewall tool “system-config-firewall”. The firewall tool is in the menu as well.
Alternately you may learn to use iptables. Iptables has several additional features including the ability to black list an ip address after failed attempts.
sudo iptables -A INPUT -p tcp –dport 22 -m state –state NEW -m recent –set –name SSH –rsource -j ACCEPT
sudo iptables -A INPUT -m recent –update –seconds 600 –hitcount 8 –rttl –name SSH –rsource -j DROP
“–hit count” is the number of new connections. Keep in mind each new connection gives multiple opportunities to enter a password. If you use scp, use a higher hitcount as each file will be a new ssh session.
“–seconds” How long an ipaddress will be blacklisted. 10 minutes is usually sufficient to deter most “script kiddies”.
You may install additional services to increase security. Keep in mind these services need to be configured and may introduce additional vulnerabilities
Denyhosts is ssh specific.
The configuration file for Denyhosts is well commented, very complete, and, IMHO, you should read it after installing this service. Denyhosts can send email alerts and track problematic ip addresses in a database. In addition, you may connect to and contribute to an external database if you wish.
Fail2ban is also popular and is not limited to ssh.