Topologie:A = fr-par-1 cibleB = fr-par-2 ciblebascule carrier seulement pour les nouveaux appels

Chemin de signalisation

La cellule admet le carrier sur son interface publique, ancre le SDP localement et transmet à Asterisk sur loopback.

Pair carrier local

8.8.8.9:5061

INVITE mTLS hermétique; ce pair n’est pas un carrier réel.

Kamailio 6.0.7

8.8.8.8:5061

Admission publique, double Record-Route puis dialogue interne 5063.

RTPEngine 26.0.1.13

127.0.0.1:22222

SDP ancré sur 8.8.8.8, plage 10000-11000.

Asterisk 22.9.0

127.0.0.1:5062

TLS loopback exact puis cycle Stasis answer/hangup.

Admission fail-closed

Une identité valide sur une mauvaise interface reste refusée. Le DID est traduit vers un alias opaque généré, jamais vers une route arbitraire.

ContrôleDécisionÉchecPreuve
Transport / identitéTLS, certificat vérifié et CN carrier exact403mTLS local avec rôles/CA carrier et cellule séparés; pair sans certificat refusé
Intégrité SIPSanity, Max-Forwards et pike fixé à 12 requêtes par fenêtre de 2 s400, 483 ou 429Configuration seulement; seuil, CPS et bursts carrier non qualifiés
ServiceDID allowlisté vers alias Stasis404Service inconnu et tentative outbound refusés en lab
MéthodeProfil inbound explicitement borné405Code; interop carrier absente

Plans réseau et frontières de confiance

Input, output et forwarding sont fermés par défaut. Chaque autorisation associe interface, CIDR, protocole et port.

PlanFlux admisInterditsStatut
Public carrierSIP TLS 5061 depuis CIDR carrier5060, HTTP, TURN, SSHRègles lab; carrier absent
Edge privé8089 depuis contrôle NavyExposition InternetContrat IaC; réseau absent
ManagementSSH 22 via VPN/bastion, NTP 123Admin publique directeCible; VPN/BGP absent
Loopback celluleSIP TLS 127.0.0.1:5062, NG UDP 127.0.0.1:22222Accès inter-celluleSockets exacts exercés dans un namespace partagé local

Pare-feu et identité active

La santé lie la politique canonique, ses permissions, le fichier rendu et les règles nft effectivement chargées.

Quatre dérives

Identité vérifiée

Mode de configuration, SHA de la politique, SHA du fichier rendu et SHA de la table active sont testés séparément.

Pas de port ajouté

Santé hors chemin

Le timer local n’écoute sur aucun socket et sa panne ne coupe pas un appel. La readiness n’est consommée par aucun carrier.

Lab hermétique

Aucun port hôte

Kamailio, RTPEngine et Asterisk partagent le namespace réseau du lab; aucun port hôte, PSTN, cloud ou action externe n’est utilisé.

Profil SIP et dialogue

Le lab brut prouve un sous-ensemble précis du dialogue. Une route présente en code ne vaut toujours pas preuve pour les scénarios non exercés.

SurfaceComportement actuelLimite exacte
INVITE / ACKRoutes pour tout 1xx avec SDP et réponses finales; 1 re-INVITE offerless reçoit l’offre SDP 2xx puis une réponse SDP transformée dans ACK, avec compteur de succès. INITIAL_LATE_OFFER et REINVITE_LATE_OFFER vérifient ack-done avant toute mutation RTPEngine: un 2xx retransmis ne rouvre plus ack-answer.Un ACK late-offer sans SDP est relayé après journalisation; un échec de transformation RTPEngine interrompt le chemin. Les deux cas restent sans teardown contrôlé ni preuve d’alarme.
Réponses finalesProduction et lab chargent tmx.so. Les named onreply_route utilisent t_drop() pour une réponse finale invalide ou impossible à ancrer; le core drop n’arrêtait pas ces réponses finales.Comportement prouvé dans les labs runtime et SBC locaux, pas avec un carrier ou un UAS externe.
PRACK / RFC 3262La campagne isolée du 29 août 2026 observe 7 PRACK: 1 RAck mal formé refusé localement en 400; 2 RAck bien formés mais non corrélés relayés au UAS sans mutation RTPEngine côté proxy; 1 PRACK corrélé sans answer SDP relayé; 1 PRACK d’acquittement sans SDP; 1 answer-in-PRACK; 1 offer-in-PRACK avec answer SDP dans le 2xx. La retransmission 183 cesse après le PRACK corrélé.Les deux unmatched reçoivent un 200 Asterisk 22.9.0 vérifié sans corps SDP. Le SDP brut entrant peut néanmoins être accepté par l’UAS aval: contournement possible de l’ancrage RTPEngine côté aval. Le lab ne prouve jamais que l’UAS n’a pas muté son état. Le 200 au PRACK privé de l’answer attendue reste également un risque, pas un succès.
État offer/answerClé exacte Call-ID + orientation des tags + RSeq/CSeq, modes prack-answer / prack-offer, tombstone prack-done. Le late offer ACK est corrélé au CSeq puis devient ack-done idempotent. Pour l’appel initial, l’early offer sans answer est réinitialisée avant la final offer; tous les dialogues synthétiques drainent à zéro.Une seule orientation active est stockée, jamais une copie reverse. Le cleanup et le delete RTPEngine essaient explicitement les deux orientations From/To. Seules les réponses 101-199 sont corrélées, pas 100; forks runtime et plusieurs 1xx fiables séquentiels restent non exercés.
re-INVITE / UPDATE3 re-INVITE: late offer, hold, reprise; 1 UPDATE SDP et 1 refresh offerless avec 2xx sans SDP; réponses reliable/late-offer/hold/reprise/UPDATE validées sur v/o/c/m/crypto, IP 172.31.93.20, ports 16000-16099 et directions recvonly/sendrecvAucun reset équivalent n’est appliqué au re-INVITE, car il pourrait tuer l’ancien média. Aucun RTP post-renégociation; rejet, glare ou timeout ne prouvent pas sa conservation.
Hold / reprise1 hold sendonly puis 1 reprise sendrecv traversent Kamailioinactive, adresse nulle, changement codec/port et effet média non exercés
Session timerstimers=yes, Min-SE 90 s, expiration 1800 s; une requête RFC avec Session-Expires 30 et sans Min-SE invalide reçoit 422 + Min-SE 90, ACK même branche, puis le dialogue normal réussitRotation/refresher et expiration réelle de session non testées
CANCEL / échec / BYECANCEL inconnu = 481. L’appel exact-socket observe le double Record-Route 5063 / 5061; le BYE Asterisk repasse par Kamailio interne 8.8.8.8:5063 et revient sur la même connexion TLS carrierCourses CANCEL/183/200/BYE, retransmissions et double cleanup non prouvés
REFER / INFO / REGISTERHors profil inboundTransfert, DTMF INFO et enregistrement non acquis

HA et comportement de panne

A et B sont deux domaines de panne complets sans état d’appel partagé ni bascule interne cross-cell.

Nouveaux appels

Carrier décide

Le retrait de la cible en échec et l’envoi vers l’autre IP dépendent du carrier.

Appels actifs

Pas de migration

La perte d’une cellule peut couper ses sessions. Aucun drain ou transfert à chaud n’est prouvé.

RTPEngine absent

Fail-closed exercé

La perte simulée refuse un nouvel appel en lab; aucune route RTP centrale ne contourne la cellule.

Interopérabilité

À contractualiser

DNS/SRV, causes, codecs, DTMF, forks, suites de 1xx fiables, timers, SRTP et anti-fraude restent à qualifier avec le carrier.

Niveau de preuve

Les labs valident des comportements locaux ciblés. Le pair de test n’est ni un carrier réel, ni une preuve PSTN ou cloud.

Kamailio

Configuration et dialogue

Kamailio 6.0.7 accepte le rendu sous UID 1000 avec tmx.so. Les labs runtime et SBC passent avec t_drop(), tombstones ACK vérifiés avant média, 7 PRACK et sessions drainées à zéro.

Exact-socket local

Chemin image exercé

mTLS 8.8.8.9:5061 vers 8.8.8.8:5061, Asterisk TLS 127.0.0.1:5062, NG 127.0.0.1:22222, SDP ancré et cycle ARI Stasis complet.

IaC

Deux cellules décrites

OpenTofu teste une cible mockée, pas l’API Scaleway.

Couverture partielle

Limites maintenues

Le lab exact-socket ne prouve aucun RTP bidirectionnel sur ce même appel. Carrier/PSTN/cloud, forks, plusieurs 1xx fiables séquentiels, ancien média sur rejet/glare, reset sûr après re-INVITE, teardown ACK-SDP, timers réels, courses CANCEL/200/BYE et RTP après chaque renégociation restent non prouvés.