Sobald unser Asterisk-PBX-Server online ist, egal ob mit einer direkten öffentlichen IP-Adresse oder über NAT hinter einer Firewall, beginnen innerhalb von Minuten automatisierte Botnetze, den Port 5060 aggressiv zu scannen, Passwörter zu erraten und nach einer Schwachstelle zu suchen. Im Jahr 2026 sind VoIP-Bedrohungen vollständig automatisiert, was bedeutet, dass unsere Verteidigung ebenfalls automatisiert werden muss.
Das optimale Tool unter Linux hierfür ist Fail2Ban, das über Filterregeln, die entsprechenden Log-Files nach auffälligen Mustern abscannt und so verdächtige IP-Adressen blockieren kann. Angenommen, ein Angreifer versucht, sich über den SSH-Port Zugriff zu dem Server zu verschaffen, so kann man definieren, dass nach 5 oder mehr Versuchen, die angreifende IP-Adresse für eine gewisse Zeit oder sogar dauerhaft über die Firewall blockiert wird.
Soweit zu der Grundfunktion und -Idee von Fail2Ban.
Da in unserem Fall der Asterisk-Server nicht frei im Internet sondern hinter einer OpenWRT-Firewall steht, nutzt die Fail2Ban-Absicherung auf dem Raspberry-Pi mit Asterisk definitiv nichts. Denn Anfragen auf Port 5060 sieht der Asterisk-Server stets mit der Router-IP-Adresse auf der auch die OpenWRT-Firewall sitzt. In diesem Fall ist das die IP 192.168.0.1. Eine Fail2Ban-regel für die SIP-Angriffe würde also lediglich die IP 192.168.0.1 blockieren und die Telefonie würde sofort zusammenbrechen. Das ist nicht das Ziel. Der hinter der Firewall stehende Asterisk-Server wird nie die realen IP-Adressen der Angreifer sehen können. Das geht nur auf der OpenWRT-Firewall selber.
Ziel ist die Absicherung eines Asterisk-Servers hinter einem OpenWrt-Router mit OpenWrt 23.05 und Firewall4 (fw4/nftables). Die Provider-IP muss von Sperren ausgenommen bleiben. Das gewünschte Ergebnis ist eine automatische Sperre externer SIP-Quellen, die nicht zur Provider-Ausnahme gehören. Fail2Ban übernimmt die dynamische Sperrung erkannter Quell-IP-Adressen. Eine vollständige Whitelist, die sämtliche anderen Quellen bereits vor dem ersten Paket blockiert, ist davon zu unterscheiden und wird durch eine zusätzliche statische Firewall-Regel umgesetzt.
Hier besteht die Herausforderung, zu erkennen, welche der vielen IP-Adressen im Kernel-Log veranwortlich sind, die die unauthorisierten SIP-Anfragen verursachen. Zur Erinnerung, Fail2Ban durchsucht die Logfiles, in unserem Fall wäre das logischerwiese /var/log/asterisk.log. Diese Datei liegt aber auf dem Asterisk-Server, hier dem Raspberry Pi, und somit für die Firewall nicht direkt erreichbar.
Da OpenWRT generell die Logs im Kernel-Log führt und wenn überhaupt nur /var/log nur im RAM liegt, müssen wir eine durchsuchbare Log-Datei anlegen, die Fail2Ban nutzen kann.
Für die Erkennung eingehender SIP-Pakete wurde die nftables-Konfiguration unter /etc/nftables.d/sip-wan-log.nft verwendet.
chain sip_wan_log {
type filter hook prerouting priority filter; policy accept;
iifname "pppoe-wan" meta l4proto { tcp, udp } th dport 5060 limit rate 20/second counter log prefix "SIP-WAN-IN " flags all
}
Das Präfix SIP-WAN-IN kennzeichnet dabei die passendem Pakete im Kernel-Log.
Damit die Kernel-Warnmeldungen in /var/log/firewall.log geschrieben werden können, muss rsyslog so konfiguriert werden.
~# uci add rsyslog selector
~# uci set rsyslog.@selector[-1].source='kern.warn'
~# uci set rsyslog.@selector[-1].destination='/var/log/firewall.log'
~# uci commit rsyslog
~# /etc/init.d/rsyslog restart
Für OpenWRT existiert auch ein Package für Fail2Ban, das sich leicht in der Busibox von OpenWRT installieren lässt.
~# opkg update
~# opkg install fail2ban
Jetzt werden noch die IP-Adressen des VoIP-Provider (in diesem Fall Telekom GmbH) zum Ausschluss benötigt. Dazu stellen wir eine DIG-Anfrage über den Service und das Protokoll:
~# dig SRV _sip._udp.tel.t-online.de
; <<>> DiG 9.20.23-1~deb13u1-Debian <<>> SRV _sip._udp.tel.t-online.de
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 22742
;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;_sip._udp.tel.t-online.de. IN SRV
;; ANSWER SECTION:
_sip._udp.tel.t-online.de. 1975 IN SRV 30 0 5060 hno002-f01-mav-pc-ra-001.edns.t-ipnet.de.
_sip._udp.tel.t-online.de. 1975 IN SRV 10 0 5060 stg010-l01-mav-pc-rb-001.edns.t-ipnet.de.
_sip._udp.tel.t-online.de. 1975 IN SRV 20 0 5060 nes008-f01-mav-pc-ra-001.edns.t-ipnet.de.
;; Query time: 0 msec
Daraus lassen jetzt die IP-Adressen auflösen:
~# dig +short A stg010-l01-mav-pc-rb-001.edns.t-ipnet.de
~# dig +short A nes008-f01-mav-pc-ra-001.edns.t-ipnet.de
~# dig +short A hno002-f01-mav-pc-ra-001.edns.t-ipnet.de
217.0.146.198
217.0.147.5
217.0.147.197
Damit haben wir alles, um die Fail2Ban-Regel zu bauen.
Diese Filterdatei /etc/fail2ban/filter.d/sip-wan.conf erkennt die protokollierten SIP-Pakete anhand der Quell-IP und des Zielports 5060:
[Definition]
failregex = ^.*SIP-WAN-IN .*SRC=<HOST> .*DPT=5060(?:\s|$)
ignoreregex =
Dabei verwendet der Filter <HOST> als Platzhalter für die IP-Adresse, die Fail2Ban bei einem Treffer sperren kann.
Unter /etc/fail2ban/jail.d/sip-wan.local wird diese Konfiguration angelegt:
[sip-wan]
enabled = true
filter = sip-wan
logpath = /var/log/firewall.log
backend = polling
port = 5060
protocol = udp
ignoreip = 127.0.0.1/8 ::1 217.0.146.198
maxretry = 604800
findtime = 600
bantime =
action = nftables-multiport[name=sip-wan, port=5060, protocol=udp, chain_hook=forward, chain_priority=-1]
Als Dauer der Sperre haben wir eine Woche (604800) gewählt, dauerhaft wäre “-1”. Dann müsste man jedoch regelmässig IP-Adressen manuell entsperren, da sonst der Speicher irgendwann volllaufen könnte.
~# fail2ban-client status
Status
|- Number of jail: 1
`- Jail list: sip-wan
list table inet f2b-table
Um die Aktion gezielt zu testen, wird eine reservierte Dokumentationsadresse vorübergehend gesperrt:
~# fail2ban-client set sip-wan banip 192.0.2.123
~# nft list tables
table inet fw4
table inet f2b-table
Die Test-IP wird danach wieder freigegeben:
~# fail2ban-client set sip-wan unbanip 192.0.2.123
~# nft list table inet f2b-table
liefert diese Ausgabe
table inet f2b-table {
set addr-set-sip-wan {
type ipv4_addr
elements = { 172.110.223.179 }
}
chain f2b-chain {
type filter hook forward priority filter - 1; policy accept;
udp dport 5060 ip saddr @addr-set-sip-wan reject with icmp port-unreachable
}
}
Folgende Abfrage bestätigt die aktive Jail:
~# fail2ban-client status sip-wan
Status for the jail: sip-wan
|- Filter
| |- Currently failed: 0
| |- Total failed: 1
| `- File list: /var/log/firewall.log
`- Actions
|- Currently banned: 1
|- Total banned: 2
`- Banned IP list: 172.110.223.179
Die Provider-Ausnahme wird ebenfalls geprüft:
~# fail2ban-client get sip-wan ignoreip
These IP addresses/networks are ignored:
|- 127.0.0.0/8
|- 217.0.146.198
~# fail2ban-client status sip-wan
Status for the jail: sip-wan
|- Filter
| |- Currently failed: 0
| |- Total failed: 1
| `- File list: /var/log/firewall.log
`- Actions
|- Currently banned: 1
|- Total banned: 2
`- Banned IP list: 172.110.223.179
oder nur die Liste der gesperrten IPs
~# fail2ban-client status sip-wan | grep 'Banned IP list'
`- Banned IP list: 172.110.223.179
Damit existiert ein wirkungsvoller Abwehrmechanismus bereits auf einer OpenWRT-Firewall, um die dahinterliegenden Asterisk-Telefonanlage vor SIP-Angriffen zu schützen. Auf eine ähnliche Art und Weise ohne die Firewallregeln lässt sich auch eine Fail2Ban-Regel anlegen, wenn der Asterisk-Server eine öffentliche IP-Adresse hat. Zusätzlich läuft das Asterisk-Log “full” nicht so schnell voll, wie wenn pro Minute Dutzende SIP-Registrierungsversuche protokolliert werden müssen.