I run OpenBSD on Soekris devices and have yet in my life to have this proven to be a poor choice of hardware. For my builds I use flashrd. Part of the design of flashrd is that /var is built from scratch during each boot and is mounted as a memory filesystem:
# mount | grep /var mfs:14425 on /var type mfs (asynchronous, local, nodev, nosuid, size=131072 512-blocks)
While this is a really cool way to do things it does limit the size of your /var filesystem. In my case – on this box is slightly less than 62 MB. Usually this is way more than adequate, but there have been times that the script kiddies have caused me grief by filling /var/authlog with failed ssh login attempts:
Jan 24 06:35:34 firewall sshd[29119]: Invalid user hscroot from 180.131.138.32 Jan 24 06:35:34 firewall sshd[29119]: input_userauth_request: invalid user hscroot [preauth] Jan 24 06:35:34 firewall sshd[29119]: Failed password for invalid user hscroot from 180.131.138.32 port 57894 ssh2 Jan 24 06:35:35 firewall sshd[29229]: Invalid user hscroot from 180.131.138.32 Jan 24 06:35:35 firewall sshd[29229]: input_userauth_request: invalid user hscroot [preauth] Jan 24 06:35:35 firewall sshd[29119]: Connection closed by 180.131.138.32 [preauth] Jan 24 06:35:35 firewall sshd[29229]: Failed password for invalid user hscroot from 180.131.138.32 port 48309 ssh2 Jan 24 06:35:35 firewall sshd[29229]: Connection closed by 180.131.138.32 [preauth]
Once /var is full all sorts of weird things start happening. In my case the firewall would still pass traffic, but dhcpd quits working properly (most likely due to its inability to log and place leases in /var/db/dhcpd.leases) and slowly the hosts on the network relying on dhcp die of attrition as they can no longer renew their leases. It’s gotta be fixed…
The most secure way to go about things would be to close ssh to the outside world. In my case that isn’t really an option, there are times that I’m out of town and if the S hit the F I could potentially lose one of my multiple ways inside the network to fix things. SSH on the outside firewall may someday (albeit it hasn’t yet) become my last hope. My solution is not unique, but it isn’t so ununique that it’s not worth mentioning. It’s all handled inside OpenBSD’s pf.conf file:
1) Create a table to hold the abusers:
table <abuse> persist
2) Make an addendum to your ssh rule that will limit the rate at which connections are allowed. For connections exceeding that limit put the source address in your abuse table using the overload directive. Make sure the scope of the rule is such that it won’t limit other types of connections and also make sure it’s far enough down in your ruleset that other rules won’t hijack your ssh traffic. In my case I used a maximum of 2 connections per 15 minutes. You may wish to loosen that up a bit in case you find yourself remotely connecting to that box often. I’d also suggest making the scope of that rule such that it doesn’t apply to connections coming from trusted networks:
pass in on em2 inet proto tcp from any to (em2) port ssh flags S/SA keep state (max-src-conn-rate 2/15, overload <abuse> flush)
3) Block the abuse table at or near the bottom of your pf.conf. Make sure you don’t have any quick rules up higher that might override this rule. You could put it higher up and use a quick rule, but I like to keep quick out of my ruleset as much as I can just as a matter of preference.
block in from <abuse>
Of course once you’re done setting it all up reload pf:
# pfctl -f /etc/pf.conf
I setup this configuration about 18 hours ago (by necessity, not forward thinking) and have since seen some fun additions to the abuse table:
# pfctl -t abuse -T show 4.49.58.41 54.146.218.7 54.215.165.55 61.160.247.8 87.106.50.214 103.41.124.18 103.41.124.30 103.41.124.31 103.41.124.37 103.41.124.111 104.152.188.150 123.57.134.96 212.83.131.138 221.235.188.205 222.186.34.202 222.219.187.9
Yay it works.
This is just a rehash from the official OpenBSD PF documentation, but unfortunately the search term “block ssh brute force OpenBSD” won’t lead you there.