Protect SSH
Server setup | |
← Previous | Next → |
Firewall | DNS server |
If you open port 22 (for SSH access) to the outside world, you'll want to protect it against opportunistic, possibly hostile, login attempts by unauthorised people. There are three tactics you should consider:
- Ensure that all accounts on the SSH server are protected by strong passwords;
- Restrict the IP addresses that can access the SSH port;
- Change the SSH port to something non-standard.
The first item is outside the scope of this page. Note that not all accounts on your computer will allow logins anyway. Those that do will require strong passwords.
Changes to config file
But before that, there are a couple of changes that need to be made to the SSH server's /etc/ssh/sshd_config
file. Disable root logins by changing the line to this
# Authentication: PermitRootLogin no
to prevent attempts to log in as root. Add the line
AllowUsers user1 user2 user3
to only allow SSH access to these users. Then restart the SSH server:
root@server:~# /etc/init.d/ssh restart
Changing the SSH port
If you're using a different port, use one above port 1024 as this is as high as most port scanners routinely go. There are three ways of doing this:
- Change the port sshd listens on
- Use the router to map a non-standard external port to port 22 on the machine on the LAN
- Use the machine's firewall to map a non-standard external port to port 22 on the machine on the LAN
The advantage of the first method is that it doesn't require fiddling with port mappings in firewalls, but it will require the extra port to be opened (and port 22 closed) and all SSH access to that machine to use the new port. The advantage of the other two methods is that you can keep the machine listening on port 22 for connections within your LAN.
Change the port sshd listens on
Change the port specified in /etc/ssh/sshd_config
:
# Run ssh on a non-standard port: Port 1111
(If you want sshd
to listen on several ports, give several Port
lines.)
To connect to this machine, either specify the new port on the command line (ssh -p 1111 user@machine
) or specify the port to use in the client user's ~/.ssh/config
file:
# Client ~/.ssh/config Host myserver HostName 72.232.194.162 User bob Port 1111
Use the router to map a non-standard external port
Use the router's 'virtual servers' or 'services' option. Open the higher port and ensure it maps to port 22 on the target machine. Not all routers can do this port mapping.
Use the machine's firewall to map a non-standard external port
Open the higher port on the router and have it map to the same port on the target machine. Then, modify the prerouting table in the iptables
rule set to map the incoming port to port 22, as used for SSH. Do this by including this fragment in the /etc/iptables.rules
file, listed below.
## ------------------------------------------------------------ # DNAT mappings # # These rules transform the packet destinations of incoming packets. # For instance, make packets coming to port 1111 be sent to port 22 (for SSH) # Change the port that you can use for SSH. # Connections to port 1111 will be mapped to port 22, where # the SSH daemon will hear them. iptables -t nat -A PREROUTING -i $IFACE -p tcp --dport 1111 -j DNAT --to ${IPADDR}:22
Filter connection attempts in the firewall
If you only connect from a few machines, you can restrict connections to those machines using the SSH server's firewall. Modify /etc/iptables.rules
to mention only the IP numbers you want:
## Allow SSH (port 22) iptables -A INPUT -i $IFACE -p tcp --syn -s $LAN --dport ssh -m limit --limit 2/m --limit-burst 10 -j ACCEPT iptables -A INPUT -i $IFACE -p tcp -s $LAN --dport ssh -j ACCEPT iptables -A INPUT -i $IFACE -p tcp --syn -s 123.123.123.123 --dport ssh -m limit --limit 1/m --limit-burst 3 -j ACCEPT iptables -A INPUT -i $IFACE -p tcp -s 123.123.123.123 --dport ssh -j ACCEPT
The first and third rules limit the number of connection attempts that will be allowed. The second and fourth rules restrict other packets to being from the specified IP addresses.
Automatic IP blocking
The final line of defence is to dynamically block IP addresses that are probing SSH (and other) ports. Fail2Ban does this, by watching logs for repeated failed login attempts, then modifying the host's firewall to reject connections from that IP.
- Install Fail2Ban:
root@server:~# aptitude install fail2ban
- Copy
/etc/fail2ban/jail.conf
to/etc/fail2ban/jail.local
, then modify/etc/fail2ban/jail.local
:
ignoreip = 127.0.0.1/8 192.168.1.0/24
- This line prevents Fail2Ban triggering on failed attempts from this network.
- Restart Fail2Ban:
root@server:~# service fail2ban restart
The remaining default settings are sensible: three failed attempts in ten minutes (600 seconds) results in that IP being banned for ten minutes. If you want to change them, adjust the findtime
, maxretry
, and bantime
settings in /etc/fail2ban/jail.local
.
To show the status of all of Fail2Ban's jails, use this command:
root@server:~# fail2ban-client status | sed -n 's/,//g;s/.*Jail list://p' | xargs -n1 fail2ban-client status