Fail2ban
From FreeSWITCH Wiki
Contents |
Fail2Ban
Fail2Ban is an intrusion prevention system that works by scanning log files and then taking action based on the entries in those logs.
You can configure Fail2Ban in a way that will update iptables firewall rules, when an authentication failure threshold is reached which helps in preventing SIP brute force attacks against freeswitch instances.
Fail2ban scans your freeswitch log file and bans IP that makes too many password failures. It updates firewall rules to reject the IP address.
Fail2Ban is available at fail2ban.org as well as more documentation.
Requirements
Fail2ban needs a log of Authentication Attempts/Failures in order to ban IPs. There are two ways to do that:
- Beta: mod_fail2ban
OR
- Enable "log-auth-failures" on each Sofia profile to monitor -- this requires a high enough loglevel on your logs to save these messages.
<param name="log-auth-failures" value="true"/>
Install
Ubuntu/Debian
apt-get install fail2ban
SUSE
zypper sa http://download.opensuse.org/repositories/security/SLE_11 openSUSE-security zypper refresh zypper up zypper install fail2ban
FreeBSD
pkg_add -r py26-fail2ban ... and all the files referenced later are in /usr/local/etc/ rather than /etc/
Centos 5
For CentOS the easiest way to do this is to install fail2ban from the EPEL repo, see http://fedoraproject.org/wiki/EPEL/FAQ
64 Bit
rpm -Uvh http://dl.fedoraproject.org/pub/epel/5/x86_64/epel-release-5-4.noarch.rpm yum -y install fail2ban
32 Bit
rpm -Uvh http://dl.fedoraproject.org/pub/epel/5/i386/epel-release-5-4.noarch.rpm yum install fail2banEnter the Fail2Ban directory you just extracted:
cd fail2ban-0.8.4 python setup.py install cp /usr/src/fail2ban-0.8.4/files/redhat-initd /etc/init.d/fail2ban chmod 755 /etc/init.d/fail2ban
(or whatever on your platform)
Confgure
Edit Config Files
Create /etc/fail2ban/filter.d/freeswitch.conf with the contents:
# Fail2Ban configuration file
#
# Author: Rupa SChomaker
#
[Definition]
# Option: failregex
# Notes.: regex to match the password failures messages in the logfile. The
# host must be matched by a group named "host". The tag "<HOST>" can
# be used for standard IP/hostname matching and is only an alias for
# (?:::f{4,6}:)?(?P<host>[\w\-.^_]+)
# Values: TEXT
#
failregex = \[WARNING\] sofia_reg.c:\d+ SIP auth failure \(REGISTER\) on sofia profile \'[^']+\' for \[.*\] from ip <HOST>
\[WARNING\] sofia_reg.c:\d+ SIP auth failure \(INVITE\) on sofia profile \'[^']+\' for \[.*\] from ip <HOST>
# Option: ignoreregex
# Notes.: regex to ignore. If this regex matches, the line is ignored.
# Values: TEXT
#
ignoreregex =
Modify /etc/fail2ban/jail.conf. Add the following (enter the correct path to *your* freeswitch.log file, and adjust the email addresses if needed for your setup):
[freeswitch]
enabled = true
port = 5060,5061,5080,5081
filter = freeswitch
logpath = /var/log/freeswitch/freeswitch.log
maxretry = 10
action = iptables-allports[name=freeswitch, protocol=all]
sendmail-whois[name=FreeSwitch, dest=root, sender=fail2ban@example.org]
(mine are /usr/local/freeswitch/log/freeswitch.log)
Restart fail2ban (/etc/init.d/fail2ban restart) and ensure that fail2ban loads the filter. The following should be in your /var/log/fail2ban.log:
2010-02-05 10:04:23,560 fail2ban.jail : INFO Creating new jail 'freeswitch-udp' 2010-02-05 10:04:23,560 fail2ban.jail : INFO Jail 'freeswitch-udp' uses poller 2010-02-05 10:04:23,561 fail2ban.filter : INFO Added logfile = /var/log/freeswitch/freeswitch.log 2010-02-05 10:04:23,562 fail2ban.filter : INFO Set maxRetry = 3 2010-02-05 10:04:23,562 fail2ban.filter : INFO Set findtime = 600 2010-02-05 10:04:23,563 fail2ban.actions: INFO Set banTime = 600 2010-02-05 10:04:23,677 fail2ban.jail : INFO Creating new jail 'freeswitch-tcp' 2010-02-05 10:04:23,677 fail2ban.jail : INFO Jail 'freeswitch-tcp' uses poller 2010-02-05 10:04:23,678 fail2ban.filter : INFO Added logfile = /var/log/freeswitch/freeswitch.log 2010-02-05 10:04:23,679 fail2ban.filter : INFO Set maxRetry = 3 2010-02-05 10:04:23,680 fail2ban.filter : INFO Set findtime = 600 2010-02-05 10:04:23,680 fail2ban.actions: INFO Set banTime = 600 2010-02-05 10:04:23,723 fail2ban.jail : INFO Jail 'freeswitch-tcp' started 2010-02-05 10:04:23,723 fail2ban.jail : INFO Jail 'freeswitch-udp' started
Verify that the iptables rules were created:
#iptables -L fail2ban-freeswitch-udp Chain fail2ban-freeswitch-udp (1 references) target prot opt source destination RETURN all -- anywhere anywhere #iptables -L fail2ban-freeswitch-tcp Chain fail2ban-freeswitch-tcp (1 references) target prot opt source destination RETURN all -- anywhere anywhere
Test the actual failure mode
Setup your favorite client with an invalid userid or invalid password. Try to login as many times as you have set your failure threshold in fail2ban. Watch the fail2ban log:
tail -f /var/log/fail2ban.log 2010-02-05 10:13:12,070 fail2ban.actions: WARNING [freeswitch-udp] Ban 192.168.1.10 2010-02-05 10:13:12,098 fail2ban.actions: WARNING [freeswitch-tcp] Ban 192.168.1.10
Verify your client can no longer do a register (should just time out). Also verify iptables:
#iptables -n -L fail2ban-freeswitch-tcp Chain fail2ban-freeswitch-tcp (1 references) target prot opt source destination DROP all -- 192.168.1.10 0.0.0.0/0 RETURN all -- 0.0.0.0/0 0.0.0.0/0 #iptables -n -L fail2ban-freeswitch-udp Chain fail2ban-freeswitch-udp (1 references) target prot opt source destination DROP all -- 192.168.1.10 0.0.0.0/0 RETURN all -- 0.0.0.0/0 0.0.0.0/0
You can then wait for fail2ban to clear the the block, or do it yourself:
#iptables -D fail2ban-freeswitch-udp 1 #iptables -L fail2ban-freeswitch-udp RETURN all -- anywhere anywhere #iptables -D fail2ban-freeswitch-tcp 1 #iptables -L fail2ban-freeswitch-udp Chain fail2ban-freeswitch-udp (1 references) target prot opt source destination RETURN all -- anywhere anywhere
SIP DOS Attack
There is a new SIP based attack that appears to be a Denial of Service attack. Here's an example of what you might see in your logfile:
2011-03-10 08:59:56.319954 [WARNING] sofia_reg.c:1247 SIP auth challenge (REGISTER) on sofia profile 'internal' for [qwerty123@10.2.39.4] from ip 109.169.63.142 2011-03-10 08:59:56.355872 [WARNING] sofia_reg.c:1247 SIP auth challenge (REGISTER) on sofia profile 'internal' for [qwerty123@10.2.39.4] from ip 109.169.63.142 2011-03-10 08:59:56.382909 [WARNING] sofia_reg.c:1247 SIP auth challenge (REGISTER) on sofia profile 'internal' for [qwerty123@10.2.39.4] from ip 109.169.63.142 2011-03-10 08:59:56.894607 [WARNING] sofia_reg.c:1247 SIP auth challenge (REGISTER) on sofia profile 'internal' for [qwerty123@10.2.39.4] from ip 109.169.63.142
grep qwerty123 /usr/local/freeswitch/log/freeswitch.log |wc -l
Returns 19,289 attempts in a little over an hour. This is a particularly nasty attack, that actually crashed my FreeSWITCH installation. I didn't see it live, or I would have set 'sofia global siptrace on' to obtain more information. Regardless, here's how you can block it with fail2ban. You might want to adjust findtime, maxtretry and bantime, but it did work on a second live attack.
vim /etc/fail2ban/filter.d/freeswitch-dos.conf
# Fail2Ban configuration file
#
# Author: soapee01
#
[Definition]
# Option: failregex
# Notes.: regex to match the password failures messages in the logfile. The
# host must be matched by a group named "host". The tag "<HOST>" can
# be used for standard IP/hostname matching and is only an alias for
# (?:::f{4,6}:)?(?P<host>[\w\-.^_]+)
# Values: TEXT
#
failregex = \[WARNING\] sofia_reg.c:\d+ SIP auth challenge \(REGISTER\) on sofia profile \'[^']+\' for \[.*\] from ip <HOST>
# Option: ignoreregex
# Notes.: regex to ignore. If this regex matches, the line is ignored.
# Values: TEXT
#
ignoreregex =
add the following to /etc/fail2ban/jail.local
[freeswitch-dos] enabled = true port = 5060,5061,5080,5081 filter = freeswitch-dos logpath = /usr/local/freeswitch/log/freeswitch.log action = iptables-allports[name=freeswitch-dos, protocol=all] maxretry = 50 findtime = 30 bantime = 6000
You might also take a look at this oreilly script
Keep yourself from getting banned.
add to /etc/fail2ban/jail.local
[DEFAULT] # "ignoreip" can be an IP address, a CIDR mask or a DNS host ignoreip = 127.0.0.1 192.168.0.99 bantime = 600 maxretry = 3
Errors
If you're seeing something like this in your fail2ban logfile:
2011-02-27 14:11:42,326 fail2ban.actions.action: ERROR iptables -N fail2ban-freeswitch-tcp
add the time.sleep(0.1) to /usr/bin/fail2ban-client
def __processCmd(self, cmd, showRet = True): beautifier = Beautifier() for c in cmd: time.sleep(0.1) beautifier.setInputCmd(c)
or
sed -i -e s,beautifier\.setInputCmd\(c\),'time.sleep\(0\.1\)\n\t\t\tbeautifier.setInputCmd\(c\)', /usr/bin/fail2ban-client

