Asterisk 11.5 + Fail2Ban

I know that I have not talked about Asterisk here before or Ubuntu for that matter. But since I just did this and it’s still fresh, I decided to put it here.

Since you are here, I assume that you have Asterisk already installed. If not, I will make a tutorial on how to install it soon.

I have Ubuntu Server and I have been monitoring my Asterisk 11.5 and see if there is anyone trying to hack into it. Sure enough, I see these logs..

This is from /var/log/asterisk/messages

[2014-02-20 19:55:37] NOTICE[3241][C-00000001]: chan_sip.c:25282 handle_request_invite: Failed to authenticate device 1400<sip:1400@[LOCAL_IP]:[PORT]>;tag=518abf5e
 [2014-02-20 19:55:38] NOTICE[3241][C-00000002]: chan_sip.c:25282 handle_request_invite: Failed to authenticate device 1400<sip:1400@LOCAL_IP]:[PORT]>;tag=a92be084
 [2014-02-20 19:55:39] NOTICE[3241][C-00000003]: chan_sip.c:25282 handle_request_invite: Failed to authenticate device 1400<sip:1400@LOCAL_IP]:[PORT]>;tag=514495fb

Now if you look at it, the logs only show the local IP and not the real source IP.  In order for us to get the source IP, we would need to enable the security logs.

Enable Security Logs

  • Open /etc/asterisk/logger.conf
vi /etc/asterisk/logger.conf
  • Add/Edit the following lines

[general]

 dateformat=%F %T

[logfiles]

messages => security,notice,warning,error

**Added “security”

  • Save.
  • Reload the logger
asterisk -rx "logger reload"
  • Test it to see if it worked by running
tail –f /var/log/asterisk/messages

If you see “SECURITY” or “SecurityEvent”, that means that it worked. If not, try restarting Asterisk. If it works, security logs should look like this:

[2014-02-20 19:55:39] SECURITY[3205] res_security_log.c: SecurityEvent="ChallengeSent",EventTV="1392951339-105122",Severity="Informational",Service="SIP",EventVersion="1",AccountID="sip:1400@[LOCAL_IP]:[PORT]",SessionID="0x7f5304029258",LocalAddress="IPV4/UDP/[LOCAL_IP]/[PORT]",RemoteAddress="IPV4/UDP/50.30.35.159/5074",Challenge="357cfd3c"
[2014-02-20 19:55:39] NOTICE[3241][C-00000003] chan_sip.c: Failed to authenticate device 1400<sip:1400@[LOCAL_IP]:[PORT]>;tag=514495fb
[2014-02-20 19:55:39] SECURITY[3205] res_security_log.c: SecurityEvent="InvalidPassword",EventTV="1392951339-243416",Severity="Error",Service="SIP",EventVersion="2",AccountID="00972598387522",SessionID="0x7f5304029258",LocalAddress="IPV4/UDP/[LOCAL_IP]/[PORT]",RemoteAddress="IPV4/UDP/50.30.35.159/5074",Challenge="357cfd3c",ReceivedChallenge="357cfd3c",ReceivedHash="c31622aaccd3fa21dcef884c6dddfc7b"

IP Address 50.30.35.159 is trying to register as SIP/1400 but it’s giving an incorrect password.

Now that we can see the source IP, time to setup our fail2ban.

Fail2ban Installation

  • Install via apt-get
sudo apt-get install fail2ban
  • Make a local copy of configuration (Optional)
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

**We will use jail.local to make changes on our fail2ban’s configuration.

 

Fail2ban Configuration

  • Open jail.local
vi /etc/fail2ban/jail.local
  • Add or edit lines
ignoreip = 127.0.0.1/8
      • I suggest you put your own IP and other’s you don’t want to get banned.
[asterisk-iptables]
# if more than 4 attempts are made within 6 hours, ban for 24 hours
enabled  = true
filter   = asterisk
action   = iptables-allports[name=ASTERISK, protocol=all]
              sendmail[name=ASTERISK, dest=you@yourmail.co.uk, sender=fail2ban@local.local]
logpath  = /var/log/asterisk/messages
maxretry = 4
findtime = 21600
bantime = 86400
      • Add this config for our Asterisk logs. I edited mine to max 3 tries  within 24 hours and ban for 3 days. You can add e-mail functionality as well so you know when someone gets banned.
  • We’re going to add a file for fail2ban’s filter. This is where we will specify the logs fail2ban is going to look for in our Asterisk logs in order to stop attacks.
vi /etc/fail2ban/filter.d/asterisk.conf

           ** I had to add a file for this, if you already have it, just edit it.

  • Add or edit lines
# Fail2Ban configuration file
# Author: Xavier Devlamynck
 
[INCLUDES]
 
# Read common prefixes. If any customizations available -- read them from
# common.local
before = common.conf
 
[Definition]
 
# Option:  failregex
# Notes.:  regex to match the password failures messages in the logfile.
# Values:  TEXT
#
log_prefix= \[\]\s*(?:NOTICE|SECURITY)%(__pid_re)s:?(?:\[\S+\d*\])? \S+:\d*
 
failregex = ^%(log_prefix)s Registration from '[^']*' failed for '<HOST>(:\d+)?' - Wrong password$
            ^%(log_prefix)s Registration from '[^']*' failed for '<HOST>(:\d+)?' - No matching peer found$
            ^%(log_prefix)s Registration from '[^']*' failed for '<HOST>(:\d+)?' - Username/auth name mismatch$
            ^%(log_prefix)s Registration from '[^']*' failed for '<HOST>(:\d+)?' - Device does not match ACL$
            ^%(log_prefix)s Registration from '[^']*' failed for '<HOST>(:\d+)?' - Peer is not supposed to register$
            ^%(log_prefix)s Registration from '[^']*' failed for '<HOST>(:\d+)?' - ACL error \(permit/deny\)$
            ^%(log_prefix)s Registration from '[^']*' failed for '<HOST>(:\d+)?' - Not a local domain$
            ^%(log_prefix)s Call from '[^']*' \(<HOST>:\d+\) to extension '\d+' rejected because extension not found in context 'default'\.$
            ^%(log_prefix)s Host <HOST> failed to authenticate as '[^']*'$
            ^%(log_prefix)s No registration for peer '[^']*' \(from <HOST>\)$
            ^%(log_prefix)s Host <HOST> failed MD5 authentication for '[^']*' \([^)]+\)$
            ^%(log_prefix)s Failed to authenticate (user|device) [^@]+@<HOST>\S*$
            ^%(log_prefix)s (?:handle_request_subscribe: )?Sending fake auth rejection for (device|user) \d*<sip:[^@]+@<HOST>>;tag=\w+\S*$
            ^%(log_prefix)s SecurityEvent="(FailedACL|InvalidAccountID|ChallengeResponseFailed|InvalidPassword)",EventTV="[\d-]+",Severity="[\w]+",Service="[\w]+",EventVersion="\d+",AccountID="\d+",SessionID="0x[\da-f]+",LocalAddress="IPV[46]/(UD|TC)P/[\da-fA-F:.]+/\d+",RemoteAddress="IPV[46]/(UD|TC)P/<HOST>/\d+"(,Challenge="\w+",ReceivedChallenge="\w+")?(,ReceivedHash="[\da-f]+")?$
 
# Option:  ignoreregex
# Notes.:  regex to ignore. If this regex matches, the line is ignored.
# Values:  TEXT
#
ignoreregex =
  •  Save.
  • Restart fail2ban service
sudo /etc/init.d/fail2ban restart
or
sudo services fail2ban restart

Now, this command is to check whether fail2ban configuration actually went through.

iptables -L -n

If you see this in your iptables command, your configuration for fail2ban is good.

Chain fail2ban-ASTERISK (1 references)
target prot opt source destination 
RETURN all -- 0.0.0.0/0 0.0.0.0/0

Now, of course you want to test if it is actually working. You can either setup your VoIP phone to send an incorrect password or I’m sure there are programs out there that can test your security. You can always delete your IP from iptables. Be careful not to ban your only access IP from the server.

Deleting IP from iptables

iptables -D [chain-name] [line #]
iptables -D fail2ban-ASTERISK 1

 ** line # = 1 starting from the first entry on top of the chain.

You will see that if it works, there would be IP address under fail2ban-ASTERISK like this:

Chain fail2ban-ASTERISK (1 references)
target prot opt source destination 
DROP all -- 209.239.123.4 0.0.0.0/0 
DROP all -- 50.30.35.159 0.0.0.0/0 
RETURN all -- 0.0.0.0/0 0.0.0.0/0

 

If you have any questions or comments, feel free to write below. If you like my contents, don’t forget to subscribe!

makkugasho

14 Replies to “Asterisk 11.5 + Fail2Ban”

  1. Hi, i’ve used your confoguration but when i’ve restart fail2ban i’ve got this:

    root@asterisk:/etc/fail2ban/filter.d# sudo service fail2ban restart
    * Restarting authentication failure monitor fail2ban ERROR NOK: (“No ‘host’ group in ‘^\\[\\]\\s*(?:NOTICE|SECURITY)(?:\\[\\d+\\]):?(?:\\[\\S+\\d*\\])? \\S+:\\d* Registration from ‘[^’]*’ failed for ‘(:\\d+)?’ – Wrong password$'”,)

    why? Thanks

    1. You’re actually right. I did not see that the “HOST” on each line was missing because of HTML. I fixed it and it should work now.

  2. When I am trying to start fail2ban I am getting the following error. Please help me. Thanks in advance.

    [….] Restarting authentication failure monitor: fail2banTraceback (most recent call last):
    File “/usr/bin/fail2ban-client”, line 404, in
    if client.start(sys.argv):
    File “/usr/bin/fail2ban-client”, line 373, in start
    return self.__processCommand(args)
    File “/usr/bin/fail2ban-client”, line 183, in __processCommand
    ret = self.__readConfig()
    File “/usr/bin/fail2ban-client”, line 378, in __readConfig
    ret = self.__configurator.getOptions()
    File “/usr/share/fail2ban/client/configurator.py”, line 68, in getOptions
    return self.__jails.getOptions(jail)
    File “/usr/share/fail2ban/client/jailsreader.py”, line 67, in getOptions
    ret = jail.getOptions()
    File “/usr/share/fail2ban/client/jailreader.py”, line 80, in getOptions
    self.__filter.getOptions(self.__opts)
    File “/usr/share/fail2ban/client/filterreader.py”, line 61, in getOptions
    self.__opts = ConfigReader.getOptions(self, “Definition”, opts, pOpts)
    File “/usr/share/fail2ban/client/configreader.py”, line 87, in getOptions
    v = self.get(sec, option[1])
    File “/usr/lib/python2.7/ConfigParser.py”, line 623, in get
    return self._interpolate(section, option, value, d)
    File “/usr/lib/python2.7/ConfigParser.py”, line 691, in _interpolate
    self._interpolate_some(option, L, rawval, section, vars, 1)
    File “/usr/lib/python2.7/ConfigParser.py”, line 726, in _interpolate_some
    section, map, depth + 1)
    File “/usr/lib/python2.7/ConfigParser.py”, line 723, in _interpolate_some
    option, section, rest, var)
    ConfigParser.InterpolationMissingOptionError: Bad value substitution:
    section: [Definition]
    option : failregex
    key : __pid_re
    rawval : :?(?:\[\S+\d*\])? \S+:\d*

    failed!

    Thanks

  3. Hello, thank you by the tutorial, i applied the configuration and seems like that work as well, one question, i have IP phones grandstream and sometimes this phones receive calls from 100 or 621, etc and in the call report dont appear and in the log not show , it happend to somebody any situation like this?

    regards.

    1. Its because your grandstream listen to all request on port 5060, its a bot who send request directly to your grandstream. I dont know how to change it on a grandstream but you need to make that it accept request only from it server.

    2. Enzo

      Turn off direct IP to IP calling and enable Authentication on Call Invite. That should stop what you are seeing. This occurs when a script get’s ahold of your phone and tries to send calls to it directly. Grandstream phones by default will accept any call sent to it, even ones from script kitties

  4. Thanks A LOT for a this post & tutorial!
    Here is something I had to do slightly differently in Elastix 2.5. In older Elastix versions, everything works as you stated.
    For Elastix 2.5 and newer versions, the logger file to edit is /etc/asterisk/logger_logfiles_custom.conf as /etc/asterisk/logger.conf will be overwritten every time you apply changes through the GUI.
    Thanks again!

Leave a Reply

Your email address will not be published. Required fields are marked *