# Fail2Ban or SSHGuard and brute-force prevention



## nanotek (Jan 14, 2014)

I'm currently running security/py-fail2ban on all my servers to prevent brute-force attacks. Initially, there was a great reduction of spam in my logs. Lately, however, there are pages of input_userauth_request [preauth] entries in my auth.log file. They're not getting anywhere; access is two-factor with pubkey only and root logins are disabled but it's annoying. I mean, there are sometimes dozens of pages I need to scroll through every single day. My PF table is growing exponentially, I've resorted to never unbanning these damned bots, but I wonder if there is another (better) alternative. Someone mentioned security/sshguard, is this program considered better practice among system administrators? Futher, what do you guys do about the auth.log entries? I'm not exaggerating when I say there are dozens of pages worth of failed attempts! Why would there have been an immediate reduction of these entries after first deploying Fail2Ban, only to see a return to previous levels weeks later?


----------



## SirDice (Jan 14, 2014)

I'm guessing you're not getting hit anymore by the 'simple' bots. Those just tried a bunch of accounts, all from the same source IP. They're quite easily blocked. As with everything this weapons-race now shifted towards more distributed scans, instead of a bunch of accounts from one address it's one or two coming from everywhere. Which makes it very hard to distinguish from normal login traffic. 

I don't think sshguard is going to be any better in repelling those distributed attacks though, I'm getting quite a few hits too. The reason I like it over fail2ban is because it has far less dependencies (none, actually  ).


----------



## nanotek (Jan 16, 2014)

You're right; the attacks are also protracted to avoid the attempt/time threshold.

Less dependencies is always a good thing; I prefer a minimalist approach. I might install security/sshguard on one server to try out. Thanks, @SirDice.


----------



## kpa (Jan 16, 2014)

Make sure you read and understand what the different parameters for security/sshguard do. The defaults may not be suitable and there's also some confusion in the port documentation (the manual page is correct, the rc(8) script for the port is incorrect), two of the defaults for the options are set wrong. This is my setup for the PF version of the port I use:


```
sshguard_enable="YES"
sshguard_safety_thresh="30"
sshguard_pardon_min_interval="600"
sshguard_prescribe_interval="7200"
```

The sshguard_safety_thresh (the -a option for sshguard(8)) is the "danger" threshold for blocking an address temporarily for at least sshguard_pardon_min_interval (the -p option for sshguard(8)) seconds. Addresses that get blocked more than once will be blocked for longer time after the first block. The sshguard_prescribe_interval setting (the -s option for sshguard(8)) is the amount of time in seconds an attack is remembered, you may have to lengthen this to counter attackers that send probes at long intervals.


----------



## nanotek (Jan 17, 2014)

Thanks, @kpa. I appreciate the help.


----------



## xy16644 (Feb 14, 2014)

Am I correct in saying that:


```
sshguard_enable="YES"
sshguard_safety_thresh="3"
sshguard_pardon_min_interval="7200"
sshguard_prescribe_interval="43200"
```

After 3 failed login attempts within 2 hours the IP address will be blocked for 12 hours?


----------



## kpa (Feb 14, 2014)

You have the sshguard_pardon_min_interval and sshguard_prescribe_interval meanings mixed up. The first one is the minimum time an IP address will be blocked for when the amount of danger is exceeded, the minimum time is applied the first time an IP address is blocked and on the next time the time increases. The second one is the amount of time an attack is remembered and it's for cases when an attack does not cause the danger limit to be exceeded but one of the subsequent ones may trigger the block.


----------



## xy16644 (Feb 14, 2014)

Many thanks @kpa, I thought I may have it mixed up.

I set it to:


```
sshguard_safety_thresh="3"
sshguard_pardon_min_interval="43200"
sshguard_prescribe_interval="7200"
```

So I can have 3 login attempts within 2 hours and after you are blocked it will be for 12 hours.


----------



## Oko (Feb 15, 2014)

nanotek said:
			
		

> I'm currently running security/py-fail2ban on all my servers to prevent brute-force attacks. Initially, there was a great reduction of spam in my logs. Lately, however, there are pages of input_userauth_request [preauth] entries in my auth.log file. They're not getting anywhere; access is two-factor with pubkey only and root logins are disabled but it's annoying. I mean, there are sometimes dozens of pages I need to scroll through every single day. My PF table is growing exponentially, I've resorted to never unbanning these damned bots, but I wonder if there is another (better) alternative. Someone mentioned security/sshguard, is this program considered better practice among system administrators? Futher, what do you guys do about the auth.log entries? I'm not exaggerating when I say there are dozens of pages worth of failed attempts! Why would there have been an immediate reduction of these entries after first deploying Fail2Ban, only to see a return to previous levels weeks later?



No, no, no! Fail2ban and sshguard are not the way to protect from brute force ssh if you are using PF. If you are running up to date version of PF which can be found only on OpenBSD you need following three lines in your pf.conf. PF has built in ssh brute force attack protection.


```
table <bruteforce> persist
block quick from <bruteforce>
pass log on $ext_if inet proto tcp from any to any port ssh \
    flags S/SA keep state \
    (max-src-conn 100, max-src-conn-rate 15/5, \
     overload <bruteforce> flush global)
```


Btw I am using fail2ban on my RedHat hosts and I played with sshguard on OpenBSD.


----------



## kpa (Feb 15, 2014)

Oko said:
			
		

> nanotek said:
> 
> 
> 
> ...



Could you at least try to explain what is wrong with security/py-fail2ban  or security/sshguard in your opinion? At least for me security/sshguard did everything it promised and very effectively blocked the offenders very fast. I'm all ears for hearing what the problem with it is.

Edit: I also don't see anything in that PF rule that the FreeBSD's pf(4) did not support or am I missing something here?


----------



## Oko (Feb 15, 2014)

kpa said:
			
		

> Could you at least try to explain what is wrong with security/py-fail2ban  or security/sshguard in your opinion? At least for me security/sshguard did everything it promised and very effectively blocked the offenders very fast. I'm all ears for hearing what the problem with it is.


IMHO it is wrong to involve third party application if the PF has already built in capabilities to accomplish the goal. That being said both
sshguard and fail2ban will work. IIRC sshguard is much easier to incorporate into your pf.conf rules but requires another separate daemon.
I opt for fewer daemons any day or night.  




			
				kpa said:
			
		

> Edit: I also don't see anything in that PF rule that the FreeBSD's pf(4) did not support or am I missing something here?


Unlike OpenSSH and OpenSMTPd which came out of the same OpenBSD kitchen PF has never meant to be portable and depends heavily 
on OpenBSD network stack. OpenBSD network stack is very different than FreeBSD network stack (I will refrain from saying better or worse
but for the record I always run OpenBSD on core network infrastructure servers and FreeBSD or DragonFly on file servers). FreeBSD version 
of PF is a couple of year old port of OpenBSD version with some serious FreeBSD customization even improvements but also obsolete syntax.
I honestly thing knowing little bit about IPFW, IPF, and PF that NetBSD made a good decision by developing NPF from ground up for NetBSD.
The latest PF at this point is probably extremely hard to port ot FreeBSD  and I personally have very low opinion of IPFW syntax and how it 
works. FreeBSD is craving for its own modern package filter.


----------



## kpa (Feb 15, 2014)

Well there's something that PF alone can not do and that is reacting to SSH authentication failures. It can only look at the connection rates and block the offender when those are exceeded. Same goes for the additional log file scanning features of security/sshguard, for example scanning of the mail log for POP3/IMAP login failures. There are some sophisticated attack schemes that use probes from many different addresses with one address sending their probes with long intervals, those are very hard to catch by just looking at connection rates.


----------



## Oko (Feb 15, 2014)

kpa said:
			
		

> Well there's something that PF alone can not do and that is reacting to SSH authentication failures.


That is a definition of brute force attack   The original title of post was "brute-force prevention".


			
				kpa said:
			
		

> It can only look at the connection rates and block the offender when those are exceeded. Same goes for the additional log file scanning features of security/sshguard, for example scanning of the mail log for POP3/IMAP login failures.


Scanning mail log for POP3/IMAP login failures is outside of scope of PF. Remember the words of wisdom we learn from Doug McIlroy:"Unix programs should do one thing only, but well."


----------



## kpa (Feb 15, 2014)

I should have written that a bit differently. PF alone is not sufficient in my opinion to counter brute force attacks because of the reasons I stated above, it can only inspect the IP level information and connection rates. You need something on the "higher level" that inspects log files for login failures etc. I mentioned POP3/IMAP because very often the attacks on your IP address(es) is not limited to just the standard SSH port. Other services (including POP3/IMAP) are tried also and if you have a smart enough system watching for the login failures it's then possible to block the offender easier because you have more evidence from more sources that the IP address in question is sending hostile probes.


----------



## Oko (Feb 15, 2014)

kpa said:
			
		

> I should have written that a bit differently. PF alone is not sufficient in my opinion to counter brute force attacks because of the reasons I stated above, it can only inspect the IP level information and connection rates. You need something on the "higher level" that inspects log files for login failures etc. I mentioned POP3/IMAP because very often the attacks on your IP address(es) is not limited to just the standard SSH port. Other services (including POP3/IMAP) are tried also and if you have a smart enough system watching for the login failures it's then possible to block the offender easier because you have more evidence from more sources that the IP address in question is sending hostile probes.



I will concede that you made me think that my original position on this problem might be wrong. I am reading right now sshguard documentation and there is a question in FAQ which addresses the advantage of sshguard over pure PF or NPF solution. I just checked OpenBSD misc archive and there is a long thread which in some sense implies that the best solution is actually combination of pf rules based on max-src-conn and/or max-src-conn-rate which I suggested and sshguard which you advocated.


 I actually appreciate this exchange very much. Thank you!!!


----------



## tnpimatt (Feb 17, 2014)

I'm a big fan of PF and its built in brute-force blocking, but that only scratches the "remote is making too many connections per second" itch.  I'm totally with SirDice about keeping it simple and avoiding additional daemons running. Here's the simplest way to avoid 99.9% of the sshd login attempts:


```
sed -i .bak -e 's/#Port 22/Port 20022/' /etc/ssh/sshd_config
   service sshd restart
```

Add an entry in ~/.ssh/config so you don't have to type in the port number all the time and voila!

When running sshd on a high numbered port isn't practical, sshguard looks pretty great, for a log watching daemon. But why parse logs when nearly every *nix system has already got a wonderfully mature system for blocking incoming connections called tcpwrappers?  I wrote my own SSH blocker (github/msimerson/Sentry) which tracks connections by IP and automatically adds them to hosts.deny, as well as PF, IPFW, etc. Like sshguard, it also handles connections from dovecot, ftpd, and other daemons. But the primary data source isn't log parsing, it's tcpwrappers, like this /etc/hosts.allow entry.


```
sshd : /var/db/sentry/hosts.deny : deny
    sshd : ALL : spawn /var/db/sentry/sentry.pl --connect --ip=%a : allow
```

Sentry gets the remote IP *before* the daemon and syslog, so it sees every connection before the daemon and syslog. The IP is in a fixed (IPv4 or IPv6) format from tcpd so there's no parsing issues or log poisoning issues to contend with. If sshguard had existed back when I first wrote Sentry, I probably wouldn't have bothered. But I really love Sentry's simplicity. There's no daemon, no compile, and the only dependency is perl.

I've been running sentry on these machines for about 6 years:


```
seattle % sudo /var/db/sentry/sentry.pl -r
   -------- summary ---------
4239 unique IPs have connected 205,009 times
  27 IPs are whitelisted
2583 IPs are blacklisted

jails % sudo /var/db/sentry/sentry.pl -r
   -------- summary ---------
4130 unique IPs have connected 471,043 times
  17 IPs are whitelisted
566 IPs are blacklisted

boston % sudo /var/db/sentry/sentry.pl -r
   -------- summary ---------
12316 unique IPs have connected 1,179,273 times
  11 IPs are whitelisted
4842 IPs are blacklisted
```

What I see in those stats is that the size of the botnets used for SSH scanning are much smaller than those used for SMTP abuse. The numbers on boston are higher mainly because that's a Linux server and I'm not running a firewall on it. So every connection hits tcpd.


----------



## spork (Mar 18, 2014)

This is a great thread, especially the notes about the startup script.

One thing I'm curious about is that it looks like most people here are running `sshguard` as a daemon.  From day one, I've been running it via syslogd, similar to this:


```
auth.info;authpriv.info     |exec /usr/local/sbin/sshguard -a 50 -p 43200
```

What appeals to me about that method is that as long as syslogd is running, I know that sshguard is running.  Alternately, if I ran it as a daemon, I'd need to have something like sysutils/daemontools to ensure that the sshguard is protecting the host.

What I'd like to hear about from other sshguard users is how you're currently dealing with jails.  We've been running sshguard on the host and then configure syslogd(8) in the jails to send auth.info and authpriv.info facilities/priorities to the host's authpriv.info.  This seems to work well and with sshguard being fed from multiple jails, we probably catch some abusers more quickly than if we had a handful of individual monitors.


----------



## SirDice (Mar 19, 2014)

spork said:
			
		

> We've been running sshguard on the host and then configure syslogd(8) in the jails to send auth.info and authpriv.info facilities/priorities to the host's authpriv.info.  This seems to work well and with sshguard being fed from multiple jails, we probably catch some abusers more quickly than if we had a handful of individual monitors.


That's a smart idea, I might have to steal that  :beergrin


----------



## fred974 (Aug 2, 2014)

spork said:
			
		

> We've been running sshguard on the host and then configure syslogd(8) in the jails to send auth.info and authpriv.info facilities/priorities to the host's authpriv.info.  This seems to work well and with sshguard being fed from multiple jails, we probably catch some abusers more quickly than if we had a handful of individual monitors.



Hi @sporkis there any change could explain me how to do this please?


----------



## aupanner (Sep 30, 2014)

xy16644 said:
			
		

> I set it to:
> 
> ```
> sshguard_safety_thresh="3"
> ...



You want 
	
	



```
sshguard_safety_thresh="30"
```
 for 3 attempts.  Each attempt is worth 10 "points".


----------



## wmoreno3 (Nov 21, 2014)

tnpimatt said:


> I'm a big fan of PF and its built in brute-force blocking, but that only scratches the "remote is making too many connections per second" itch.  I'm totally with SirDice about keeping it simple and avoiding additional daemons running. Here's the simplest way to avoid 99.9% of the sshd login attempts:
> 
> 
> ```
> ...


I like PF too, because OpenBSD is a great operating system and FreeBSD now supports it, I tried IPFW and IPFILTER (IPF) but no luck.

```
root@server:~ # uname -a
FreeBSD server.mydomain 10.1-RELEASE FreeBSD 10.1-RELEASE #0 r274401: Tue Nov 11 21:02:49 UTC 2014     root@releng1.nyi.freebsd.org:/usr/obj/usr/src/sys/GENERIC  amd64
```
I do what you said, I used PuTTY now with SSH on port 20022 ready.
Please, what does mean "Add an entry in ~/.ssh/config", please explain me.


----------



## storvi_net (Nov 21, 2014)

You can use a ~/.ssh/config file on your client, which lets you configure all the settings.

The following configuration entry (on your client) should work for you:

```
#~/.ssh/config
Host server
   Hostname   aaa.bbb.ccc.ddd #IP-Address or hostname
   User     username # Username
   Port 20022   # Port of the ssh-daemon
```

Every time you type `ssh server`, your client will automatically resolve "server" to you configured one.

Edit: this is applicable to OpenSSH clients.

Regards
Markus


----------



## dvl@ (Nov 25, 2014)

spork said:


> What I'd like to hear about from other sshguard users is how you're currently dealing with jails.  We've been running sshguard on the host and then configure syslogd(8) in the jails to send auth.info and authpriv.info facilities/priorities to the host's authpriv.info.  This seems to work well and with sshguard being fed from multiple jails, we probably catch some abusers more quickly than if we had a handful of individual monitors.



My plan for jails is to use fail2ban on the jail host and configure it to inspect the logs in each jail.

The primary reason I liked fail2ban is the ability to create recipes for various log types.


----------



## rtwingfield (May 27, 2015)

Regarding this _year-old_ post, https://forums.freebsd.org/threads/...and-brute-force-prevention.44255/#post-250859, by tnpimatt,

The *sentry* system sounds interesting ...simplicity of the concept; however I have a question regarding the utilization of the /etc/hosts.deny file . . .now "depreciated"? Running FreeBSD 10.1-RELEASE ...will there be problems with the OS recognizing the file.

Also, I'm considering installing the application in /usr/local/var/db/sentry, i.e., "user land", to keep it out of the distribution base file system.

Thoughts and comments appreciated!


----------



## dvl@ (May 27, 2015)

I think the URL you want is: https://forums.freebsd.org/threads/...and-brute-force-prevention.44255/#post-250859


----------



## rtwingfield (May 27, 2015)

. . .already fixed it 

Just so my questions on the previous page don't get lost, this URL:
https://forums.freebsd.org/threads/...and-brute-force-prevention.44255/#post-290340


----------



## SirDice (May 27, 2015)

rtwingfield said:


> however I have a question regarding the utilization of the /etc/hosts.deny file . . .now "depreciated"?


Access control using hosts_access(3) was created somewhere in the early 1990's when host based firewalls weren't that common. Applications need to specifically have support for it built-in or it won't work. Nowadays it's easier to create the access controls using the host's firewall as it works directly on the network layer. Applications don't have to specifically support it. So its use is largely deprecated. 



> Running FreeBSD 10.1-RELEASE ...will there be problems with the OS recognizing the file.


Nope, it should work. But the application you're protecting does need to have support for it. Not everything does. Sentry does look like it supports PF, so I suggest using that instead of a hosts.deny.


----------



## xoneill (Mar 18, 2018)

rtwingfield said:


> . . .already fixed it
> 
> Just so my questions on the previous page don't get lost, this URL:
> https://forums.freebsd.org/threads/...and-brute-force-prevention.44255/#post-290340



A bit late on the response....

I'd keep with the default installation path in /var/db/sentry.

hosts.allow is now combined per comments in /etc/hosts.allow:


```
# NOTE: The hosts.deny file is deprecated.
#       Place both 'allow' and 'deny' rules in the hosts.allow file.
#       See hosts_options(5) for the format of this file.
#       hosts_access(5) no longer fully applies.
```

hosts.deny is specified by the following /etc/hosts.allow CONFIG lines:


```
sshd : /var/db/sentry/hosts.deny : deny
sshd : ALL : spawn /var/db/sentry/sentry.pl -c --ip=%a : allow
```


----------

