How I configure SSH for security

I use SSH for logging in to remote systems (even as remote as accross the same table) but more and more login attempts happen on systems facing the public Internet. Really simple, old-fashioned password-guessing attempts, trying to find a valid login/pw combination, usually from a system taken over this way, hoping to not show up in the logs too much on the receiving side.

But I do read the logs. And I get annoyed when some idiot from Italy or Brazil (it seems all the little crackers live in those countries) tries over and over and over and over ... 10, 20, or 900 attempts to guess a password.

Adjusting logging levels

First I had to adjust logging a bit so I do have entries of all attempts. I adjusted the LogLevel to VERBOSE so I get to see the accounts tried.

Config settings to make only the right people use ssh (without PAM)

On some machines I only allow public key logins. This will confuse not so very hightech users! Config snippet from /etc/ssh/sshd_config:
RhostsAuthentication no
PermitRootLogin no
StrictModes yes
AllowGroups users

PasswordAuthentication no
RSAAuthentication yes
PubkeyAuthentication yes
But only the right people (and no system account!) are member of that group 'users'. For other machines not reachable from the public Internet (via either IPv4 or IPv6), I allow passworded logins.
hostsAuthentication no
PermitRootLogin no
StrictModes yes
AllowGroups users 

PasswordAuthentication yes
RSAAuthentication yes
PubkeyAuthentication yes
So, logs are still filled with...
Dec 19 23:21:02 firewall sshd[29417]: Connection from 222.234.2.94 port 56761
Dec 19 23:21:02 firewall sshd[29417]: Enabling compatibility mode for protocol 2.0
Dec 19 23:21:04 firewall sshd[29417]: Could not reverse map address 222.234.2.94.
Dec 19 23:21:05 firewall sshd[29420]: Connection from 222.234.2.94 port 56836
Dec 19 23:21:05 firewall sshd[29420]: Enabling compatibility mode for protocol 2.0
Dec 19 23:21:07 firewall sshd[29420]: Could not reverse map address 222.234.2.94.
Dec 19 23:21:07 firewall sshd[29423]: Connection from 222.234.2.94 port 56906
Dec 19 23:21:08 firewall sshd[29423]: Enabling compatibility mode for protocol 2.0
Dec 19 23:21:09 firewall sshd[29423]: Could not reverse map address 222.234.2.94.
Dec 19 23:21:10 firewall sshd[29426]: Connection from 222.234.2.94 port 56979
Dec 19 23:21:10 firewall sshd[29426]: Enabling compatibility mode for protocol 2.0
Dec 19 23:21:12 firewall sshd[29426]: User games not allowed because none of user's groups are listed in AllowGroups
Dec 19 23:21:12 firewall sshd[29426]: Could not reverse map address 222.234.2.94.
Dec 19 23:21:13 firewall sshd[29431]: Connection from 222.234.2.94 port 57044
Dec 19 23:21:13 firewall sshd[29431]: Enabling compatibility mode for protocol 2.0
Dec 19 23:21:15 firewall sshd[29431]: Could not reverse map address 222.234.2.94.
Dec 19 23:21:16 firewall sshd[29434]: Connection from 222.234.2.94 port 57124
Dec 19 23:21:16 firewall sshd[29434]: Enabling compatibility mode for protocol 2.0
Dec 19 23:21:18 firewall sshd[29434]: Could not reverse map address 222.234.2.94.
Dec 19 23:21:18 firewall sshd[29437]: Connection from 222.234.2.94 port 57195
Dec 19 23:21:19 firewall sshd[29437]: Enabling compatibility mode for protocol 2.0
Dec 19 23:21:21 firewall sshd[29437]: Could not reverse map address 222.234.2.94.
Dec 19 23:21:21 firewall sshd[29440]: Connection from 222.234.2.94 port 57275
Dec 19 23:21:21 firewall sshd[29440]: Enabling compatibility mode for protocol 2.0
but you know all those attempts are thwarted. But the other side does not take a hint (the answering bits of ssh show that password logins won't work).

Config settings with FreeBSD and PAM

With FreeBSD 5.x and PAM things are about the same. I first thought I had to redo AllowGroups in PAM but found out later that keyword still works.

Firewalling repetitive tries in Linux

What I added recently is a bit of firewalling rules using the ipt_recent module in the Linux kernel (recent versions). This module allows firewall rules that fire when some other rule has fired recently.

The rules look like:

iptables -t filter -A INPUT -j LOGREJECT --protocol tcp --destination-port ssh \
--syn -m recent --name ssh --update --seconds 60 --hitcount 3
iptables -t filter -A INPUT --protocol tcp --destination-port ssh --syn \
-m recent --name ssh --set
The second rule will add a source address to the list 'ssh' (to add new ones) and the first rule will be hit when an address reaches hitcount 3 in 60 seconds. LOGREJECT is a rule that logs hits (up until a certain amount per second) and sends tcp rejects:
iptables -t filter -N LOGREJECT
if [ "$WANTLOG" == "yes" ]; then
    $IPTABLES -t filter -A LOGREJECT -m limit --limit 1/second -j LOG \
	--log-level debug --log-prefix 'FW reject: '
fi
iptables -t filter -A LOGREJECT -j REJECT --protocol tcp \
--reject-with tcp-reset
iptables -t filter -A LOGREJECT -j REJECT
Now, the logs look like this:
Dec 21 03:38:55 firewall sshd[6629]: Connection from 202.170.95.5 port 58504
Dec 21 03:38:55 firewall sshd[6629]: Enabling compatibility mode for protocol 2.0
Dec 21 03:38:57 firewall sshd[6629]: User root not allowed because none of user's groups are listed in AllowGroups
Dec 21 03:38:57 firewall sshd[6629]: Could not reverse map address 202.170.95.5.
Dec 21 03:38:58 firewall sshd[6634]: Connection from 202.170.95.5 port 59122
Dec 21 03:38:58 firewall sshd[6634]: Enabling compatibility mode for protocol 2.0
Dec 21 03:39:01 firewall sshd[6634]: User root not allowed because none of user's groups are listed in AllowGroups
Dec 21 03:39:01 firewall sshd[6634]: Could not reverse map address 202.170.95.5.
Dec 21 03:39:02 firewall sshd[6639]: Connection from 202.170.95.5 port 59879
Dec 21 03:39:02 firewall sshd[6639]: Enabling compatibility mode for protocol 2.0
Dec 21 03:39:05 firewall sshd[6639]: User root not allowed because none of user's groups are listed in AllowGroups
Dec 21 03:39:05 firewall sshd[6639]: Could not reverse map address 202.170.95.5.
After which the entries continue in the firewall log:

Dec 21 03:39:05 firewall kernel: FW reject: IN=ppp0 OUT= MAC= SRC=202.170.95.5 DST=xx.yy.zz.00 LEN=60 TOS=0x00 PREC=0x00 TTL=56 ID=59465 DF PROTO=TCP SPT=60528 DPT=22 WINDOW=5840 RES=0x00 SYN URGP=0
Dec 21 03:39:06 firewall kernel: FW reject: IN=ppp0 OUT= MAC= SRC=202.170.95.5 DST=xx.yy.zz.00 LEN=60 TOS=0x00 PREC=0x00 TTL=56 ID=23935 DF PROTO=TCP SPT=60563 DPT=22 WINDOW=5840 RES=0x00 SYN URGP=0
Dec 21 03:39:06 firewall kernel: FW reject: IN=ppp0 OUT= MAC= SRC=202.170.95.5 DST=xx.yy.zz.00 LEN=60 TOS=0x00 PREC=0x00 TTL=56 ID=11545 DF PROTO=TCP SPT=60810 DPT=22 WINDOW=5840 RES=0x00 SYN URGP=0
Dec 21 03:39:06 firewall kernel: FW reject: IN=ppp0 OUT= MAC= SRC=202.170.95.5 DST=xx.yy.zz.00 LEN=60 TOS=0x00 PREC=0x00 TTL=56 ID=40006 DF PROTO=TCP SPT=60821 DPT=22 WINDOW=5840 RES=0x00 SYN URGP=0

For now, most stuff gets stopped.

Firewalling repetitive tries in Linux with fail2ban

Fail2ban can detect repetitive failed tries from the same IP and block it easily. The above recipe can't see the difference between failed and allowed attempts (some software doesn't mind constantly restarting ssh connections). Fail2ban analyzes the logfiles and sees the difference.

Firewalling repetitive tries in FreeBSD

Where the above is a nearly common recipe found in multiple places (I couldn't find the right person to credit for it), the same kind of recipe for FreeBSD is hard to find. My google-fu kept failing me, I found: FreeBSD security mailing list: SSH scans vs connection ratelimiting and OpenBSD mailing list archive on this issue Time for lots of reading of man pf.conf(5). And building a test rig on a local machine, because I want to understand stuff before I test it on a machine in a colo...

At the moment I use Bruteforceblocker. This program parses the logfiles from ssh daemon(s) and keeps tabs on hosts that try too often and adds them to the pf table for blocking ssh attempts. Works ok, although I had to make a few changes to make it see attempts for valid accounts that cannot login via ssh.

Conclusion

Finding the right balance between ease-of-use (especially for the people with less experience in computer security ;)) and security is quite hard.
Comments about this page and updates are welcome. E-mail is the preferred contact method.
Koos van den Hout (koos+website@idefix.net)