Sur un trunk SIP, la sécurité n'est pas une option de déploiement, c'est une responsabilité contractuelle
Toll fraud, STIR/SHAKEN, mTLS, durcissement du SBC. Ce qui protège un trunk SIP en 2026, couche par couche, avec les configurations et la checklist.
La fraude télécom a représenté 38,95 milliards de dollars de pertes en 2023 selon la CFCA, soit 2,5% des revenus du secteur. En 2026, les attaques sur les infrastructures voix restent un risque d'exploitation : DDoS ciblés sur les registrars, brute-force sur les credentials SIP, exploitation des failles de configuration des SBC. Pour un intégrateur qui déploie de la voix chez ses clients, ça ne se traite plus en option, ça s'écrit dans le contrat.
Voici les mesures, couche par couche, de la terminaison transport jusqu'au monitoring.
Trois vecteurs, et le premier se découvre sur la facture
Le toll fraud est le plus coûteux. Un attaquant compromet un compte SIP ou exploite un trunk mal fermé pour router des appels internationaux premium, et le client découvre le problème sur sa facture mensuelle, souvent plusieurs milliers d'euros trop tard.
Le registration hijacking vise la redirection. L'attaquant intercepte ou forge des requêtes REGISTER pour renvoyer les appels entrants vers ses propres endpoints, et sans authentification mutuelle un simple sniff du réseau suffit.
Le DDoS SIP, enfin, sature. Des volumes massifs de requêtes INVITE ou OPTIONS noient le SBC ou le proxy, et les mitigations classiques du web (CDN, WAF) ne protègent pas le trafic SIP en UDP.
En 2026, un trunk SIP en UDP clair est une faute professionnelle
Le chiffrement du transport est la première ligne.
# Rejoué : kamailio -c -f, version 5.7.4, sortie « config file ok ».
# enable_tls vient AVANT le chargement du module : dans l'autre ordre, tls.so
# se charge en annonçant que TLS est désactivé. Sans les deux, le socket tls:
# est refusé au démarrage et la config ci-dessous ne fait rien.
enable_tls=1
loadmodule "tls.so"
listen=tls:203.0.113.20:5061 # l'interface de signalisation, pas 0.0.0.0
modparam("tls", "tls_method", "TLSv1.2+")
modparam("tls", "verify_certificate", 1)
modparam("tls", "require_certificate", 1)
modparam("tls", "private_key", "/etc/kamailio/tls/server.key")
modparam("tls", "certificate", "/etc/kamailio/tls/server.crt")
modparam("tls", "ca_list", "/etc/kamailio/tls/ca.pem")
Le paramètre s'appelle tls_method, pas method. La version intuitive existe dans beaucoup d'exemples qui circulent, et Kamailio la refuse au démarrage : parameter <method> ... not found in module <tls>, sortie 255. Une config de trunk qui ne démarre pas se remarque tout de suite. C'est la version qui démarre en laissant une faille ouverte qui coûte cher, et c'est pour ça que les trois points suivants comptent.
TLS 1.2 au minimum, parce que 1.0 et 1.1 sont obsolètes et vulnérables. Ça, tout le monde le fait.
Le mTLS est le niveau le plus haut disponible sur un trunk, et c'est là que la plupart s'arrêtent trop tôt. Un TLS simple n'authentifie que le serveur : ton SBC prouve son identité, le pair ne prouve rien. require_certificate à 1 renverse la situation et exige que le client présente aussi son certificat. La différence est nette : sans mTLS, n'importe qui peut monter une session TLS vers ton SBC et attaquer la couche au-dessus en étant chiffré, donc invisible pour une inspection réseau.
Avec une réserve qui annule tout le bénéfice si on la rate. verify_certificate valide la chaîne contre le ca_list, il ne vérifie pas que le certificat présenté est celui du pair attendu. Pointe ce ca_list sur un bundle d'autorités publiques et n'importe quel certificat valide du monde franchit la poignée de main, pendant que tu crois avoir authentifié ton opérateur. Le ca_list d'un trunk est une CA privée dédiée, avec un certificat par pair. Le contrôle d'identité, lui, se fait au-dessus, par IP ACL ou par correspondance sur le sujet du certificat.
Et SRTP pour le media, parce que TLS protège la signalisation pendant que les flux RTP circulent sur un canal séparé.
# Illustratif : pas rejoué sur un SBC. Les noms de paramètres AudioCodes
# changent entre versions majeures, alors relis-les dans la doc de la tienne.
SRTPMode: RequireSRTP
SRTPOfferedSuites: AES_CM_128_HMAC_SHA1_80
DTLSMode: Enabled
L'authentification digest ne suffit pas
Les credentials faibles ou laissés par défaut restent le premier vecteur. Ma règle sur les missions : 32 caractères minimum, générés automatiquement et jamais choisis à la main, avec une rotation trimestrielle automatisée via l'API du provider ou le script de provisioning. La longueur compte moins que la génération : un mot de passe choisi par un humain reste devinable à 32 caractères.
L'IP ACL vient en complément, parce que le digest seul laisse passer qui connaît le secret.
# Rejoué : les six règles s'insèrent, dans cet ordre, sur iptables 1.8.
# N'autoriser que le TLS, depuis les pairs connus. Le 5060 en clair est fermé
# sur les deux transports. Oublier tcp/5060, sur lequel Kamailio écoute par
# défaut, laisse une ACL qu'on contourne en changeant simplement de transport.
iptables -A INPUT -p tcp --dport 5061 -s 203.0.113.10 -j ACCEPT
iptables -A INPUT -p udp --dport 5060 -j DROP
iptables -A INPUT -p tcp --dport 5060 -j DROP
iptables -A INPUT -p tcp --dport 5061 -j DROP
# Le plan media, à aligner sur la plage RTP réellement configurée sur le SBC.
iptables -A INPUT -p udp --dport 10000:20000 -s 203.0.113.10 -j ACCEPT
iptables -A INPUT -p udp --dport 10000:20000 -j DROP
Trois réserves sur cet exemple. -A ajoute en fin de chaîne, donc sur un hôte qui porte déjà un REJECT catch-all (firewalld, une politique RHEL par défaut) les lignes ajoutées ici peuvent ne jamais être atteintes, y compris les ACCEPT, ce qui coupe le trunk au lieu de le protéger : vérifie la chaîne réelle avec iptables -L INPUT -n --line-numbers plutôt que de faire confiance à l'ordre d'écriture. Rien n'est persisté, donc ce contrôle disparaît au reboot si tu ne le ranges pas dans ton outil de configuration. Et chaque règle a besoin de son jumeau ip6tables : une ACL IPv4 seule se contourne exactement comme le tcp/5060 oublié si le SBC écoute aussi en v6.
Rate limiting sur le SBC
C'est la mesure la plus efficace contre le brute-force et les scans. Un SBC correctement réglé limite le nombre de requêtes par source et par seconde.
# Rejoué : kamailio -c -f, version 5.7.4, sortie « config file ok ».
# xlog.so est chargé explicitement : sans lui le bloc échoue au démarrage sur
# « failed to find command xlog », alors que la règle de limitation, elle, est
# correcte. Un module manquant ne se signale qu'au redémarrage suivant.
loadmodule "pike.so"
loadmodule "xlog.so"
modparam("pike", "sampling_time_unit", 2)
modparam("pike", "reqs_density_per_unit", 30)
modparam("pike", "remove_latency", 4)
route[REQINIT] {
if (!pike_check_req()) {
xlog("L_WARN", "Blocked SIP flood from $si\n");
exit;
}
}
Avec ces valeurs, une source qui envoie plus de 30 requêtes par tranche de 2 secondes est bloquée pendant 4 secondes. Ajuste les seuils au volume légitime de ton infrastructure, sinon tu bloqueras ton propre trafic aux heures de pointe.
STIR/SHAKEN n'est pas ton chantier, c'est celui de l'opérateur
Il faut le dire clairement parce que beaucoup de contenus le présentent comme une tâche d'intégrateur. STIR/SHAKEN signe cryptographiquement l'identité de l'appelant pour limiter l'usurpation de numéro, et ce sont les opérateurs qui portent les certificats, la signature et l'obligation réglementaire. Obligatoire aux États-Unis pour les fournisseurs de voix concernés, il se traite en Europe comme un standard à connaître dans les architectures transfrontalières, pas comme une obligation uniforme.
Ce qui te concerne tient en deux lignes. Sur les appels entrants, le niveau d'attestation transmis par l'opérateur dit ce qu'il a réellement vérifié : en A l'identité de l'appelant et son droit d'usage du numéro, en B l'identité seule, en C rien d'autre que le fait que l'appel vient d'une passerelle. C'est une information à exploiter dans le routage, pas une brique à déployer. Et le corollaire commercial : ne le vends pas comme un livrable, tu ne le contrôles pas.
Durcir le SBC : la checklist
Le SBC est le point de terminaison exposé sur Internet, donc c'est là que le durcissement se paie.
| Mesure | Priorité | Impact |
|---|---|---|
| Désactiver les protocoles non utilisés (H.323, MGCP) | Haute | Réduit la surface d'attaque |
| Limiter les codecs autorisés | Moyenne | Empêche l'exploitation via codecs exotiques |
| Activer la détection d'anomalies SIP | Haute | Bloque les requêtes malformées |
| Journaliser toutes les tentatives d'authentification | Haute | Détection des scans et brute-force |
| Séparer les interfaces management et media | Haute | Empêche l'accès admin depuis Internet |
| Mettre à jour le firmware régulièrement | Haute | Corrige les CVE connues |
| Configurer des alarmes sur le taux d'échec INVITE | Moyenne | Détection précoce de fraude |
| Restreindre les destinations internationales | Haute | Limite l'impact du toll fraud |
La mesure qui paie le plus vite : bloquer les préfixes inutilisés
Contre le toll fraud, c'est ce qui produit un effet immédiat. Et c'est aussi l'endroit où les exemples qui circulent se trompent de table.
Sur un AudioCodes, le blocage d'une destination se pose dans la table de routage IP-to-IP, avec la règle placée avant les règles de routage normales. IPOutboundManipulation ne sait pas rejeter un appel : elle réécrit des numéros, elle ne décide pas de leur sort. J'ai vu passer plus d'un snippet qui lui attribue un champ Action: Reject, lequel n'existe pas. Ce genre de configuration s'importe sans erreur visible et ne bloque rien.
Le contenu de la liste mérite la même attention que sa syntaxe. Un préfixe non attribué dans le plan E.164 ne route nulle part, donc le bloquer ne protège de rien. Et un indicatif pays n'est pas une tarification : 976 est la Mongolie, un pays entier, pas un service surtaxé. Ce que tu bloques utilement, ce sont les vraies plages à revenu partagé, comme le 1900 nord-américain ou le 899 français, plus les destinations que le client n'appelle jamais et dont le tarif de terminaison est élevé. Cette seconde liste se tire de son historique d'appels, pas d'un article.
L'analyse CDR en direct, et la coupure avant la facture
C'est la mesure qui rattrape tout ce que la prévention a laissé passer, et c'est celle que je mets en place en premier après le durcissement.
Une précision d'abord, parce qu'elle change la façon de lire ce qui suit : ce mécanisme est conçu et documenté, il n'a pas encore coupé de trafic en production. Ce que tu lis est une conception, pas un retour d'expérience.
Le principe tient en une fenêtre glissante d'une heure. Les CDR sont analysés au fil de l'eau, pas en fin de mois, et la règle qui déclenche n'est pas le volume brut mais le volume vers une destination inhabituelle pour ce client. Un client qui appelle le Maghreb tous les jours n'a rien d'anormal à y passer trente appels dans l'heure. Le même volume vers une destination qui n'apparaît nulle part dans son historique est une fraude en cours, pas une hypothèse.
Ce qui suit la détection est la vraie décision : la coupure est préventive, et le client final est prévenu. Couper d'abord, expliquer ensuite. C'est inconfortable, parce que tu interromps du trafic sur la foi d'un motif statistique, et tu auras des faux positifs. Mais l'alternative se chiffre : une nuit de toll fraud non interrompue coûte plus cher que la demi-journée d'explication qui suit une coupure injustifiée.
Ce qu'on ne coupe jamais, et il faut l'écrire avant de coder quoi que ce soit. La coupure porte sur la classe de destination suspecte, comme le blocage de préfixes décrit plus haut, jamais sur le trunk entier et jamais sur le poste appelant.
Les numéros d'urgence sont exemptés nommément, par une règle d'autorisation placée au-dessus de la règle anti-fraude. Nommément, parce que compter sur le fait que la règle de blocage ne les matchera pas est un pari, alors qu'une autorisation explicite se vérifie.
Avec deux réserves, et la première m'a coûté du temps. Que la règle placée au-dessus l'emporte réellement dépend de la famille de SBC : l'ordre d'évaluation des tables n'est pas le même partout, et certaines plateformes appliquent une manipulation avant une décision de routage. Teste l'exemption sur ta plateforme, avec un appel réel vers un numéro d'urgence pendant que la règle anti-fraude est armée. Ne la déduis pas de la position de la ligne dans le tableau.
La seconde réserve est la liste elle-même, qui dépend du pays. Chaque plan de numérotation national a la sienne, et un client multi-pays en a autant que d'implantations. Pour la France, l'Arcep en fait une liste opposable de douze numéros acheminés gratuitement : 112, 15, 17, 18, 114, 115, 119, 116000, 116117, 191, 196, 197. Les six premiers sont ceux auxquels tout le monde pense. Le 119 pour l'enfance en danger, le 196 pour l'urgence maritime et le 197 pour l'alerte attentat n'y pensent pas moins, et pour un client scolaire ou côtier ils ne sont pas optionnels. Un automate anti-fraude qui prive un client de l'un d'eux ne pose pas un problème de SLA, il pose un problème de sécurité des personnes.
Trois conditions vont avec, et elles se règlent dans le contrat, pas dans le code. L'alerte part au client en même temps que la coupure, jamais après : une coupure silencieuse détruit la confiance bien plus sûrement que la fraude. Le mandat de couper est écrit noir sur blanc, parce qu'interrompre la production d'un client sans clause opposable est une faute contractuelle même quand la détection est juste. Et le chemin de remise en service est défini, avec une astreinte joignable, sinon le faux positif de vendredi soir dure jusqu'à lundi.
Reste le démarrage à froid. Un nouveau client n'a pas d'historique, donc toutes ses destinations sont inhabituelles et les premières semaines ne produisent que du faux positif. Il faut une période d'apprentissage pendant laquelle la règle alerte sans couper.
Deux axes complètent le dispositif. Fail2ban bloque automatiquement les IP après N échecs d'authentification. Et un syslog centralisé agrège les logs de tous les SBC et proxys sur une plateforme unique, Grafana et Loki ou ELK.
# Illustratif : pas rejoué. Le filtre `kamailio-auth` référencé ici est à
# écrire, fail2ban n'en fournit pas pour Kamailio.
[kamailio-auth]
enabled = true
filter = kamailio-auth
action = iptables-allports[name=kamailio, protocol=all]
logpath = /var/log/kamailio/kamailio.log
maxretry = 5
bantime = 3600
findtime = 300
Ce que ça change commercialement
Aucune de ces mesures ne suffit seule, et c'est le point : le chiffrement du transport, l'authentification forte, la conformité réglementaire selon les pays et les routes, le durcissement du SBC et le monitoring se tiennent les uns les autres.
Un client qui subit une fraude SIP ne renouvelle pas son contrat. Un client dont l'infrastructure est auditée, durcie et surveillée en parle autour de lui.
Un trunk SIP à durcir ou à auditer, côté intégrateur, opérateur ou équipe B2B ? Prendre contact.
Sources
- CFCA, "Telecommunications fraud increased 12% in 2023 equating to an estimated $38.95 billion lost to fraud". Vérifié le 2026-08-04 : la page résout, le titre correspond, et elle situe la perte à 2,5% des revenus télécom.
- eCFR, 47 CFR § 64.6301, Caller ID authentication, pour le cadre réglementaire américain STIR/SHAKEN.
- Arcep, décision n° 2022-2372 modifiant la décision n° 02-1179, pour la liste des numéros d'urgence acheminés gratuitement en France.
- Les blocs marqués « rejoué » ont été passés à
kamailio -c -fen 5.7.4 et àiptables1.8, dans un conteneur Ubuntu 24.04. Ceux marqués « illustratif » ne l'ont pas été, faute d'équipement, et le disent à l'endroit où tu les copierais.
Note terrain par qaryon
Nicolas Marxer
Architecte solutions en communications d'entreprise, spécialisé dans les déploiements opérateur, intégrateur et B2B.
Besoin d'un avis terrain sur votre architecture de communication ?
Audit, cadrage ou déploiement : j'interviens directement sur UCaaS, CCaaS, IPBX, SBC, automatisation et IA appliquée.
Discuter d'un projet télécomÀ lire aussi
Isoler un datacenter VoIP en journée, sans couper un appel
Intervenir sur un datacenter en journée sans couper un client. Le drain passe par le DNS, pas par le SBC : on retire l'IP, on laisse les sessions finir, on remet en miroir. Le vrai piège, c'est le TTL.
En SIP, ce qui est négocié n'est pas ce qui est supporté
Trois trunks qui refusaient de passer un appel entre deux vendeurs. À chaque fois, un pair qui signale une chose et en fait une autre. Le SBC absorbe, la trace tranche.
Je n'automatise pas la décision, j'automatise le fait qu'elle expire
Une CVE tombe sur un composant que tu exploites. La dépendance est corrigée en amont, mais l'éditeur n'a pas republié son image. Tu ne peux ni patcher, ni livrer, ni oublier. Ce qui se passe ensuite ne se délègue pas à un modèle, et c'est la meilleure explication que je connaisse de ce que l'IA ne sait pas faire.