Learn how to deploy Fail2ban with Asterisk to detect and automatically block SIP brute force attacks, credential stuffing, and registration floods in production ViciDial environments.
Overview
SIP brute force attacks represent one of the most persistent threats to Asterisk PBX systems. Attackers continuously probe your system attempting to register accounts, make unauthorized calls, or enumerate valid extensions. Without proper protection, these attacks consume bandwidth, degrade call quality, and can enable toll fraud costing thousands of dollars per hour.
This tutorial covers production-grade Fail2ban configuration specifically tuned for Asterisk SIP environments. You'll learn to detect attack patterns, create intelligent filters that minimize false positives, and automatically block offending IP addresses at the firewall level.
Prerequisites
Before implementing this guide, ensure you have:
- Asterisk 13+ running on a Linux system (CentOS 7+, Ubuntu 18.04+, Debian 10+)
- ViciDial installation (optional, but this tutorial assumes ViciDial 2.14+)
- Root or sudo access to the server
- Fail2ban 0.10+ installed (
sudo apt-get install fail2banoryum install fail2ban) - iptables firewall (or ufw on Ubuntu — we'll cover both)
- Basic Linux command-line proficiency
- SSH access for remote administration
- Asterisk SIP logs enabled and writing to
/var/log/asterisk/messages
Verify your Asterisk version:
asterisk -v
Verify Fail2ban installation:
fail2ban-client --version
Section 1: Understanding SIP Attack Patterns
Common SIP Attacks Against Asterisk
SIP brute force attacks follow recognizable patterns in Asterisk logs:
1. Registration Attacks (Most Common)
[timestamp] NOTICE[thread]: chan_sip.c:2xxx in handle_request_register():
Registration from '<sip:6001@attacker-ip>' failed for 'attacker-ip' -
Wrong password
2. Invitation Floods
[timestamp] WARNING[thread]: chan_sip.c:xxxx in handle_request_invite():
Call from 'sip:attacker@attacker-ip' to extension rejected -
peer not found
3. Options Enumeration Multiple OPTIONS requests probing for valid extensions or server details.
4. Extension Enumeration Rapid INVITE requests to sequential extensions (6001, 6002, 6003, etc.) attempting to discover valid users.
Why Standard Fail2ban Filters Are Insufficient
Default Fail2ban filters for Asterisk are often:
- Too aggressive (blocking legitimate carriers)
- Too lenient (missing credential stuffing attacks)
- Poorly tuned for modern SIP attack patterns
- Generating excessive false positives
This tutorial provides battle-tested filters refined from years of ViciDial production deployments.
Section 2: Preparing Your Asterisk Logging
Verify SIP Debug Logging is Enabled
Check your /etc/asterisk/sip.conf or /etc/asterisk/sip-vicidial.conf:
[general]
; Ensure these settings exist
sip_debug = no
; But enable logging for failed registrations
sip_logger = yes
Enable Verbose Logging for Failed Registrations
Ensure your logger.conf captures SIP messages:
cat /etc/asterisk/logger.conf
Expected output should include:
[logfiles]
messages => notice,warning,error
full => notice,warning,error,debug,verbose
Test Logging
Trigger a failed registration attempt and verify it appears in logs:
tail -f /var/log/asterisk/messages | grep -i "registration\|failed\|wrong password"
When you get a failed SIP registration attempt (try registering with wrong credentials), you should see:
[timestamp] NOTICE[thread]: chan_sip.c:2924 in handle_request_register():
Registration from '<sip:[email protected]>' failed for '192.168.1.100' -
Wrong password
Section 3: Creating Custom Fail2ban Filters for Asterisk SIP
Create the Filter File
Create a new filter specifically for SIP attacks:
sudo nano /etc/fail2ban/filter.d/asterisk-sip-vicidial.conf
Paste the following comprehensive filter configuration:
# Fail2ban filter for Asterisk SIP brute force attacks
# Designed for ViciDial production environments
# Detects registration failures, invitation rejections, and credential stuffing
[Definition]
failregex = ^.*\[.*\].*Registration from '<sip:.*@<HOST>>' failed for '<HOST>'.*$
^.*\[.*\].*Registration from '<sip:.*@<HOST>>' failed - .*$
^.*\[.*\].*Call from 'sip:.*@<HOST>' to extension .* rejected.*$
^.*\[.*\].*sip:.*@<HOST>.*peer not found.*$
^.*\[.*\].*<HOST>.*REGISTER.*401 Unauthorized.*$
^.*\[.*\].*<HOST>.*INVITE.*401 Unauthorized.*$
^.*\[.*\].*<HOST>.*REGISTER.*403 Forbidden.*$
^.*\[.*\].*<HOST>.*INVITE.*403 Forbidden.*$
^.*\[.*\].*<HOST>.*ACK.*408 Request Timeout.*$
ignoreregex = ^.*from '127\.0\.0\.1'.*$
^.*from 'localhost'.*$
^.*from '::1'.*$
# Explanation:
# failregex: Matches various SIP authentication failures
# ignoreregex: Prevents false positives from localhost
Create an Aggressive Filter for Extension Enumeration
Create a separate filter for detecting extension enumeration attacks:
sudo nano /etc/fail2ban/filter.d/asterisk-sip-enum.conf
# Fail2ban filter for SIP extension enumeration
# Detects rapid INVITE/OPTIONS to non-existent extensions
[Definition]
failregex = ^.*\[.*\].*<HOST>.*INVITE.*to extension.*not found.*$
^.*\[.*\].*Call from 'sip:.*@<HOST>' to extension .* rejected.*$
^.*\[.*\].*<HOST>.*Extension '.*' does not exist.*$
ignoreregex = ^.*from 'localhost'.*$
^.*from '127\.0\.0\.1'.*$
Create a Filter for Invitation/Call Floods
sudo nano /etc/fail2ban/filter.d/asterisk-sip-flood.conf
# Fail2ban filter for SIP flooding attacks
# Detects rapid call attempts from single source
[Definition]
failregex = ^.*\[.*\].*<HOST>.*INVITE.*$
ignoreregex = ^.*from 'localhost'.*$
^.*from '127\.0\.0\.1'.*$
Verify Filter Syntax
Test your filter configurations:
sudo fail2ban-regex /var/log/asterisk/messages /etc/fail2ban/filter.d/asterisk-sip-vicidial.conf
Expected output shows matched patterns and statistics. If you see "0 matches," your filter may need adjustment. Check the exact log format in your messages file:
grep -i "registration\|failed\|wrong password" /var/log/asterisk/messages | head -5
Section 4: Creating Fail2ban Jails for Asterisk SIP
Create the Main Asterisk SIP Jail
Create the jail configuration:
sudo nano /etc/fail2ban/jail.d/asterisk-sip.conf
Paste the following production-grade configuration:
# Fail2ban jail for Asterisk SIP brute force protection
# Designed for ViciDial production environments
[asterisk-sip]
enabled = true
port = sip
filter = asterisk-sip-vicidial
logpath = /var/log/asterisk/messages
maxretry = 5
findtime = 600
bantime = 3600
action = iptables-multiport[name=AsteriskSIP, port="5060,5061", protocol=udp]
iptables-multiport[name=AsteriskSIP, port="5060,5061", protocol=tcp]
sendmail-whois[name=AsteriskSIP, dest=root@localhost, sender=fail2ban@localhost]
# Configuration explanation:
# maxretry: Block after 5 failed attempts (adjust based on legitimate traffic)
# findtime: Within 600 seconds (10 minutes)
# bantime: Block for 3600 seconds (1 hour)
# port: Standard SIP ports (UDP and TCP)
# action: Block with iptables AND send email notification
[asterisk-sip-enum]
enabled = true
port = sip
filter = asterisk-sip-enum
logpath = /var/log/asterisk/messages
maxretry = 3
findtime = 60
bantime = 86400
action = iptables-multiport[name=AsteriskEnum, port="5060,5061", protocol=udp]
iptables-multiport[name=AsteriskEnum, port="5060,5061", protocol=tcp]
# Extension enumeration attack settings (more aggressive)
# maxretry: Block after just 3 attempts to non-existent extensions
# findtime: Within 60 seconds
# bantime: Block for 24 hours (86400 seconds)
[asterisk-sip-flood]
enabled = true
port = sip
filter = asterisk-sip-flood
logpath = /var/log/asterisk/messages
maxretry = 30
findtime = 60
bantime = 7200
action = iptables-multiport[name=AsteriskFlood, port="5060,5061", protocol=udp]
iptables-multiport[name=AsteriskFlood, port="5060,5061", protocol=tcp]
# Call flood settings
# maxretry: Allow 30 calls per minute (tune based on your capacity)
# bantime: Block for 2 hours if exceeded
Section 5: Whitelisting Legitimate Traffic
Create IP Whitelist for Known Carriers
Critical for avoiding false positives with carrier IP ranges:
sudo nano /etc/fail2ban/jail.local
Add a DEFAULT section with ignored IPs:
[DEFAULT]
# Whitelist localhost
ignoreip = 127.0.0.1/8 ::1
192.168.0.0/16
10.0.0.0/8
172.16.0.0/12
# Add your carrier/provider IPs (replace with your actual IPs)
# Example: Major carrier registration servers
; ignoreip = 203.0.113.10 198.51.100.20 192.0.2.30
# Destemail for notifications
destemail = [email protected]
sendername = Fail2ban
action = %(action_)s
ViciDial-Specific Whitelist Configuration
For ViciDial with multiple carriers, create a dynamic whitelist:
sudo nano /etc/fail2ban/ip-whitelist.txt
# Whitelist ViciDial internal IPs
127.0.0.1
192.168.1.0/24
# Add your carrier IPs here (one per line)
203.0.113.50
203.0.113.51
203.0.113.52
Query your ViciDial database for active carrier IPs and add them automatically:
#!/bin/bash
# /usr/local/bin/update-fail2ban-whitelist.sh
# Run daily via cron to whitelist all ViciDial carriers
mysql -u root -pYOURPASSWORD -e "
SELECT DISTINCT carrier_ip FROM asterisk.vicidial_carrier_log
WHERE call_date > DATE_SUB(NOW(), INTERVAL 7 DAY)
AND carrier_ip IS NOT NULL
AND carrier_ip != '0.0.0.0';" | grep -v carrier_ip >> /etc/fail2ban/ip-whitelist.txt
# Remove duplicates
sort /etc/fail2ban/ip-whitelist.txt | uniq > /tmp/whitelist && mv /tmp/whitelist /etc/fail2ban/ip-whitelist.txt
fail2ban-client set asterisk-sip banip 0.0.0.0
Add to crontab:
0 2 * * * /usr/local/bin/update-fail2ban-whitelist.sh
Section 6: Starting and Validating Fail2ban
Restart Fail2ban Service
sudo systemctl restart fail2ban
sudo systemctl enable fail2ban
Verify service status:
sudo systemctl status fail2ban
Verify Jails are Active
sudo fail2ban-client status
Expected output:
Status
|- Number of jail: 3
`- Jail list: asterisk-sip, asterisk-sip-enum, asterisk-sip-flood
Check Individual Jail Status
sudo fail2ban-client status asterisk-sip
Expected output:
Status for the jail: asterisk-sip
|- Filter
| |- Currently failed: 0
| |- Total failed: 0
| `- File list: /var/log/asterisk/messages
`- Actions
|- Currently banned: 0
|- Total banned: 0
`- Ban list:
View Fail2ban Log
tail -f /var/log/fail2ban.log
Watch for initialization messages:
2024-XX-XX XX:XX:XX asterisk-sip[XXXX]: Set banTime = 3600
2024-XX-XX XX:XX:XX asterisk-sip[XXXX]: Set findTime = 600
2024-XX-XX XX:XX:XX asterisk-sip[XXXX]: Set maxRetry = 5
Section 7: Testing Your Configuration
Simulate a Brute Force Attack
From a test machine (NOT production):
# Simulate failed registration attempts
for i in {1..6}; do
sipsak -s sip:6001@your-asterisk-ip -C sip:badpass@your-asterisk-ip
sleep 2
done
Monitor Fail2ban in Real-Time
tail -f /var/log/fail2ban.log
You should see:
2024-XX-XX XX:XX:XX asterisk-sip[XXXX]: Found 192.168.1.100 - 2024-XX-XX XX:XX:XX
2024-XX-XX XX:XX:XX asterisk-sip[XXXX]: VERBOSE: ban IPs: ['192.168.1.100']
Check iptables Rules
sudo iptables -L | grep -i asterisk
You should see blocking rules:
Chain f2b-AsteriskSIP (2 references)
target prot opt source destination
DROP all -- 192.168.1.100 anywhere
View Banned IPs
sudo fail2ban-client status asterisk-sip
Shows:
`- Ban list: 192.168.1.100
Section 8: ViciDial Integration & Monitoring
Query ViciDial Logs for Brute Force Evidence
Check if attacks appear in ViciDial database:
mysql -u root -pPASSWORD asterisk -e "
SELECT UNIX_TIMESTAMP(call_date) as timestamp,
extension,
caller_id_number,
remote_ip,
call_status
FROM vicidial_log
WHERE call_status = 'FAILED'
AND call_date > DATE_SUB(NOW(), INTERVAL 1 HOUR)
ORDER BY call_date DESC LIMIT 20;
"
Create Alert Dashboard
Add to /vicidial/admin/index.php or create a monitoring script:
#!/bin/bash
# /usr/local/bin/sip-attack-monitor.sh
BANNED_IPS=$(sudo fail2ban-client status asterisk-sip | grep "Ban list:" | awk '{print $NF}')
FAILED_REGS=$(grep -c "Wrong password" /var/log/asterisk/messages | tail -100)
echo "=== SIP Security Status ==="
echo "Currently Banned IPs: $BANNED_IPS"
echo "Failed Registrations (last 100): $FAILED_REGS"
if [ "$FAILED_REGS" -gt 50 ]; then
echo "ALERT: High number of failed registrations detected!"
fi
Enable Email Notifications
Update /etc/fail2ban/jail.d/asterisk-sip.conf actions:
action = iptables-multiport[name=AsteriskSIP, port="5060,5061", protocol=udp]
iptables-multiport[name=AsteriskSIP, port="5060,5061", protocol=tcp]
sendmail-whois[name=AsteriskSIP, [email protected], sender=fail2ban@yourhost]
Verify sendmail is installed:
sudo apt-get install sendmail
Section 9: Fine-Tuning for Your Environment
Adjusting Thresholds for High-Volume Environments
If you're running a high-volume ViciDial system with legitimate carrier traffic, adjust:
[asterisk-sip]
maxretry = 10 # Increased from 5
findtime = 900 # Increased to 15 minutes
bantime = 1800 # Reduced to 30 minutes
Handling Legitimate User Mistakes
Users entering wrong passwords repeatedly:
[asterisk-sip]
maxretry = 10 # Allow 10 attempts before blocking
findtime = 1800 # Within 30 minutes
Aggressive Mode for Known Attack Periods
If you're under active attack, temporarily increase sensitivity:
sudo fail2ban-client set asterisk-sip maxretry 2
sudo fail2ban-client set asterisk-sip bantime 86400
Revert afterward:
sudo fail2ban-client set asterisk-sip maxretry 5
sudo fail2ban-client set asterisk-sip bantime 3600
Section 10: Advanced Filtering Techniques
Rate-Based Blocking
Add to your filter for per-second limiting:
[asterisk-sip-rate]
enabled = true
filter = asterisk-sip-vicidial
logpath = /var/log/asterisk/messages
maxretry = 20
findtime = 10
bantime = 1800
action = iptables-multiport[name=AsteriskRate, port="5060,5061", protocol=udp]
Blocks IPs generating more than 20 attempts in 10 seconds.
Geographic-Based Blocking (Optional)
For additional security, block entire geographic regions (use with caution):
sudo apt-get install geoip-bin geoip-database
# Create filter
nano /etc/fail2ban/filter.d/asterisk-sip-geo.conf
[Definition]
failregex = ^.*\[.*\].*<HOST>.*Registration.*failed.*$
ignoreregex = ^.*localhost.*$
Then use geoiplookup in custom actions (advanced topic).
Section 11: Troubleshooting
Jail Not Detecting Attacks
Problem: Fail2ban shows 0 failed attempts despite ongoing attacks.
Solution:
- Verify filter regex against actual log entries:
sudo fail2ban-regex /var/log/asterisk/messages /etc/fail2ban/filter.d/asterisk-sip-vicidial.conf -v
- Check log format matches your Asterisk version:
grep "Registration from" /var/log/asterisk/messages | head -3
- Compare against filter definition in
.conffile and adjust<HOST>placement
Excessive False Positives
Problem: Legitimate users and carriers getting blocked.
Solution:
- Increase
maxretry:
sudo fail2ban-client set asterisk-sip maxretry 10
- Add carrier IPs to whitelist:
[DEFAULT]
ignoreip = 127.0.0.1/8 203.0.113.0/24 198.51.100.0/24
- Temporarily disable aggressive jails:
sudo fail2ban-client set asterisk-sip-enum enabled false
Fail2ban Not Starting
Problem: Service fails to start with no error message.
Solution:
- Check syntax:
sudo fail2ban-client -d
- Review logs:
sudo journalctl -u fail2ban -n 50
- Verify file permissions:
sudo chown -R root:root /etc/fail2ban/
sudo chmod -R 755 /etc/fail2ban/
IP Not Being Banned Despite Multiple Failures
Problem: Known attacking IP not appearing in ban list.
Solution:
- Verify IP is actually in logs:
grep "192.168.1.100" /var/log/asterisk/messages | wc -l
- Check if IP is whitelisted:
sudo fail2ban-client get asterisk-sip ignoreself
- Manually test the ban:
sudo fail2ban-client set asterisk-sip banip 192.168.1.100
iptables Rules Not Applied
Problem: IPs banned in Fail2ban but traffic still reaching Asterisk.
Solution:
- Verify iptables has rules:
sudo iptables -L | grep -i asterisk
sudo iptables -L | grep DROP
- Check if ufw is interfering:
sudo ufw status
- Reinstall iptables action:
sudo fail2ban-client stop asterisk-sip
sudo fail2ban-client start asterisk-sip
Ports Not Matching Configuration
Problem: Filter works but action doesn't block SIP ports.
Solution:
Ensure your jail specifies ports explicitly:
[asterisk-sip]
port = 5060,5061
And action references them:
action = iptables-multiport[name=AsteriskSIP, port="5060,5061", protocol=udp]
Section 12: Maintenance & Ongoing Management
Regular Fail2ban Health Checks
Create a weekly audit script:
#!/bin/bash
# /usr/local/bin/fail2ban-audit.sh
echo "=== FAIL2BAN AUDIT REPORT ==="
echo "Generated: $(date)"
echo ""
echo "Service Status:"
systemctl is-active fail2ban
echo ""
echo "Jail Summary:"
fail2ban-client status | grep "Number of jail"
echo ""
echo "Active Bans:"
fail2ban-client status asterisk-sip | grep "Total banned"
fail2ban-client status asterisk-sip-enum | grep "Total banned"
fail2ban-client status asterisk-sip-flood | grep "Total banned"
echo ""
echo "Failed Registrations (past 24h):"
grep -c "Wrong password" /var/log/asterisk/messages
echo ""
echo "Recent Banked IPs:"
fail2ban-client status asterisk-sip | grep "Ban list" -A 5
Schedule it:
echo "0 3 * * 0 /usr/local/bin/fail2ban-audit.sh | mail -s 'Fail2ban Audit' [email protected]" | crontab -
Unban Legitimate IPs
If you accidentally blocked a carrier:
sudo fail2ban-client set asterisk-sip unbanip 203.0.113.50
View Ban History
grep "Ban " /var/log/fail2ban.log | tail -20
Backup Your Configuration
sudo tar -czf /backup/fail2ban-config-$(date +%Y%m%d).tar.gz /etc/fail2ban/
Summary
This tutorial provided production-grade Fail2ban configuration specifically designed for Asterisk and ViciDial environments. You've learned to:
- Detect SIP attacks using custom-tuned filters matching registration failures, enumeration attempts, and call floods
- Deploy intelligent jails with appropriate thresholds for your environment
- Whitelist legitimate traffic to prevent blocking carriers and internal systems
- Monitor and test configurations to ensure proper functionality
- Integrate with ViciDial for comprehensive threat awareness
- Troubleshoot common issues preventing false positives and ensuring coverage
- Maintain ongoing security through regular audits and updates
Key takeaways:
- Start conservative: Set high maxretry values and lower them gradually based on real traffic patterns
- Whitelist aggressively: Every legitimate carrier and system prevents false positives
- Monitor continuously: Automated alerting catches problems before they impact service
- Test thoroughly: Simulate attacks in staging before deploying to production
- Document everything: Note all custom IPs, exceptions, and threshold changes
Your Asterisk system is now protected against the most common SIP attack vectors. Combined with strong extension passwords, disabled auto-provisioning, and restricted dialing permissions, Fail2ban significantly reduces your attack surface.
For ongoing updates, monitor Fail2ban's GitHub repository and subscribe to Asterisk security mailing lists. SIP attack patterns evolve constantly, and staying informed ensures your defenses remain effective.