Filtrage pour asterisk / debian

Mettre fin aux sollicitations vers un serveur sip ouvert sur le WAN est une préoccupation. Il faut pouvoir garantir une utilisation privée.
Et puis non, désolé, je n’ai que le moins possible de temps machine à allouer aux botnets.
Fail2ban ne donnant plus satisfaction sur le sujet depuis la version 1.8 d’asterisk, une alternative doit être trouvée.
Le protocole SIP prévoit que les échanges soient pourvus d’un champ user-agent de taille variable.
Les botnets ont des user-agent reconnaissables (sipcli, friendly-scanner, sipvicious...) ou random.
Toutefois, dans le cas où on connaît les clients qui ont autorité pour établir une session, il est possible au niveau réseau de filtrer leur user-agent.

Voici un paquet SIP à titre d’exemple, son user-agent est ’friendly-scanner’, ce ’scanneur amical’ dénote une envie de mapper le dialplan ou de récolter les options proposées par le serveur, ne correspondant en rien à quoique ce soit d’amical :

OPTIONS sip:100@<l'ip_publique d'asterisk> SIP/2.0
Via: SIP/2.0/UDP 127.0.0.1:5137;branch=z9hG4bK-4071317194;rport
Content-Length: 0
From: "sipvicious"<sip:100@1.1.1.1>; tag=35326566653838663133633401383133363938393132
Accept: application/sdp
User-Agent: friendly-scanner
To: "sipvicious"<sip:100@1.1.1.1>
Contact: sip:100@127.0.0.1:5137
CSeq: 1 OPTIONS
Call-ID: 858906445237543922877123
Max-Forwards: 70

Un autre paquet non souhaité, avec un autre style de user-agent :

Via: SIP/2.0/UDP 209.251.103.236;branch=z9hG4bKjg9W1gC39Eoc5e;rport
From: "123456789" <sip:123456789@209.251.103.236>;tag=hY5Ak8YfYC0R
To: <sip:24189525@82.239.xxx.yyy>
Contact: <sip:123456789@209.251.103.236>
CSeq: 101 INVITE
Call-Id: Wxv_TpLnHThsF7D3_1XLOc32VgayIe2QOc3lkgaqPzywOc32Vg
User-Agent: dy6NAcSVXDMc0HH
Max-Forwards: 70
Allow: INVITE, ACK, CANCEL, BYE
Content-Type: application/sdp
Content-Length: 497

En observant le trafic, on voit que la plupart des botnets incrémentent leur port source de 1 à chaque connexion en partant du port UDP 5060, en comparaison, un client SIP ’en règle’ avec ses identifiants n’aura pas ce comportement.

Quelques règles simples de filtrage permettent de laisser vaines une grande partie de ces tentatives.

Attention : ces règles ne sauraient être un palliatif exhaustif à tous les types de sollicitations indésirables vers un serveur SIP, et cela ne ressemble en rien à ce qu’on appelle une ’bonne pratique’ !

Voici une stratégie qui correspond à mon attente,

- On dirige le trafic à destination du port UDP 5060 vers une chaîne utilisateur qu’on créée avant :

# iptables -N ASTERISK
# iptables -A INPUT -p udp -m udp --dport 5060 -j ASTERISK

- Une fois dans la chaîne, on peut traiter les user-agents, accepter ceux qu’on attend :

# iptables -A ASTERISK -m string --string "chaîne_de_caractères_contenue_dans_le_user-agent" --algo bm -j ACCEPT

Il est possible de répéter cette règle pour plusieurs user-agents. Cette règle en l’état inspecte tout le paquet SIP, ce qui peut demander relativement beaucoup de temps à traiter sur un serveur avec plusieurs dizaines de clients.
Les options d’iptables —to et —from permettent de positionner un offset de bits ce qui permet justement d’alléger la tâche, netfilter ayant moins de bits à lire et à comparer.
Ceci ouvre une problématique, mais autant de solutions, sachant qu’un logiciel softphone permet souvent de modifier son user-agent.

- On abandonne le trafic qui arrive en bout de chaîne mais on garde un œil dessus avec ULOG :

- Il faut installer la cible ULOG, car non présente par défaut, et la configurer :

# apt-get install ulogd2 ulogd2-pcap

# vi /etc/ulogd.conf

- Pour utiliser ULOG dans netfilter, il faut décommenter la ligne correspondant à son plugin.

plugin="/usr/lib/ulogd/ulogd_PCAP.so"

- Dans la section [PCAP], on peut spécifier où on veut enregistrer un fichier de sortie au format pcap, autre part que dans /var/log par exemple, ou un doublon. Pour ma part, c’est sur un dossier monté sur le réseau, je peux donc ouvrir le fichier produit avec cablerequin pour une lecture aisée.

file="/point_de_montage/dossier/fichier.pcap"
# file="/var/log/ulog/pcap.log"
sync=1

- On peut quitter et enregistrer quand les changements voulus ont été apportés.

:wq

- Redémarrer ulogd

# service ulogd2 restart

- Insérer en dernier la règle qui va permettre de logguer le trafic non désiré avant de l’abandonner

# iptables -A ASTERISK -j ULOG
# iptables -A ASTERISK -j DROP

- Ne pas oublier une plage de ports RTP, ceux par lesquels les flux audio vont transiter.

# iptables -A INPUT -p udp -m udp --dport 36384:36640 -j ACCEPT

- Il faut veiller à ce que cela corresponde avec la plage de ports que le serveur utilise, pour vérifier, il faut éditer dans le dossier asterisk le fichier rtp.conf.

# vi /etc/asterisk/rtp.conf

- On établit une plage cohérente avec le filtrage envisagé :

rtpstart=36384
rtpend=36640

- Vérifier les règles, avec les colonnes de chiffres à gauche qui indiquent le nombre de paquets passés dans telle ou telle règle.

# iptables -nvL --line-numbers

Pour aider au diagnostic, il est possible de remettre à zéro les compteurs de paquets :

# iptables -Z

ou bien pour une seule règle :

# iptables -Z ASTERISK 1

ce qui aura pour effet de remettre à zéro la première ligne de la chaine ’ASTERISK’.