Guides
fail2ban for Asterisk, FreePBX and other SIP servers
A PBX on a public IP gets SIP REGISTER floods within hours: bots guessing extension passwords to make expensive calls on your account. fail2ban's asterisk jail bans them on both TCP and UDP. Here's the setup for plain Asterisk, FreePBX, FreeSWITCH and Kamailio.
To protect Asterisk with fail2ban, enable the stock [asterisk] jail in /etc/fail2ban/jail.local and point logpath at Asterisk's log, usually /var/log/asterisk/messages plus the security log. The jail already bans ports 5060 and 5061 on both TCP and UDP. The asterisk filter matches failed registrations, unknown peers, rejected calls and PJSIP security events.
[asterisk]
enabled = true
backend = auto
logpath = /var/log/asterisk/messages
/var/log/asterisk/security
maxretry = 5
bantime = 1dbackend = auto makes the jail read the files even on Ubuntu 24.04, whose defaults-debian.conf switches every jail to the systemd journal.
What the stock asterisk jail does#
From jail.conf:
[asterisk]
port = 5060,5061
action_ = %(default/action_)s[name=%(__name__)s-tcp, protocol="tcp"]
%(default/action_)s[name=%(__name__)s-udp, protocol="udp"]
logpath = /var/log/asterisk/messages
maxretry = 10The jail runs two copies of your ban action, one named asterisk-tcp and one named asterisk-udp. SIP runs over UDP by default, and a jail with the usual protocol = tcp would ban the wrong traffic. Because the jail overrides action_, the TCP+UDP pair is kept even when you change banaction.
SIP scanners often probe other services too. To block a caught address on every port, use the all-ports action in the jail:
[asterisk]
enabled = true
backend = auto
banaction = %(banaction_allports)s
logpath = /var/log/asterisk/messages
/var/log/asterisk/securityThat still produces the -tcp/-udp pair, each blocking all ports for its protocol. If you also run RTP on UDP 10000–20000, an all-ports ban stops a banned scanner from sending media garbage as well.
What the asterisk filter matches#
The filter covers both the old chan_sip and the current chan_pjsip messages:
[2026-10-25 18:36:10] NOTICE[1638] chan_sip.c: Registration from '<sip:301@example.com>' failed for '203.0.113.42' - Wrong password
[2026-10-25 18:36:11] NOTICE[1943] res_pjsip/pjsip_distributor.c: Request 'REGISTER' from '<sip:100@192.0.2.10>' failed for '203.0.113.42:5072' (callid: abc123) - No matching endpoint found
[2026-10-25 18:36:12] NOTICE[3477] chan_sip.c: Call from '' (198.51.100.7:10836) to extension '0011441234567' rejected because extension not found in context 'default'.
[2026-10-25 18:36:13] SECURITY[1724] res_security_log.c: SecurityEvent="ChallengeResponseFailed",EventTV="2026-10-25T18:36:13.659+0000",Severity="Error",Service="PJSIP",EventVersion="1",AccountID="<unknown>",SessionID="3686a690",LocalAddress="IPV4/UDP/192.0.2.10/5060",RemoteAddress="IPV4/UDP/203.0.113.42/5084",Challenge="1569024763/510a7e",Response="8e1814",ExpectedResponse=""| Event | Source |
|---|---|
Registration from ... failed ... Wrong password / No matching peer found / Device does not match ACL |
chan_sip |
Request '...' from '...' failed for '<IP>' ... No matching endpoint found / Failed to authenticate |
chan_pjsip |
Call from ... rejected because extension not found in context |
chan_sip, chan_pjsip (toll-fraud probes) |
Host <IP> failed to authenticate, No registration for peer |
chan_iax2 |
SecurityEvent="InvalidAccountID / ChallengeResponseFailed / InvalidPassword / FailedACL" |
security log (any channel driver, also AMI) |
fail2ban 1.1.1 fixed the PJSIP "No matching endpoint found" rule for newer Asterisk versions that append after X tries in Y ms.
Turn on the Asterisk security log#
PJSIP reports most authentication failures as security events, and those go to the security log level only. Enable a channel for it in /etc/asterisk/logger.conf:
[logfiles]
messages => notice,warning,error
security => securityApply it with asterisk -rx 'logger reload'. Asterisk then writes /var/log/asterisk/security, which is why the jail above lists both files. A PJSIP-only server with just messages misses many failed logins.
If Asterisk logs to syslog or the journal instead of files, use backend = systemd. The filter has journalmatch = _SYSTEMD_UNIT=asterisk.service and handles the extra timestamp Asterisk prints in journal lines.
Test the jail#
sudo fail2ban-regex /var/log/asterisk/messages asterisk
sudo fail2ban-regex /var/log/asterisk/security asterisk
sudo fail2ban-client -t
sudo systemctl restart fail2ban
sudo fail2ban-client status asteriskA PBX on a public IP usually has matches within a day. If fail2ban-regex shows 0 matched lines but you can see failures in the log, the log format is probably customized (dateformat in logger.conf or a remote syslog prefix). Paste one line into the regex tester to compare. More on reading the output on the fail2ban-regex page.
Pair the jail with recidive: SIP bots come back the moment a ban expires, and a week-long all-ports ban on the second offence ends that.
FreePBX: Intrusion Detection is fail2ban#
FreePBX's Intrusion Detection (part of the Sangoma System Admin module) is fail2ban with a GUI. The module writes fail2ban's configuration, including /etc/fail2ban/jail.local, and shows bans in Admin → System Admin → Intrusion Detection. Don't install a second fail2ban.
Changes you make directly in jail.local get overwritten the next time the module rewrites it. Put local overrides in a separate file that's read after jail.local:
[DEFAULT]
ignoreip = 127.0.0.1/8 ::1 192.168.1.0/24The jail.local guide explains the load order: jail.d/*.local comes last, so it wins.
"FreePBX fail2ban not running"#
When the dashboard says fail2ban isn't running or Intrusion Detection won't start, find the real error first:
sudo systemctl status fail2ban
sudo journalctl -u fail2ban -n 50 --no-pager
sudo fail2ban-client -tCommon causes:
- Missing log file. On FreePBX 17 (Debian 12) there's no
/var/log/auth.logor/var/log/secure, so an SSH jail fails withHave not found any log file for ... jailand fail2ban refuses to start. Setbackend = systemdfor that jail in ajail.d/*.localfile, or create the missing file. See no log file. - A filter referenced by a jail doesn't exist (
Unable to read the filter). Usually left over from a module update. Reinstall or update the System Admin module. - Start limit hit. After several failed starts systemd stops trying. Fix the cause, then
systemctl reset-failed fail2ban && systemctl start fail2ban.
FreeSWITCH#
The stock [freeswitch] jail and freeswitch filter match Sofia auth failures:
2026-10-25 18:36:10.767815 [WARNING] sofia_reg.c:1478 SIP auth failure (INVITE) on sofia profile 'internal' for [1000@192.0.2.10] from ip 203.0.113.42FreeSWITCH only logs these when log-auth-failures is on in each Sofia profile (<param name="log-auth-failures" value="true"/>). Then set the log path, which in packaged installs is usually under /var/log/freeswitch/:
[freeswitch]
enabled = true
backend = auto
port = 5060,5061,5080,5081
logpath = /var/log/freeswitch/freeswitch.logThe stock jail uses port = 5060,5061 and a TCP+UDP action pair like Asterisk. Ports 5080/5081 are FreeSWITCH's default external profile. The filter's default mode = extra also counts auth challenges, which every normal client triggers once per call. If your phones get banned, switch to mode = normal.
Kamailio and OpenSIPS#
fail2ban ships no Kamailio filter, but you control what Kamailio logs. Log a line when an auth check fails with credentials present, then match it:
if (!auth_check("$fd", "subscriber", "1")) {
if (is_present_hf("Authorization") || is_present_hf("Proxy-Authorization")) {
xlog("L_WARN", "F2B-AUTH-FAIL: $rm from $si:$sp user=$fU\n");
}
auth_challenge("$fd", "0");
exit;
}[Definition]
failregex = ^\s*(?:\S+ )?\S*kamailio\[\d+\]: WARNING: <script>: F2B-AUTH-FAIL: \S+ from <ADDR>(?::\d+)?
ignoreregex =That regex matches a syslog line like Oct 25 18:36:10 sip1 /usr/sbin/kamailio[2210]: WARNING: <script>: F2B-AUTH-FAIL: REGISTER from 203.0.113.42:5060 user=100. Check your real line first, because log prefixes differ between versions and log_prefix settings. Kamailio's own pike and htable modules can block floods in-process, and they work well alongside fail2ban.
3CX#
3CX doesn't use fail2ban for SIP. It has a built-in anti-hacking feature that blacklists IPs after failed registrations, plus a global IP blacklist shared between 3CX installs, both managed in the 3CX admin console. Don't add an asterisk-style jail on a 3CX host. Use fail2ban there for SSH only.
asterisk and freeswitch filter reference#
The built-in filters this guide uses, exactly as fail2ban 1.1.1 ships them — with the log lines they match and a link to test them. All other built-in filters are in the filter library.
asterisk Asterisk PBX
The asterisk filter bans SIP and IAX clients with failed registrations, wrong passwords or unknown extensions. File: /etc/fail2ban/filter.d/asterisk.conf; jail [asterisk]; log on Debian/Ubuntu: /var/log/asterisk/messages.
Log lines it bans (from fail2ban's test suite):
[2012-02-13 17:21:54] NOTICE[1638] chan_sip.c: Registration from '<sip:301@example.com>' failed for '1.2.3.4' - Wrong password[2012-02-13 17:18:22] NOTICE[1638] chan_sip.c: Registration from '<sip:301@example.com>' failed for '1.2.3.4' - No matching peer found[2012-02-13 17:21:21] NOTICE[1638] chan_sip.c: Registration from '<sip:301@example.com>' failed for '1.2.3.4' - Username/auth name mismatch
Show the failregex fail2ban compiles (8 lines)
^(?:\[\])?\s*(?:<[^.]+\.[^.]+>\s+)?(?:\S+\s+)?(?:kernel:\s?\[ *\d+\.\d+\]:?\s+)?(?:@vserver_\S+\s+)?(?:(?:(?:\s*\[\d+\])?:\s+[\[\(]?asterisk(?:\(\S+\))?[\]\)]?:?|[\[\(]?asterisk(?:\(\S+\))?[\]\)]?:?(?:\s*\[\d+\])?:?)\s+)?(?:\[ID \d+ \S+\]\s+)?(?:NOTICE|SECURITY|WARNING)(?:\s*\[\d+\]):?(?:\[C-[\da-f]*\])?:? [^:]+:\d*(?:(?: in)? [^:]+:)? <F-CONTENT>.+</F-CONTENT>$^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)$
^Call (?:from '[^']*' )?\((?:(?:TCP|UDP):)?<HOST>:\d+\) to extension '[^']*' rejected because extension not found in context
^(?:Host )?<HOST> (?:failed (?:to authenticate\b|MD5 authentication\b)|tried to authenticate with nonexistent user\b)
^No registration for peer '[^']*' \(from <HOST>\)$
^hacking attempt detected '<HOST>'$
^SecurityEvent="(?:FailedACL|InvalidAccountID|ChallengeResponseFailed|InvalidPassword)"(?:(?:,(?!RemoteAddress=)\w+="[^"]*")*|.*?),RemoteAddress="IPV[46]/[^/"]+/<HOST>/\d+"(?:,(?!RemoteAddress=)\w+="[^"]*")*$
^"Rejecting unknown SIP connection from <HOST>(?::\d+)?"$
^Request (?:'[^']*' )?from '(?:[^']*|.*?)' failed for '<HOST>(?::\d+)?'\s\(callid: [^\)]*\) - (?:No matching endpoint found|Not match Endpoint(?: Contact)? ACL|(?:Failed|Error) to authenticate)\b[^']*$Test asterisk in the browser or on the server: sudo fail2ban-regex /var/log/asterisk/messages asterisk · source
freeswitch FreeSWITCH
The freeswitch filter bans SIP clients with failed registrations or calls on FreeSWITCH. File: /etc/fail2ban/filter.d/freeswitch.conf; jail [freeswitch]; log on Debian/Ubuntu: /var/log/freeswitch.log; modes: ddos, extra, normal.
Log lines it bans (from fail2ban's test suite):
2013-12-31 17:39:54.767815 [WARNING] sofia_reg.c:1533 SIP auth challenge (INVITE) on sofia profile 'internal' for [011448708752617@192.168.2.51] from ip 81.94.202.2512013-12-31 17:39:54.767815 [WARNING] sofia_reg.c:1478 SIP auth failure (INVITE) on sofia profile 'internal' for [000972543480510@192.168.2.51] from ip 5.11.47.2362013-12-31 17:39:54.767815 [WARNING] sofia_reg.c:2531 Can't find user [1001@192.168.2.51] from 5.11.47.236
Show the failregex fail2ban compiles (2 lines)
^^(?:\[\])?\s*(?:<[^.]+\.[^.]+>\s+)?(?:\S+\s+)?(?:kernel:\s?\[ *\d+\.\d+\]:?\s+)?(?:@vserver_\S+\s+)?(?:(?:(?:\[\d+\])?:\s+[\[\(]?freeswitch(?:\(\S+\))?[\]\)]?:?|[\[\(]?freeswitch(?:\(\S+\))?[\]\)]?:?(?:\[\d+\])?:?)\s+)?(?:\[ID \d+ \S+\]\s+)?[^\[]*\s*\[WARN(?:ING)?\](?: \[SOFIA\])? \[?sofia_reg\.c:\d+\]? <F-CONTENT>.+</F-CONTENT>$^Can't find user \[[^@]+@[^\]]+\] from <HOST>$
^SIP auth (?:failure|challenge) \((REGISTER|INVITE)\) on sofia profile \'[^']+\' for \[[^\]]*\] from ip <HOST>$Test freeswitch in the browser or on the server: sudo fail2ban-regex /var/log/freeswitch.log freeswitch · source
FAQ#
How do I set up fail2ban for Asterisk?#
Enable the stock [asterisk] jail in jail.local and set logpath to /var/log/asterisk/messages, plus /var/log/asterisk/security after adding security => security to logger.conf. The jail bans ports 5060 and 5061 on both TCP and UDP. Test with fail2ban-regex /var/log/asterisk/messages asterisk.
Why is fail2ban not running on FreePBX?#
Usually a jail can't find its log file, often SSH on FreePBX 17 (Debian 12, no auth.log), and fail2ban refuses to start. Run systemctl status fail2ban and fail2ban-client -t, then fix the jail with backend = systemd in a jail.d/*.local file, because the System Admin module rewrites jail.local.
Does the fail2ban asterisk filter work with PJSIP?#
Yes. It matches PJSIP's Request ... failed for '<IP>' ... No matching endpoint found and Failed to authenticate notices, plus ChallengeResponseFailed and InvalidPassword security events. Enable the security log channel in logger.conf, because many PJSIP failures only appear there.
Why does fail2ban ban SIP on TCP and UDP separately?#
The [asterisk] jail defines two actions, asterisk-tcp and asterisk-udp, because SIP mostly runs over UDP while TLS (5061) uses TCP. A single action with the default protocol = tcp would leave UDP 5060, the port bots actually use, open to the banned address.
Does 3CX need fail2ban?#
Not for SIP. 3CX blocks addresses with repeated failed registrations through its built-in anti-hacking feature and IP blacklist, configured in the admin console. fail2ban on a 3CX server is useful for SSH only.
Is there a fail2ban filter for Kamailio?#
No stock one. Log failed authentication with xlog from your routing script, using a fixed tag such as F2B-AUTH-FAIL, and write a short filter for that line. Kamailio's pike and htable modules can also rate-limit and block abusive sources inside Kamailio.
Spotted something wrong or out of date? Tell us — every page is checked against the current fail2ban release.