Protect your Asterisk server against brute forcing

As Internet accessible corporate Voice over IP servers continue to grow in number, so does the risk of rogue individuals gaining access to SIP extensions due to weak or poorly managed Asterisk passwords.

You can protect your Asterisk server using Fail2Ban. Fail2ban scans log files like /var/log/asterisk/full or /var/log/secure and bans IP addresses with to any password failures. It then updates firewall rules to reject the IP address permenantly or for a administrator defined period of time.

This article does NOT negate the need to set strong SIP extension passwords or change system default passwords, this is purely aimed at countering the most common way to hack SIP servers: Brute-forcing SIP passwords.

To install Fail2Ban for Asterisk –

SSH to your VoIP server and login as root , then type the following commands:

yum -y install jwhois
cd /usr/src/
wget http://sourceforge.net/projects/fail2ban/files/fail2ban-stable/fail2ban-0.8.4/fail2ban-0.8.4.tar.bz2/download
tar -jxf fail2ban-0.8.4.tar.bz2
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
cd /etc/fail2ban/filter.d
touch asterisk.conf

Copy these the following into a new configuration file: /etc/fail2ban/filter.d/asterisk.conf:


# /etc/fail2ban/filter.d/asterisk.conf
# Fail2Ban configuration file
#
#
# $Revision: 250 $
#

[INCLUDES]

# Read common prefixes. If any customizations available -- read them from
# common.local
#before = common.conf


[Definition]

#_daemon = asterisk

# 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>\S+)
# Values:  TEXT
#

failregex = NOTICE.* .*: Registration from '.*' failed for '<HOST>' - Wrong password
 NOTICE.* .*: Registration from '.*' failed for '<HOST>' - No matching peer found
 NOTICE.* .*: Registration from '.*' failed for '<HOST>' - Username/auth name mismatch
 NOTICE.* .*: Registration from '.*' failed for '<HOST>' - Device does not match ACL
 NOTICE.* <HOST> failed to authenticate as '.*'$
 NOTICE.* .*: No registration for peer '.*' (from <HOST>)
 NOTICE.* .*: Host <HOST> failed MD5 authentication for '.*' (.*)
 NOTICE.* .*: Failed to authenticate user .*@<HOST>.*

# Option:  ignoreregex
# Notes.:  regex to ignore. If this regex matches, the line is ignored.
# Values:  TEXT
#
ignoreregex =
#

Modify the [default] ignoreip section and Add the [asterisk-iptables] section to your /etc/fail2ban/jail.conf file:

NOTE: You need to define your alert email address below.

# /etc/fail2ban/jail.conf

[DEFAULT]
ignoreip = 127.0.0.1 192.168.0.0/16 10.0.0.0/8 172.16.0.0/16

[asterisk-iptables]
enabled  = true
filter   = asterisk
action   = iptables-allports[name=ASTERISK, protocol=all]
sendmail-whois[name=ASTERISK, [email protected][email protected]]
logpath  = /var/log/asterisk/fail2ban
maxretry = 5
bantime = 600

Backup the logger.conf file to logger.conf~ and create a new configuration file:

# mv /etc/asterisk/logger.conf /etc/asterisk/logger.conf.bak
# touch /etc/asterisk/logger.conf

Copy the following into a new configuration file /etc/asterisk/logger.conf:

[general]
dateformat=%F %T
[logfiles]
full => notice,warning,error,debug,verbose
fail2ban => notice

Reload logger module in Asterisk:

# asterisk -rx "module reload logger"

Add Fail2ban to the list of startup services:

# chkconfig fail2ban on

Start Fail2ban:

# /etc/init.d/fail2ban start

Check if fail2ban is listed in IPTABLES:

# iptables -L -v

You should see “fail2ban-ASTERISK” in your iptables output.

With this configuration in place, anyone trying to brute force (hack) your SIP account passwords will now be banned after 5 failed login attempts for 600 seconds (10 minutes). If required, you can adjust these variables in /etc/fail2ban/jail.conf.

How to test –

Download a copy of X-Lite and try to connect to your Asterisk box using false credentials. Make sure you don’t try this from an IP address that is on the “ignoreip” list ( 192.168.22.0/24 for instance ). If your client gets blocked after 5 attempts and you receive an email saying your IP has been blocked, then you can safely assume that your configuration is working correctly.

You can also test the filter regex expressions using:

$fail2ban-regex /var/log/asterisk/full /etc/fail2ban/filter.d/asterisk.conf

and

$fail2ban-regex /var/log/secure /etc/fail2ban/filter.d/sshd.conf

NOTE: The above rules test Asterisk and SSH rules against your log history.

4 Comments

  1. Rich

    Nice post, but:

    ConfigParser.ParsingError: File contains parsing errors: /etc/fail2ban/filter.d/asterisk.conf
    [line 30]: “NOTICE.* failed to authenticate as ‘.*’$\n”

    Not sure what the error is but commenting that line out fixes it

  2. Hey and thanks for this good how to ..

    Here is my expectation .Just want to block the hole range of IP Address not only source IPAddress

    some one try to access from 123.28.109.212

    I want want to block 123.28.109.0/24 …

    Can you change the code for this requirement..

    Advance thanks for you

    Thanks
    K~

  3. I am did on my ubuntu its showing error like below

    Just simply i followed your steps with out missing any thing .. Guide me

    ####################################

    root@HomePBX:~# /etc/init.d/fail2ban start
    /etc/init.d/fail2ban: line 13: /etc/init.d/functions: No such file or directory
    Starting fail2ban: Traceback (most recent call last):
    File “/usr/bin/fail2ban-client”, line 401, in ?
    if client.start(sys.argv):
    File “/usr/bin/fail2ban-client”, line 370, in start
    return self.__processCommand(args)
    File “/usr/bin/fail2ban-client”, line 180, in __processCommand
    ret = self.__readConfig()
    File “/usr/bin/fail2ban-client”, line 375, in __readConfig
    ret = self.__configurator.getOptions()
    File “/usr/share/fail2ban/client/configurator.py”, line 65, in getOptions
    return self.__jails.getOptions(jail)
    File “/usr/share/fail2ban/client/jailsreader.py”, line 64, in getOptions
    ret = jail.getOptions()
    File “/usr/share/fail2ban/client/jailreader.py”, line 75, in getOptions
    ret = self.__filter.read()
    File “/usr/share/fail2ban/client/filterreader.py”, line 53, in read
    return ConfigReader.read(self, “filter.d/” + self.__file)
    File “/usr/share/fail2ban/client/configreader.py”, line 59, in read
    SafeConfigParserWithIncludes.read(self, [bConf, bLocal])
    File “/usr/share/fail2ban/client/configparserinc.py”, line 105, in read
    fileNamesFull += SafeConfigParserWithIncludes.getIncludes(filename)
    File “/usr/share/fail2ban/client/configparserinc.py”, line 76, in getIncludes
    parser.read(resource)
    File “/usr/lib/python2.4/ConfigParser.py”, line 267, in read
    self._read(fp, filename)
    File “/usr/lib/python2.4/ConfigParser.py”, line 490, in _read
    raise e
    ConfigParser.ParsingError: File contains parsing errors: /etc/fail2ban/filter.d/asterisk.conf
    [line 30]: “NOTICE.* failed to authenticate as ‘.*’$\n”
    /etc/init.d/fail2ban: line 38: echo_failure: command not found

    root@HomePBX:~# /etc/init.d/fail2ban stop
    /etc/init.d/fail2ban: line 13: /etc/init.d/functions: No such file or directory
    Stopping fail2ban: /etc/init.d/fail2ban: line 59: echo_failure: command not found

    #####################################

  4. I had the same issue as above. Don’t remove the line, edit to;
    NOTICE.*.*: failed to authenticate as ‘.*’$
    (still untested)

    Matt Martin
    VCCS Telecom

Comments are closed