Hardening a public-facing PBX — fail2ban, allowlists, pjsip security, port 5060 reality
A PBX with port 5060 on the public internet receives SIP brute-force traffic from the moment it boots. The attackers are looking for weak extension passwords to compromise and use for toll fraud. Within hours of an unprotected PBX going public, you can rack up thousands of dollars in fraudulent calls. This article covers the layered hardening that prevents this.
The threat in 30 seconds
Automated scanners probe SIP ports across the internet continuously. When they find one, they try common extension numbers (1000, 100, sip, voip) with common passwords. If they get a successful registration, they use the compromised extension to place outbound calls to premium-rate international numbers. The carrier bills the PBX owner for the calls. Discovering this on Monday morning is unpleasant.
Layer 1 — Strong passwords
The single most effective control. Every extension password should be:
- At least 16 characters.
- Generated randomly (not "extension number plus year").
- Different per extension.
- Different from the SIP user name.
FreePBX® generates random passwords by default when you create extensions. Don't override with something memorable.
Layer 2 — Responsive Firewall
FreePBX includes the Responsive Firewall (System Admin → Intrusion Detection). It does two things:
- Allowlists known good sources: trusted networks (your offices), your carrier IPs, and dynamically IPs that successfully registered an extension.
- Blocks traffic from non-allowlisted sources that fail authentication or send protocol-violating messages.
Setup:
- System Admin → Intrusion Detection → enable.
- Settings → Network → add your trusted networks (office LAN, home, etc.) under "Local Networks."
- Connectivity → Trunks → verify each carrier's IP/CIDR is in the trust list.
Result: random scanners can't get past the firewall at all. Brute force attempts go nowhere because the packets are dropped before Asterisk sees them.
Layer 3 — fail2ban
fail2ban watches Asterisk logs for failed authentication and auto-bans the source IP after N tries. Default FreePBX install includes it; verify it's running:
fail2ban-client status
fail2ban-client status asterisk
You should see active jails for asterisk and recent banned IPs. If you don't, check /etc/fail2ban/jail.local:
[asterisk]
enabled = true
filter = asterisk
action = iptables-allports[name=ASTERISK, protocol=all]
logpath = /var/log/asterisk/messages
maxretry = 5
findtime = 600
bantime = 3600
Lower maxretry to 3 and raise bantime to 86400 (24 hours) on PBXes under heavy attack.
Layer 4 — pjsip security settings
In Asterisk pjsip config, several settings reduce attack surface:
- allow_subscribe = no — disables SIP SUBSCRIBE outside known endpoints. Reduces scanner info-gathering.
- auth_type = userpass (default; don't change to "anonymous").
- identify_by = username,ip — accept endpoints by username AND verify source IP (where feasible).
- allow_overlap = no — disables overlap dialing.
Layer 5 — Outbound call rate limits
If something does get through and starts placing fraud calls, rate limits cap the damage. In FreePBX:
- Outbound Routes → on each route, set a low max concurrent call limit. A small office doesn't need to place 50 simultaneous outbound calls; 5 is plenty.
- Class of Service module (commercial): set per-extension outbound call limits. Front-desk extension can call anywhere; conference room extension can only call within the office.
Layer 6 — Restrict international dialing
Toll-fraud calls are almost always international (premium- rate numbers in obscure countries). Restrict outbound dial patterns:
- Outbound Route for international: require explicit prefix (011 then country code).
- Set the international route to require a PIN before connecting, or restrict to specific extensions that need international.
- If you don't actually call internationally: block the international route entirely. Easy to undo when you legitimately need it.
Layer 7 — Monitoring
Be alerted to anomalies, not just to outright breaches:
- CDR-based alerts. A script that runs every 10 minutes against the CDR table, flags > N calls to > N unique international numbers in the last hour. Open-source examples exist; not too hard to write.
- Failed registration counts. Watch fail2ban ban counts. A sudden spike suggests targeted attack.
- Carrier portal alerts. Most carriers offer cost-threshold notifications. Set one at $50/day if you normally spend $5.
Should port 5060 be public at all?
If all your phones are at known sites and you have a static office IP, restrict SIP to those sources only at the firewall. Then no scanner can reach Asterisk in the first place.
If you have remote workers or BYOD phones, port 5060 has to be public — fall back on the layered controls above.
The non-standard port myth
Moving SIP off port 5060 (to 5160 or wherever) buys you a few days of obscurity, then scanners catch up. Don't rely on this as your primary control. The Responsive Firewall + fail2ban + strong passwords is the actual defense; non-standard ports are at most a noise reduction.
Quick audit checklist
- All extension passwords ≥ 16 chars, random, unique.
- Responsive Firewall enabled with trusted networks populated.
- fail2ban active with bantime ≥ 24 hours.
- Outbound route max-call limits set.
- International dialing locked or restricted.
- Carrier cost alert set at a reasonable threshold.
- You're monitoring failed-registration counts.
Also Read
Powered by WHMCompleteSolution