In this article I’ll describe how to protect Asterisk from hacking attempts with Fail2ban in CentOS Linux. Fail2Ban is a standard Linux tool used to scan log files and then block IP’s found in those log files using iptables. Fail2ban depends completely on the application (in this case Asterisk) to detect any intrusion/failure and log the user data, upon which fail2ban can then act. Fail2ban does not provide any type of intrusion detection, hack detection, etc., it depends completely on Asterisk to do that.
Fail2ban Installation
As simple as:
1 |
yum install fail2ban |
Fail2ban Configuration
In /etc/fail2ban/jail.local
make sure you have the section configured like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
[asterisk] filter = asterisk enabled = true port = 5060,5061,5038 action = %(banaction)s[name=%(__name__)s-tcp, port="%(port)s", protocol="tcp", chain="%(chain)s", actname=%(banaction)s-tcp] %(banaction)s[name=%(__name__)s-udp, port="%(port)s", protocol="udp", chain="%(chain)s", actname=%(banaction)s-udp] %(mta)s-whois[name=%(__name__)s, dest="%(destemail)s"] #what log to check: logpath = /var/log/asterisk/messages #max failed attempts before ban maxretry = 5 #in this time range (in seconds) findtime = 21600 # ban for (in seconds) bantime = 259200 |
Check that /etc/fail2ban/filter.d/asterisk.conf
has the following content:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
# Fail2Ban filter for asterisk authentication failures # [INCLUDES] # Read common prefixes. If any customizations available -- read them from # common.local before = common.conf [Definition] _daemon = asterisk __pid_re = (?:\[\d+\]) iso8601 = \d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d+[+-]\d{4} # All Asterisk log messages begin like this: log_prefix= (?:NOTICE|SECURITY|WARNING)%(__pid_re)s:?(?:\[C-[\da-f]*\])? [^:]+:\d*(?:(?: in)? \w+:)? failregex = ^%(__prefix_line)s%(log_prefix)s Registration from '[^']*' failed for '<HOST>(:\d+)?' - (Wrong password|Username/auth name mismatch|No matching peer found|Not a local domain|Device does not match ACL|Peer is not supposed to register|ACL error \(permit/deny\)|Not a local domain)$ ^%(__prefix_line)s%(log_prefix)s Call from '[^']*' \(<HOST>:\d+\) to extension '[^']*' rejected because extension not found in context ^%(__prefix_line)s%(log_prefix)s Host <HOST> failed to authenticate as '[^']*'$ ^%(__prefix_line)s%(log_prefix)s <HOST> failed to authenticate as '[^']*'$ ^%(__prefix_line)s%(log_prefix)s No registration for peer '[^']*' \(from <HOST>\)$ ^%(__prefix_line)s%(log_prefix)s Host <HOST> failed MD5 authentication for '[^']*' \([^)]+\)$ ^%(__prefix_line)s%(log_prefix)s Failed to authenticate (user|device) [^@]+@<HOST>\S*$ ^%(__prefix_line)s%(log_prefix)s hacking attempt detected '<HOST>'$ ^%(__prefix_line)s%(log_prefix)s SecurityEvent="(FailedACL|InvalidAccountID|ChallengeResponseFailed|InvalidPassword)",EventTV="([\d-]+|%(iso8601)s)",Severity="[\w]+",Service="[\w]+",EventVersion="\d+",AccountID="(\d*|<unknown>)",SessionID=".+",LocalAddress="IPV[46]/(UDP|TCP|WS)/[\da-fA-F:.]+/\d+",RemoteAddress="IPV[46]/(UDP|TCP|WS)/<HOST>/\d+"(,Challenge="[\w/]+")?(,ReceivedChallenge="\w+")?(,Response="\w+",ExpectedResponse="\w*")?(,ReceivedHash="[\da-f]+")?(,ACLName="\w+")?$ ^%(__prefix_line)s%(log_prefix)s "Rejecting unknown SIP connection from <HOST>"$ ^%(__prefix_line)s%(log_prefix)s Request (?:'[^']*' )?from '[^']*' failed for '<HOST>(?::\d+)?'\s\(callid: [^\)]*\) - (?:No matching endpoint found|Not match Endpoint(?: Contact)? ACL|(?:Failed|Error) to authenticate)\s*$ ignoreregex = # Author: Xavier Devlamynck / Daniel Black # # General log format - main/logger.c:ast_log # Address format - ast_sockaddr_stringify # # First regex: channels/chan_sip.c # # main/logger.c:ast_log_vsyslog - "in {functionname}:" only occurs in syslog |
Asterisk logger.conf configuration
Make sure to set
1 |
dateformat=%F %T |
and
1 |
messages => notice,warning,error |
in /etc/asterisk/logger.conf
Reload Asterisk logger with:
1 |
asterisk -rx "logger reload" |
And start fail2ban:
1 |
service fail2ban start |
Execute
1 |
iptables -L -v -n |
and you should see two new chains probably already filled with some banned IPs:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
... Chain f2b-asterisk-tcp (1 references) pkts bytes target prot opt in out source destination 0 0 REJECT all -- * * 185.40.4.84 0.0.0.0/0 reject-with icmp-port-unreachable 0 0 REJECT all -- * * 62.210.181.126 0.0.0.0/0 reject-with icmp-port-unreachable 2 144 RETURN all -- * * 0.0.0.0/0 0.0.0.0/0 Chain f2b-asterisk-udp (1 references) pkts bytes target prot opt in out source destination 2 1559 REJECT all -- * * 185.40.4.84 0.0.0.0/0 reject-with icmp-port-unreachable 3 2377 REJECT all -- * * 62.210.181.126 0.0.0.0/0 reject-with icmp-port-unreachable 4866 2409K RETURN all -- * * 0.0.0.0/0 0.0.0.0/0 |
You are all set!