Page tree
Skip to end of metadata
Go to start of metadata

Rules for a Free PBX Host Server

IP Tables rules

Protect yourself by only opening required ports (and limit brute force attempts at authenticating)

-A INPUT -p udp -m multiport --dports 5060,5061 -m set --match-set fail2ban-ASTERISK src -j REJECT --reject-with icmp-port-unreachable
-A INPUT -p tcp -m multiport --dports 5060,5061 -m set --match-set fail2ban-ASTERISK src -j REJECT --reject-with icmp-port-unreachable
-A INPUT -p tcp -m multiport --dports 22 -j fail2ban-ssh
-A INPUT -m set --match-set voip_bl src -j DROP
-A INPUT -i lo -j ACCEPT
-A INPUT -p udp -m udp --dport 10000:20000 -j ACCEPT
-A INPUT -p udp -m udp --dport 2727 -j ACCEPT
-A INPUT -p udp -m udp --dport 4569 -j ACCEPT
-A INPUT -s -p udp -m udp --dport 5060:5061 -j ACCEPT
-A INPUT -s -p tcp -m tcp --dport 5060:5061 -j ACCEPT
-A INPUT -s known_external_proxy -p udp -m udp --dport 5060:5061 -j ACCEPT
-A INPUT -p udp -m udp --dport 5060:5061 -m string --string "User-Agent: VaxSIPUserAgent" --algo bm --to 65535 -j DROP
-A INPUT -p udp -m udp --dport 5060:5061 -m string --string "User-Agent: friendly-scanner" --algo bm --to 65535 -j REJECT --reject-with icmp-port-unreachable
-A INPUT -p udp -m udp --dport 5060:5061 -m string --string "REGISTER sip:" --algo bm --to 65535 -m recent --set --name VOIP --rsource
-A INPUT -p udp -m udp --dport 5060:5061 -m string --string "REGISTER sip:" --algo bm --to 65535 -m recent --update --seconds 60 --hitcount 12 --rttl --name VOIP --mask --rsource -j DROP
-A INPUT -p udp -m udp --dport 5060:5061 -m string --string "INVITE sip:" --algo bm --to 65535 -m recent --set --name VOIPINV --rsource
-A INPUT -p udp -m udp --dport 5060:5061 -m string --string "INVITE sip:" --algo bm --to 65535 -m recent --update --seconds 60 --hitcount 12 --rttl --name VOIPINV --mask --rsource -j DROP
-A INPUT -p tcp -m tcp --dport 5060:5061 -m hashlimit --hashlimit-upto 6/sec --hashlimit-burst 5 --hashlimit-mode srcip,dstport --hashlimit-name tunnel_limit -j ACCEPT
-A INPUT -p udp -m udp --dport 5060:5061 -m hashlimit --hashlimit-upto 6/sec --hashlimit-burst 5 --hashlimit-mode srcip,dstport --hashlimit-name tunnel_limit -j ACCEPT
-A INPUT -s -p icmp -j ACCEPT
-A INPUT -s -p tcp -m tcp --dport 137 -j ACCEPT
-A INPUT -s -p tcp -m tcp --dport 138 -j ACCEPT
-A INPUT -s -p tcp -m tcp --dport 139 -j ACCEPT
-A INPUT -s -p tcp -m tcp --dport 445 -j ACCEPT
-A INPUT -s -p tcp -m tcp --dport 10000 -j ACCEPT
-A INPUT -s -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -s -p tcp -m tcp --dport 123 -j ACCEPT
-A INPUT -s -p udp -m udp --dport 123 -j ACCEPT
-A INPUT -s -p tcp -m tcp --dport 5038 -j ACCEPT
-A INPUT -s -p tcp -m tcp --dport 58080 -j ACCEPT
-A INPUT -s -p tcp -m tcp --dport 55050 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 443 -j ACCEPT
-A INPUT -s -p tcp -m tcp --dport 514 -j ACCEPT
-A INPUT -s -p udp -m udp --dport 514 -j ACCEPT

Note 1: Replace with your local network e.g.

Note 2: -s ensures that even if you open that port by mistake through your public router, it will be not respond to public hosts, and it will only respond to hosts on your intranet

Note 3: Opening 5060:5061 to the public is only necessary if you need to have clients connecting to your system from the internet. If you can avoid doing this (e.g. because all your clients are local desk phones, or use VPNs) remove all the 5060:5061 public access control and replace with just limiting access to your intranet instead:

-A INPUT -s -p udp -m udp --dport 5060 -j ACCEPT
-A INPUT -s -p tcp -m tcp --dport 5060 -j ACCEPT 

Port Names

Media Gateway Control Protocol2727MGCP
Asterisk API5038Asterisk

Fail 2 Ban

Protect yourself by preventing probes and brute force attacks

Install fail2ban and ipset on ubuntu

apt-get install fail2ban ipset


The following are extensions of the original Fail2Ban with iptables and Asterisk, updated it to catch some extra port scans/ probes, and use ipset.

Please refer to that article for background notes.



# Fail2Ban filter for asterisk authentication failures
__pid_re = (?:\[\d+\])
# All Asterisk log messages begin like this:
log_prefix= \[\]\s*(?:NOTICE|SECURITY)%(__pid_re)s:?(?:\[C-[\da-f]*\])? \S+:\d*
failregex = ^%(log_prefix)s Registration from '[^']*' failed for '<HOST>(:\d+)?' \(.*\) - (Wrong password|No matching peer found|Username\/auth name mismatch|Device does not match ACL|Peer is not supposed to register|ACL error \(permit\/deny\)|Not a local domain)$
        ^%(log_prefix)s Request from '[^']*' failed for '<HOST>(:\d+)?' \(.*\) - No matching endpoint found$
        ^%(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]+")?$
        ^\[\]\s*WARNING%(__pid_re)s:?(?:\[C-[\da-f]*\])? Ext\. s: "Rejecting unknown SIP connection from <HOST>"$
ignoreregex =

# Author: Xavier Devlamynck, extended by Graham Barnett


The following uses ipset rather than iptables as ipset is much faster and better

# "ignoreip" can be an IP address, a CIDR mask or a DNS host. Fail2ban will not
# ban a host which matches an address in this list. Several addresses can be
# defined using space separator.
ignoreip =

# Multiple jails, 1 per protocol, are necessary ATM:
# see
enabled  = true
filter   = asterisk
port     = 5060,5061
action   = iptables-ipset-proto4[name=ASTERISK, port='5060,5061', protocol=tcp]
#uncomment for bl           voipbl[serial=XXXXXXXXXX]
protocol = tcp
logpath  = /var/log/asterisk/fail2ban2
maxretry = 5
bantime = 259200

enabled  = true
filter   = asterisk
port     = 5060,5061
action   = iptables-ipset-proto6[name=ASTERISK, port='5060,5061', protocol=udp]
#uncomment for bl           voipbl[serial=XXXXXXXXXX]
protocol = udp
logpath  = /var/log/asterisk/fail2ban2
maxretry = 5
bantime = 259200

# Jail for more extended banning of persistent abusers
# !!! WARNING !!!
#   Make sure that your loglevel specified in fail2ban.conf/.local
#   is not at DEBUG level -- which might then cause fail2ban to fall into
#   an infinite loop constantly feeding itself with non-informative lines
enabled  = false
filter   = recidive
logpath  = /var/log/fail2ban.log
action   = iptables-ipset-proto6[name=recidive, protocol=all]
           sendmail-whois-lines[name=recidive, logpath=/var/log/fail2ban.log]
bantime  = 604800  ; 1 week
findtime = 86400   ; 1 day
maxretry = 5



VOIP Blacklist

Protect yourself by preventing known bad VOIP sources from trying to access your VOIP server

VoIPBL is a distributed VoIP blacklist that is aimed to protects against VoIP Fraud and minimizing abuse for network that have publicly accessible PBX's.       

Please see VoIP Blacklist for how to install a block list of known bad ip addresses.





Error rendering macro 'contentbylabel'

parameters should not be empty


  1. Graham,

    Sorry if this is not the right place, but I have found no other way to contact you.

    The iptables ruleset seems to be incorrect, the "recent" module doesn't have a "–mask" option.


      --mask netmask
      Netmask that will be applied to this recent list.

      1. Hi Graham,

        Thanks for your reply.
        The man page you're referring to is for iptables version 1.4.18.
        FreePBX 6.12.65 (Stable) is bundled with iptables 1.4.7 which does not support the --mask option there it seems.

  2. I believe that the default is, so I have removed the mask setting for FreePBX 6.12.65 etc

      126     if (rev == XT_RECENT_REV_1)
      127         memset(&info_v1->mask, 0xFF, sizeof(info_v1->mask));

  3. Good Day,

    I see this is a dated post (2015). I would like to know if the configs above are still valid? I've recently been placed in a position where I need to keep track of three FreePBX VoIP servers running We found that one server had some fraud calls placed to Africa. I begin poking around and found this post. On the machine in question I ran IPTABLES -S to see what the rules looked like. The first three statements are...


    I recall this being a bad deal. I learned that these should be set to DROP and then the following rules set in place ACCEPT or DROP ports, etc. 

    If IPTABLES is configured can I flush the rules and use the ipset configuration listed up above?

    We have fail2ban & ipset packages loaded (package info below). I have not found a ipset configuration file. Maybe ipset is not being used at this time? I executed ipset -l and got no response.

    fail2ban-fpbx.noarch 0.8.14-75.sng7

    ipset.x86_64 6.29-1.el7

    ipset-libs.x86_64 6.29-1.el7

    The VoIP Blacklist link looks like something I should implement that may help out. Has there been any feedback on its success? Has the Blacklist cut down on fraud activity? Guidance on this topic would be greatly appreciated.