# SSHGuard + IPFW to protect PureFTPd



## fuhdan (Jul 23, 2013)

Hi,

I want to protect my PureFTPd server. I have the following setup:


```
| Internet | ------ | Transparent Firewall | ------ | Pureftpd server |
```

I forward the PureFTPd syslogs to the firewall (/var/log/pureftpd.log). The syslog works fine. I can see on the firewall the failed logins. I installed the security/sshguard-ipfw port.

I adjusted the start script from sshguard as follows:

/usr/local/etc/rc.d/sshguard

```
#!/bin/sh
#-
# Copyright (c) 2012 iXsystems, Inc.
# All rights reserved.
#
# Written by: Xin Li <delphij@FreeBSD.org>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# $FreeBSD: ports/security/sshguard/files/sshguard.in,v 1.3 2013/02/01 15:41:58 svnexp Exp $
#

# PROVIDE: sshguard
# REQUIRE: LOGIN cleanvar

#
# Add the following lines to /etc/rc.conf to enable sshguard:
# sshguard_enable (bool):       Set to "NO" by default.
#                               Set it to "YES" to enable sshguard
# sshguard_pidfile (str):       Path to PID file.
#                               Set to "/var/run/sshguard.pid" by default
# sshguard_watch_logs (str):    Colon splitted list of logs to watch.
#                               Set to "/var/log/auth.log:/var/log/maillog"
#                               by default.
# The following options directly maps to their command line options,
# please read manual page sshguard(8) for detailed information:
# sshguard_blacklist (str):     [thr:]/path/to/blacklist.
#                               Set to "40:/var/db/sshguard/blacklist.db"
#                               by default.
# sshguard_safety_thresh (int): Safety threshold.  Set to "40" by default.
# sshguard_pardon_min_interval (int):
#                               Minimum pardon interval.  Set to "1200"
#                               by default.
# sshguard_prescribe_interval (int):
#                               Prescribe interval.  Set to "420" by
#                               default.
# sshguard_whitelistfile (str): Path to the whitelist.
#                               Set to "/usr/local/etc/sshguard.whitelist"
#                               by default.


. /etc/rc.subr

name="sshguard"
rcvar="sshguard_enable"
command="/usr/sbin/daemon"
actual_command="/usr/local/sbin/${name}"
procname="${actual_command}"

load_rc_config $name

: ${sshguard_enable="NO"}
: ${sshguard_pidfile="/var/run/${name}.pid"}
: ${sshguard_blacklist="40:/var/db/sshguard/blacklist.db"}
: ${sshguard_safety_thresh="4"}
: ${sshguard_pardon_min_interval="1200"}
: ${sshguard_prescribe_interval="420"}
: ${sshguard_whitelistfile="/usr/local/etc/sshguard.whitelist"}
: [color="Red"]${sshguard_watch_logs="/var/log/pureftpd.log"}[/color]

pidfile="${sshguard_pidfile}"
sshguard_watch_params=`echo ${sshguard_watch_logs} | tr : \\\n | sed -e s/^/-l\ /g | tr \\\n \ `
start_precmd="${name}_prestart"

command_args="-cf ${actual_command} -b ${sshguard_blacklist} ${sshguard_watch_params} -a ${sshguard_safety_thresh} -p ${sshguard_pardon_min_interval} -s ${sshguard_prescribe_interval} -w ${sshguard_whitelistfile} -i ${sshguard_pidfile}"

sshguard_prestart()
{
        mkdir -p `dirname ${sshguard_blacklist##*:}`
        [ -e ${sshguard_whitelistfile} ] || touch ${sshguard_whitelistfile}
}

run_rc_command "$1"
```

In my opinion, now sshguard should check the PureFTPd log and add an IPFW rule as soon as there are more than four failed login attemps. But I never get an IPFW rule, if I list the rules with:
`ipfw list`.

In the log I can see that sshguard starts up

```
sshguard[71977]: Started successfully [(a,p,s)=(4, 1200, 420)], now ready to scan.
```
I also tried to adjust syslog.conf But also there the sshguard does never add an IPFW rule.

Thanks for your help.

Cheers Daniel


----------



## SirDice (Jul 23, 2013)

You're not supposed to edit the rc scripts. Simply add values to /etc/rc.conf:

```
sshguard_enable="YES"
sshguard_watch_logs="/var/log/pureftpd.log"
```


----------



## fuhdan (Jul 23, 2013)

Thanks @SirDice,

So I reinstalled sshguard-ipfw to undo all my changes. I added the following lines to the rc.conf:

```
sshguard_enable="YES"
sshguard_watch_logs="/var/log/pureftpd.log"
sshguard_safety_thresh="4"
```


I restarted sshguard

```
sshguard[71977]: Got exit signal, flushing blocked addresses and exiting...
sshguard[73875]: Started successfully [(a,p,s)=(4, 1200, 420)], now ready to scan.
```
The pureftpd.log:

```
Jul 23 11:26:37 <ftp.info> pureftpd-host pure-ftpd: (?@xxx.xxx.xxx.xxx) [INFO] New connection from xxx.xxx.xxx.xxx
Jul 23 11:26:43 <ftp.warn> pureftpd-host pure-ftpd: (?@xxx.xxx.xxx.xxx) [WARNING] Authentication failed for user [daniel]
Jul 23 11:26:43 <ftp.info> pureftpd-host pure-ftpd: (?@xxx.xxx.xxx.xxx) [INFO] Logout.
Jul 23 11:26:48 <ftp.info> pureftpd-host pure-ftpd: (?@xxx.xxx.xxx.xxx) [INFO] New connection from xxx.xxx.xxx.xxx
Jul 23 11:26:53 <ftp.warn> pureftpd-host pure-ftpd: (?@xxx.xxx.xxx.xxx) [WARNING] Authentication failed for user [daniel]
Jul 23 11:26:53 <ftp.info> pureftpd-host pure-ftpd: (?@xxx.xxx.xxx.xxx) [INFO] Logout.
Jul 23 11:26:58 <ftp.info> pureftpd-host pure-ftpd: (?@xxx.xxx.xxx.xxx) [INFO] New connection from xxx.xxx.xxx.xxx
Jul 23 11:27:04 <ftp.warn> pureftpd-host pure-ftpd: (?@xxx.xxx.xxx.xxx) [WARNING] Authentication failed for user [daniel]
Jul 23 11:27:04 <ftp.info> pureftpd-host pure-ftpd: (?@xxx.xxx.xxx.xxx) [INFO] Logout.
Jul 23 11:27:09 <ftp.info> pureftpd-host pure-ftpd: (?@xxx.xxx.xxx.xxx) [INFO] New connection from xxx.xxx.xxx.xxx
Jul 23 11:27:13 <ftp.warn> pureftpd-host pure-ftpd: (?@xxx.xxx.xxx.xxx) [WARNING] Authentication failed for user [daniel]
Jul 23 11:27:14 <ftp.info> pureftpd-host pure-ftpd: (?@xxx.xxx.xxx.xxx) [INFO] Logout.
Jul 23 11:27:19 <ftp.info> pureftpd-host pure-ftpd: (?@xxx.xxx.xxx.xxx) [INFO] New connection from xxx.xxx.xxx.xxx
Jul 23 11:27:24 <ftp.warn> pureftpd-host pure-ftpd: (?@xxx.xxx.xxx.xxx) [WARNING] Authentication failed for user [daniel]
Jul 23 11:27:25 <ftp.info> pureftpd-host pure-ftpd: (?@xxx.xxx.xxx.xxx) [INFO] Logout.
Jul 23 11:27:30 <ftp.info> pureftpd-host pure-ftpd: (?@xxx.xxx.xxx.xxx) [INFO] New connection from xxx.xxx.xxx.xxx
Jul 23 11:27:34 <ftp.warn> pureftpd-host pure-ftpd: (?@xxx.xxx.xxx.xxx) [WARNING] Authentication failed for user [daniel]
Jul 23 11:27:34 <ftp.info> pureftpd-host pure-ftpd: (?@xxx.xxx.xxx.xxx) [INFO] Logout.
```

But still no rule with `ipfw list` that blocks my IP.

Am I right, that sshguard should block an address which has more than four failed logins within seven minutes for about twenty minutes?

```
option a = 4
option p = 1200
option s = 420
```

Cheers Daniel


----------



## SirDice (Jul 23, 2013)

fuhdan said:
			
		

> Am I right, that sshguard should block an address which has more than 4 failed logins within 7 minutes for about 20 minutes?


Yes, it should. I use security/sshguard-pf so I'm not sure what's needed on the IPFW side. For PF I need to add an 'anchor' to my ruleset, entries get added to PF at that point in my ruleset.


----------



## fuhdan (Jul 23, 2013)

OK. I now installed the PF firewall on my box. I have some questions about the bridging interface. When I want to allow outgoing traffic I have to add the following lines to the file pf.conf:


```
set skip on bridge0
pass in on $dmz_if proto { tcp, udp, icmp } from any to any modulate state
pass out on $ext_if proto { tcp, udp, icmp } from any to any modulate state
```

Is there a way to simplify the rules, so I don't have to have always two rules for one traffic flow? Anyway. My sshguard is still not working. Snips from /etc/pf.conf:


```
...
### Add tables here
table <sshguard> persist
...
block in quick on $ext_if proto tcp from <sshguard> to any label "bruteforce"
```

I can see the log entries in the file /var/log/purftpd.log

```
Jul 23 16:47:57 <ftp.info> purftpd-host pure-ftpd: (?@xxx.xxx.xxx.xxx) [INFO] New connection from xxx.xxx.xxx.xxx
Jul 23 16:48:01 <ftp.warn> purftpd-host pure-ftpd: (?@xxx.xxx.xxx.xxx) [WARNING] Authentication failed for user [daniel]
Jul 23 16:48:01 <ftp.info> purftpd-host pure-ftpd: (?@xxx.xxx.xxx.xxx) [INFO] Logout.
Jul 23 16:48:06 <ftp.info> purftpd-host pure-ftpd: (?@xxx.xxx.xxx.xxx) [INFO] New connection from xxx.xxx.xxx.xxx
Jul 23 16:48:11 <ftp.warn> purftpd-host pure-ftpd: (?@xxx.xxx.xxx.xxx) [WARNING] Authentication failed for user [daniel]
Jul 23 16:48:11 <ftp.info> purftpd-host pure-ftpd: (?@xxx.xxx.xxx.xxx) [INFO] Logout.
Jul 23 16:48:16 <ftp.info> purftpd-host pure-ftpd: (?@xxx.xxx.xxx.xxx) [INFO] New connection from xxx.xxx.xxx.xxx
Jul 23 16:48:20 <ftp.warn> purftpd-host pure-ftpd: (?@xxx.xxx.xxx.xxx) [WARNING] Authentication failed for user [daniel]
Jul 23 16:48:20 <ftp.info> purftpd-host pure-ftpd: (?@xxx.xxx.xxx.xxx) [INFO] Logout.
Jul 23 16:48:25 <ftp.info> purftpd-host pure-ftpd: (?@xxx.xxx.xxx.xxx) [INFO] New connection from xxx.xxx.xxx.xxx
Jul 23 16:48:30 <ftp.warn> purftpd-host pure-ftpd: (?@xxx.xxx.xxx.xxx) [WARNING] Authentication failed for user [daniel]
Jul 23 16:48:30 <ftp.info> purftpd-host pure-ftpd: (?@xxx.xxx.xxx.xxx) [INFO] Logout.
Jul 23 16:48:35 <ftp.info> purftpd-host pure-ftpd: (?@xxx.xxx.xxx.xxx) [INFO] New connection from xxx.xxx.xxx.xxx
Jul 23 16:48:41 <ftp.warn> purftpd-host pure-ftpd: (?@xxx.xxx.xxx.xxx) [WARNING] Authentication failed for user [daniel]
Jul 23 16:48:41 <ftp.info> purftpd-host pure-ftpd: (?@xxx.xxx.xxx.xxx) [INFO] Logout.
Jul 23 16:48:47 <ftp.info> purftpd-host pure-ftpd: (?@xxx.xxx.xxx.xxx) [INFO] New connection from xxx.xxx.xxx.xxx
Jul 23 16:48:50 <ftp.warn> purftpd-host pure-ftpd: (?@xxx.xxx.xxx.xxx) [WARNING] Authentication failed for user [daniel]
Jul 23 16:48:50 <ftp.info> purftpd-host pure-ftpd: (?@xxx.xxx.xxx.xxx) [INFO] Logout.
Jul 23 16:48:55 <ftp.info> purftpd-host pure-ftpd: (?@xxx.xxx.xxx.xxx) [INFO] New connection from xxx.xxx.xxx.xxx
Jul 23 16:49:01 <ftp.warn> purftpd-host pure-ftpd: (?@xxx.xxx.xxx.xxx) [WARNING] Authentication failed for user [daniel]
Jul 23 16:49:01 <ftp.info> purftpd-host pure-ftpd: (?@xxx.xxx.xxx.xxx) [INFO] Logout.
Jul 23 16:49:06 <ftp.info> purftpd-host pure-ftpd: (?@xxx.xxx.xxx.xxx) [INFO] New connection from xxx.xxx.xxx.xxx
Jul 23 16:49:11 <ftp.warn> purftpd-host pure-ftpd: (?@xxx.xxx.xxx.xxx) [WARNING] Authentication failed for user [daniel]
Jul 23 16:49:11 <ftp.info> purftpd-host pure-ftpd: (?@xxx.xxx.xxx.xxx) [INFO] Logout.
Jul 23 16:49:17 <ftp.info> purftpd-host pure-ftpd: (?@xxx.xxx.xxx.xxx) [INFO] New connection from xxx.xxx.xxx.xxx
Jul 23 16:49:22 <ftp.warn> purftpd-host pure-ftpd: (?@xxx.xxx.xxx.xxx) [WARNING] Authentication failed for user [daniel]
Jul 23 16:49:22 <ftp.info> purftpd-host pure-ftpd: (?@xxx.xxx.xxx.xxx) [INFO] Logout.
```
but no entry in the table.
`pfctl -t sshguard -T show`

```
No ALTQ support in kernel
ALTQ related functions disabled
```

My /etc/rc.conf:

```
...
pf_rules="/etc/pf.conf"
pf_flags=""
pflog_enable="YES"
pflog_logfile="/var/log/pflog"
pflog_flags=""
...
sshguard_enable="YES"
sshguard_watch_logs="/var/log/auth.log:/var/log/maillog:/var/log/pureftpd.log"
sshguard_safety_thresh="4"
```
And /usr/local/etc/rc.d/sshguard seems to start correctly. 
Log entries from /var/log/messages

```
Jul 23 16:47:47 <auth.notice> firewall-host sshguard[3919]: Got exit signal, flushing blocked addresses and exiting...
Jul 23 16:47:47 <auth.notice> firewall-host sshguard[4423]: Started successfully [(a,p,s)=(4, 1200, 420)], now ready to scan.
Jul 23 16:48:01 <ftp.warn> purftpd-host pure-ftpd: (?@xxx.xxx.xxx.xxx) [WARNING] Authentication failed for user [daniel]
Jul 23 16:48:30 <ftp.warn> purftpd-host last message repeated 3 times
Jul 23 16:49:22 <ftp.warn> purftpd-host last message repeated 5 times
```



Also the ssh login failur is not blocked:
/var/log/auth.log

```
Jul 23 19:17:45 <auth.err> firewall-host-host sshd[1306]: pam_winbind(sshd): request wbcLogonUser failed: WBC_ERR_AUTH_ERROR, PAM error: PAM_USER_UNKNOWN (13), NTSTATUS: NT_STATUS_NO_SUCH_USER, Error message was: No such user
Jul 23 19:17:45 <auth.err> firewall-host-host sshd[1304]: error: PAM: authentication error for root from 10.253.24.151
Jul 23 19:17:51 <auth.err> firewall-host-host sshd[1307]: pam_winbind(sshd): request wbcLogonUser failed: WBC_ERR_AUTH_ERROR, PAM error: PAM_USER_UNKNOWN (13), NTSTATUS: NT_STATUS_NO_SUCH_USER, Error message was: No such user
Jul 23 19:17:51 <auth.err> firewall-host-host sshd[1304]: error: PAM: authentication error for root from 10.253.24.151
Jul 23 19:17:56 <auth.err> firewall-host-host sshd[1308]: pam_winbind(sshd): request wbcLogonUser failed: WBC_ERR_AUTH_ERROR, PAM error: PAM_USER_UNKNOWN (13), NTSTATUS: NT_STATUS_NO_SUCH_USER, Error message was: No such user
Jul 23 19:17:56 <auth.err> firewall-host-host sshd[1304]: error: PAM: authentication error for root from 10.253.24.151
Jul 23 19:18:00 <auth.err> firewall-host-host sshd[1309]: pam_winbind(sshd): request wbcLogonUser failed: WBC_ERR_AUTH_ERROR, PAM error: PAM_USER_UNKNOWN (13), NTSTATUS: NT_STATUS_NO_SUCH_USER, Error message was: No such user
Jul 23 19:18:00 <auth.err> firewall-host-host sshd[1304]: error: PAM: authentication error for root from 10.253.24.151
```

by the way. My system is:
`uname -a`

```
FreeBSD firewall-host 9.1-RELEASE-p4 FreeBSD 9.1-RELEASE-p4 #0: Mon Jun 17 11:42:37 UTC 2013     root@amd64-builder.daemonology.net:/usr/obj/usr/src/sys/GENERIC  amd64
```

I did a little debugging and tested sshguard while failed login with the following command:
`tail -n0 -F /var/log/auth.log | env SSHGUARD_DEBUG=foo /usr/local/sbin/sshguard`

```
whitelist: add '127.0.0.1' as plain IPv4.
whitelist: add plain IPv4 127.0.0.1.
Started successfully [(a,p,s)=(40, 420, 1200)], now ready to scan.
Starting parse
Entering state 0
Reading a token: --accepting rule at line 213 ("Jul 23 22:58:10")
Next token is token TIMESTAMP_SYSLOG ()
Cleanup: discarding lookahead token TIMESTAMP_SYSLOG ()
Stack now 0
Starting parse
Entering state 0
Reading a token: --accepting rule at line 213 ("Jul 23 22:58:13")
Next token is token TIMESTAMP_SYSLOG ()
Cleanup: discarding lookahead token TIMESTAMP_SYSLOG ()
Stack now 0
Starting parse
Entering state 0
Reading a token: --accepting rule at line 213 ("Jul 23 22:58:13")
Next token is token TIMESTAMP_SYSLOG ()
Cleanup: discarding lookahead token TIMESTAMP_SYSLOG ()
Stack now 0
Starting parse
Entering state 0
Reading a token: --accepting rule at line 213 ("Jul 23 22:58:13")
Next token is token TIMESTAMP_SYSLOG ()
Cleanup: discarding lookahead token TIMESTAMP_SYSLOG ()
Stack now 0
^CGot exit signal, flushing blocked addresses and exiting...
```

For me it looks, that sshguard has a problem with the syslogmessages on my system ...


----------

