Protect SSH

From Smith family
Jump to: navigation, search
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:

  1. Ensure that all accounts on the SSH server are protected by strong passwords;
  2. Restrict the IP addresses that can access the SSH port;
  3. 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:

  1. Change the port sshd listens on
  2. Use the router to map a non-standard external port to port 22 on the machine on the LAN
  3. 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
       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 --dport ssh -m limit --limit 1/m --limit-burst 3 -j ACCEPT
iptables -A INPUT -i $IFACE -p tcp       -s --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 =
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.

See also