Need of securing sshd
Some system administrators may noticed that attackers have been attempting to login with common usernames and passwords over SSH. In the system logs of /var/log/secure, similar entries to the following for many common usernames (such as “admin”, “guest”, “test”, and “root”) may be seen:
Oct 28 11:11:08 hostname sshd: Illegal user admin from 172.16.59.10 Oct 28 11:11:12 hostname sshd: Failed password for illegal user admin from 172.16.59.10 port 33762 ssh2
Repeated attempts may be indicative of an attacker trying to guess the password to a particular account, especially the root account, by “brute force”. A brute force attack is one where the password is repeatedly guessed until the correct one is found.
How to secure the SSHD daemon?
There are many ways to make SSH more secure. Here we discuss some guidelines.
Using TCP Wrappers
The most simple way to secure the SSH daemon is to selectively deny access to it using features from the tcp_wrappers-libs package. This package is installed by default. tcpwrappers are configured through the files /etc/hosts.allow and /etc/hosts.deny. To completely deny access to the SSH daemon, add the following text to /etc/hosts.deny:
# vi /etc/hosts.deny sshd: ALL
This will completely disable access to the SSH daemon from any client. If there are a few hosts that should be allowed to connect, add the following lines to /etc/hosts.allow:
# vi /etc/hosts.allow sshd: 192.168.0.1, trusted.one-domain.com, 192.168.23.0/24, *.trusted.net
This would allow connections from the IP address 192.168.0.1, the hostname trusted.one-domain.com, the network 192.168.23.0/24, and the domain *.trusted.net while disallowing any other connections. Remember, you need to deny and allow host/networks.
When you have a host within the local corporate network use TCP Wrappers is probably enough since most of the hosts are under your control, so you can ensure a low chance of attack. But What happen if you have a SSHD Service running over internet, or on a non-administered (Hostile) network like a site2site vpn with a provider? You can get more control on access with iptables. Also iptables can give to you more flexibility and robustness.
You can list your rule set with the “iptables -nL –line-numbers” command to see what rules are in place already, this is the default rules that came with the fresh CentOS/RHEL 6 Install:
# iptables -nL --line-numbers Chain INPUT (policy ACCEPT) num target prot opt source destination 1 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED 2 ACCEPT icmp -- 0.0.0.0/0 0.0.0.0/0 3 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 4 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:22 5 REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited Chain FORWARD (policy ACCEPT) num target prot opt source destination 1 REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited Chain OUTPUT (policy ACCEPT) num target prot opt source destination
Then you can add or remove the rules. The next examples on the INPUT chain will insert a rule to iptables at position. Remember that you need to put the rule on a specific position, ie. line 3, just over the default DROP rules, you can specify it writing:
# iptables -I INPUT 3 -p TCP -i eth0 -s 192.168.1.39 --dport 22 -j ACCEPT
Running the following command as root will drop all SSH access to 192.168.1.22:
# iptables -I INPUT [line-number] -p tcp -i eth0 -s 192.168.1.22 --dport 22 -j DROP
Please refer to man iptables for additional options and usage, or autohelp iptables –help for a short summary:
# man iptables # autohelp iptables
If you want to enable some specific host, you can run the following command to allow the access:
# iptables -I INPUT [line-number] -p tcp -i eth0 -s 192.168.1.39 --dport 22 -j ACCEPT
Additionally, one of the best use of a firewall in case of the SSH service on an insecure network is to apply rate-control over the non-secure origins; to do it, you just need to use:
# iptables -I INPUT [line-number] -p tcp --dport 22 -m state --state NEW -m recent --set --name SSH # iptables -I INPUT [line-number] -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 60 --hitcount 12 --rttl --name SSH -j LOG --log-prefix 'SSH-HIT-RATE: ' # iptables -I INPUT [line-number] -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 60 --hitcount 12 --rttl --name SSH -j DROP # iptables -I INPUT [line-number] -p tcp --dport 22 -m state --state NEW -j ACCEPT # on the default fresh-install ruleset this rule is already in place, you can ignore
These 3 rules setup a hitrate of 12 new connection tries by minute, you need to adjust this values according to your needs. All the logs of this rule will appear in the /var/log/messages file, prefix ‘SSH-HIT-RATE’ is used to ease looking for the related entries.
Please take special attention when you test your new rules. If you make a non-critical mistake, you can go back to the previous saved config using “service iptables force-reload“. When the configuration was finalized, you can save your firewall rules with “service iptables save“.
There are other steps that can be taken if restricting access is not possible. This is some of the best practices of the SSHD configuration:
The most highly recommended action, especially as a defense against brute force attacks, would be to prevent root from logging in directly via SSH. To do this you need change the line which reads:
# vi /etc/ssh/sshd_config #PermitRootLogin yes
to the following:
# vi /etc/ssh/sshd_config PermitRootLogin no
This will require that you configure sudo or use su to gain privilege as the user root over the ssh session of a non-root user. Alternatively, you can set up ssh keys for the user root and use below option to allow the user root to log in using keys only.
# vi /etc/ssh/sshd_config PermitRootLogin without-password
Change the specific port other than the default. It is possible to change it to any random number between 1025 and 65535, as attackers will assume that port 22 will be used for the ssh protocol. Find this line in /etc/sshd/sshd_config:
Change it to something like this:
Port number 1101 is an example. Now you need to access to this server to the port 1101 when you do a ssh connection:
$ ssh someuser@ssh-server:1101
Ensure that the server only accept the SSH Protocol Version 2:
# Protocol 2,1 ### hash this entry and make below entry to allo only ssh v2. Protocol 2
Change the time that a user can spend with the login prompt open (value in seconds):
# Default value is 120 seconds. # Adjust this value according your needs. LoginGraceTime 30
This cuts down some kind of DoS attacks that can be done simulating slow logins.
3rd pary apps
To block access to hosts attempting to brute force attack the system, these additional 3rd party packages services can be used:
- fail2ban (EPEL)
- denyhosts (EPEL)
They operate on different layers, providing different approach to act on a specific event.