Asterisk + Fail2Ban

Asterisk 15 Centos 7 IPtables instead default firewalld

 mv /etc/fail2ban/jail.d/00-firewalld.conf /etc/fail2ban/jail.d/00-firewalld.disabled
 systemctl restart fail2ban

jail.conf

default action:

 banaction = iptables-multiport

full log by default

asterisk policy, log must exists:

[asterisk]
enabled = true
port     = 5060,5061
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"]
logpath  = /var/log/asterisk/full
maxretry = 10

use security log

etc/fail2ban/filterd/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 = SECURITY.* SecurityEvent="FailedACL".*RemoteAddress=".+?/.+?/<HOST>/.+?".*
            SECURITY.* SecurityEvent="InvalidAccountID".*RemoteAddress=".+?/.+?/<HOST>/.+?".*
            SECURITY.* SecurityEvent="ChallengeResponseFailed".*RemoteAddress=".+?/.+?/<HOST>/.+?".*
            SECURITY.* SecurityEvent="InvalidPassword".*RemoteAddress=".+?/.+?/<HOST>/.+?".*
 
# Option:  ignoreregex
# Notes.:  regex to ignore. If this regex matches, the line is ignored.
# Values:  TEXT
#
ignoreregex =

Asterisk Logger

/etc/asterisk/logger.conf

 secure => security
 CLI> logger reload

/etc/fail2ban/jail.conf

[asterisk]
...
logpath  = /var/log/asterisk/secure
...
 wget http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm &&
 wget http://rpms.famillecollet.com/enterprise/remi-release-6.rpm &&
 rpm -Uvh remi-release-6*.rpm epel-release-6*.rpm
 yum install fail2ban
 yum install phyton iptables 

устаревшее

устаревшее

Создадим правила фильтрации

 touch /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 =

Синтаксис для Asterisk 1.6 отличается отсутствием номера порта '<HOST>'

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>.*

Fail2ban содержит правила и фильтры для Asterisk по умолчанию

/etc/fail2ban/filter.d/asterisk.conf

# 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+\])

# All Asterisk log messages begin like this:
log_prefix= (?:NOTICE|SECURITY)%(__pid_re)s:?(?:\[C-[\da-f]*\])? \S+:\d*( in \w+:)?

failregex = ^(%(__prefix_line)s|\[\]\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 su$
            ^(%(__prefix_line)s|\[\]\s*)%(log_prefix)s Call from '[^']*' \(<HOST>:\d+\) to extension '\d+' rejected because extension not found in context 'default'\.$
            ^(%(__prefix_line)s|\[\]\s*)%(log_prefix)s Host <HOST> failed to authenticate as '[^']*'$
            ^(%(__prefix_line)s|\[\]\s*)%(log_prefix)s No registration for peer '[^']*' \(from <HOST>\)$
            ^(%(__prefix_line)s|\[\]\s*)%(log_prefix)s Host <HOST> failed MD5 authentication for '[^']*' \([^)]+\)$
            ^(%(__prefix_line)s|\[\]\s*)%(log_prefix)s Failed to authenticate (user|device) [^@]+@<HOST>\S*$
            ^(%(__prefix_line)s|\[\]\s*)%(log_prefix)s (?:handle_request_subscribe: )?Sending fake auth rejection for (device|user) \d*<sip:[^@]+@<HOST>>;tag=\w+\S*$
            ^(%(__prefix_line)s|\[\]\s*)%(log_prefix)s SecurityEvent="(FailedACL|InvalidAccountID|ChallengeResponseFailed|InvalidPassword)",EventTV="[\d-]+",Severity="[\w]+",Service="[\w]+",EventVersion="\d+",AccountID="\d*",SessionID="$
            ^(%(__prefix_line)s|\[\]\s*WARNING%(__pid_re)s:?(?:\[C-[\da-f]*\])? )Ext\. s: "Rejecting unknown SIP connection from <HOST>"$

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

устаревшее pjsip

устаревшее pjsip

Fail2ban PjSIP

# 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+\])

# All Asterisk log messages begin like this:
log_prefix= (?:NOTICE|SECURITY)%(__pid_re)s:?(?:\[C-[\da-f]*\])? \S+:\d*( in \w+:)?

failregex = ^(%(__prefix_line)s|\[\]\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|\[\]\s*)%(log_prefix)s Call from '[^']*' \(<HOST>:\d+\) to extension '\d+' rejected because extension not found in context 'default'\.$
            ^(%(__prefix_line)s|\[\]\s*)%(log_prefix)s Host <HOST> failed to authenticate as '[^']*'$
            ^(%(__prefix_line)s|\[\]\s*)%(log_prefix)s No registration for peer '[^']*' \(from <HOST>\)$
            ^(%(__prefix_line)s|\[\]\s*)%(log_prefix)s Host <HOST> failed MD5 authentication for '[^']*' \([^)]+\)$
            ^(%(__prefix_line)s|\[\]\s*)%(log_prefix)s Failed to authenticate (user|device) [^@]+@<HOST>\S*$
            ^(%(__prefix_line)s|\[\]\s*)%(log_prefix)s (?:handle_request_subscribe: )?Sending fake auth rejection for (device|user) \d*<sip:[^@]+@<HOST>>;tag=\w+\S*$
            ^(%(__prefix_line)s|\[\]\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]+")?(,ACLName="\w+")?$
            ^(%(__prefix_line)s|\[\]\s*WARNING%(__pid_re)s:?(?:\[C-[\da-f]*\])? )Ext\. s: "Rejecting unknown SIP connection from <HOST>"$
            ^(%(__prefix_line)s|\[\]\s*)%(log_prefix)s Request from '.*' failed for '<HOST>(:[0-9]{1,5})?' (.*) - (No matching endpoint found)$
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
 ^(%(__prefix_line)s|\[\]\s*)%(log_prefix)s Request from '.*' failed for '<HOST>(:[0-9]{1,5})?' (.*) - (No matching endpoint found)$
 
 ^(%(__prefix_line)s|\[\]\s*)%(log_prefix)s Request '.*' from '.*' failed for '<HOST>(:[0-9]{1,5})?' (.*) - (No matching endpoint found)$

/etc/fail2ban/jail.conf

[asterisk]

enabled  = true
filter   = asterisk
action   = iptables-multiport[name=asterisk-tcp, port="5060,5061", protocol=tcp]
           iptables-multiport[name=asterisk-udp, port="5060,5061", protocol=udp]
           sendmail-whois[name=Asterisk, dest=root@localhost, sender=fail2ban@localhost]
logpath  = /var/log/asterisk/messages
maxretry = 3
bantime = 259200

Или jail.local

[asterisk-iptables]
enabled  = true
filter   = asterisk
action   = iptables-allports[name=SIP, protocol=all]
           sendmail[name=SIP, dest=root@localhost, sender=root@localhost]
logpath  = /var/log/asterisk/messages
maxretry = 5
bantime = 1800

<spoiler|устаревшее>

/etc/fail2ban/jail.conf

[asterisk-iptables]

enabled  = true
filter   = asterisk
action   = iptables-allports[name=ASTERISK, protocol=all]
           sendmail-whois[name=ASTERISK, dest=root, sender=fail2ban@asterisk]
logpath  = /var/log/asterisk/messages
maxretry = 3
bantime = 259200

</spoiler>

/etc/asterisk/logger_logfiles_custom.conf

  messages => notice,warning,error
  # asterisk -rx "logger rotate"
 /etc/init.d/fail2ban start
 /etc/init.d/iptables start
 chkconfig iptables on
 chkconfig fail2ban on
 sipsak  -U  -s sip:s@192.168.0.1:5060
 sipsak  -U  -s sip:s@192.168.0.1:5060
 sipsak  -U  -s sip:s@192.168.0.1:5060
 iptables -L
 Chain fail2ban-ASTERISK (1 references)
 target     prot opt source               destination  
 DROP       all  --  192.168.0.22         anywhere
 RETURN     all  --  anywhere             anywhere     
 fail2ban-client status asterisk-iptables
Status for the jail: asterisk-iptables
|- filter
|  |- File list:	/var/log/asterisk/secure 
|  |- Currently failed:	0
|  `- Total failed:	3
`- action
   |- Currently banned:	1
   |  `- IP list:	192.168.0.22
   `- Total banned:	1

удалить правило из iptables

 iptables -D fail2ban-ASTERISK 1

дополнительно

Блокировка пакетов средствами IPtables по названию сканера

iptables -I INPUT -p udp --dport 5060 -m string --string "friendly-scanner" --algo bm -j DROP
iptables -I INPUT -p udp --dport 5060 -m string --string "sip-scan" --algo bm -j DROP
iptables -I INPUT -p udp --dport 5060 -m string --string "sundayddr" --algo bm -j DROP
iptables -I INPUT -p udp --dport 5060 -m string --string "iWar" --algo bm -j DROP
iptables -I INPUT -p udp --dport 5060 -m string --string "sipsak" --algo bm -j DROP
iptables -I INPUT -p udp --dport 5060 -m string --string "sipvicious" --algo bm -j DROP

banned examples

banned examples

Chain fail2ban-asterisk-udp (1 references)
target     prot opt source               destination
REJECT     all  --  ns304512.ip-94-23-212.eu  anywhere            reject-with icmp-port-unreachable
REJECT     all  --  69.30.254.10         anywhere            reject-with icmp-port-unreachable
REJECT     all  --  178.32.131.44        anywhere            reject-with icmp-port-unreachable
REJECT     all  --  s18080713.onlinehome-server.info  anywhere            reject-with icmp-port-unreachable
REJECT     all  --  192.187.109.154      anywhere            reject-with icmp-port-unreachable
REJECT     all  --  46.165.251.197       anywhere            reject-with icmp-port-unreachable
REJECT     all  --  212-129-55-216.rev.poneytelecom.eu  anywhere            reject-with icmp-port-unreachable
REJECT     all  --  static-ip-188-138-120-135.inaddr.ip-pool.com  anywhere            reject-with icmp-port-unreachable
REJECT     all  --  s18081076.onlinehome-server.info  anywhere            reject-with icmp-port-unreachable
REJECT     all  --  212-129-54-198.rev.poneytelecom.eu  anywhere            reject-with icmp-port-unreachable
REJECT     all  --  62-210-148-71.rev.poneytelecom.eu  anywhere            reject-with icmp-port-unreachable
REJECT     all  --  195-154-34-157.rev.poneytelecom.eu  anywhere            reject-with icmp-port-unreachable
REJECT     all  --  107.150.61.186       anywhere            reject-with icmp-port-unreachable
REJECT     all  --  h31-3-236-162.host.redstation.co.uk  anywhere            reject-with icmp-port-unreachable
REJECT     all  --  107.150.52.234       anywhere            reject-with icmp-port-unreachable
REJECT     all  --  95.211.117.10        anywhere            reject-with icmp-port-unreachable
RETURN     all  --  anywhere             anywhere

Нажмите, чтобы отобразить

Нажмите, чтобы скрыть

Fail2Ban:
This is a pretty simple implementation, and can be done quickly. I have already setup an email relay on my Asterisk box to email me, so you may need to do that before hand or modify the settings slightly. I really enjoy being able to know by email what bad things are happening.
First, modify Asterisk to spit out errors in a separate log file:
Edit /etc/asterisk/logger.conf and:
– Un-comment the first dateformat line under [general]:

1
dateformat=%F %T   ; ISO 8601 date format
– Then, modify the messages line near the bottom and add security:

1
messages => security,notice,warning,error
Restart the Asterisk logger module to make the changes take effect:


sudo asterisk -rx "logger reload"
Now, install fail2ban:


sudo apt-get -y install fail2ban
Add the folowing to the end of /etc/fail2ban/jail.conf:


[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=dest@email.here, sender=fail2ban@address.here]
logpath  = /var/log/asterisk/security
maxretry = 4
findtime = 21600
bantime = 86400
Then, move the existing asterisk.conf in filter.d to a backup in the directory below (or wherever else you would like):


cd /etc/fail2ban/filter.d
sudo mv asterisk.conf ../asterisk.conf.orig
Create a new asterisk.conf in filter.d and add the following:

# Fail2Ban configuration file
#
#
# $Revision: 251 $
#
 
[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
#
# Asterisk 1.8 uses Host:Port format which is reflected here
 
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>:.*' - 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.* .*: Registration from '.*' failed for '<HOST>:.*' - Peer is not supposed to register
            NOTICE.* .*: Registration from '.*' failed for '<HOST>:.*' - ACL error (permit/deny)
            NOTICE.* .*: Registration from '.*' failed for '<HOST>:.*' - Device does not match ACL
            NOTICE.* .*: Registration from '\".*\".*' failed for '<HOST>:.*' - No matching peer found
            NOTICE.* .*: Registration from '\".*\".*' failed for '<HOST>:.*' - Wrong password
            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>.*
            NOTICE.* .*: <HOST> failed to authenticate as '.*'
            NOTICE.* .*: <HOST> tried  to authenticate with nonexistent user '.*'
            VERBOSE.*SIP/<HOST>-.*Received incoming SIP connection from unknown peer
   
# Option:  ignoreregex
# Notes.:  regex to ignore. If this regex matches, the line is ignored.
# Values:  TEXT
#
ignoreregex =
Restart fail2ban:

1
sudo service fail2ban restart

В случае если fail2ban работает, но блокировка не происходит, следует проверить лог: /var/log/fail2ban (информативность лога можно настроить в конфигурационном файле fail2ban)

Частые ошибки:

ERROR NOK: («Unable to compile regular expression …) - в случае ошибки в регулярном выражении

ERROR NOK: ('Action iptables-multiport already exists',) - в случае если версия fail2ban требует разделения действий. В таком случае нужно указать в jail.conf разные имена для действий: actname=asterisk-tcp и actname=asterisk-udp

[asterisk]

enabled  = true
filter   = asterisk
action   = iptables-multiport[actname=asterisk-tcp,name=asterisk-tcp, port="5060,5061", protocol=tcp]
           iptables-multiport[actname=asterisk-udp,name=asterisk-udp, port="5060,5061", protocol=udp]
           sendmail-whois[name=Asterisk, dest=root@localhost, sender=fail2ban@localhost]
logpath  = /var/log/asterisk/secure
maxretry = 3
bantime = 259200
  • artikle/fail2ban.txt
  • Последние изменения: 2020/10/26