Aller au contenu principal

ADR-0173 : Plateforme de téléphonie Navin : Asterisk, Kamailio, LiveKit SIP, SeaweedFS, multi-tenant et HA

  • Statut : accepté
  • Date : 2026-11-03
  • Portée : catalogue du Navin Manager (navin-manager/catalog/services/asterisk.yaml, kamailio.yaml, rtpengine.yaml, livekit*.yaml), domaine téléphonie du Control Plane (services/control-plane/src/eai/domains/telephony), migrations sql/postgres/V202__telephony*.sql et suivantes, section « Téléphonie » du portail (portal/src)
  • Documents liés : ADR-0101 (politique de licences), ADR-0166 (haute disponibilité déclarée par service), ADR-0171 (installation durcie), docs/architecture/ADRs/ADR-0173-* (ce document), guides téléphonie (docs/fr/guides/telephony)

Contexte​

Le client demande une téléphonie d'entreprise commercialisable : PBX, proxy SIP, passerelle SIP vers LiveKit, agents vocaux IA, multi-tenant, haute disponibilité, interfaces Web, sans démonstration. Deux plateformes existent et gardent leur rôle : le Navin Manager et ses agents installent et exploitent l'infrastructure ; Navin Enterprise AI Platform configure et administre les usages. LiveKit Server est déjà au catalogue (méthodes binary et podman, mode distributed sur Redis) et le Control Plane signe des jetons de salle LiveKit pour la voix temps réel ; LiveKit SIP, LiveKit Egress, les workers d'agents, Asterisk, Kamailio et RTPengine n'existent pas.

Décision​

1. Deux plans, des interfaces explicites​

QuiPar quoiFait quoi
Navin Manageragents Navin sur les hôtesinstallation, versions, configuration système, ports, certificats, clusters, HA, sauvegardes, contrôles de santé, rollback
Navin EnterpriseAMI et ARI d'Asterisk, JSONRPC de Kamailio, API Twirp de LiveKit, S3 de SeaweedFStenants, extensions, trunks, numéros, routage, IVR, files, agents, enregistrements, CDR, quotas
Navin EnterpriseAPI du Manager (domaine platform_manager existant)lecture de l'inventaire et de l'état des services ; toute opération d'infrastructure est demandée au Manager

Le Control Plane n'exécute aucune commande système. Le Manager ne gère ni extension, ni IVR, ni file, ni règle métier.

2. Services du catalogue du Manager​

ServiceComposantsMéthodesRôle
asteriskasterisk (pool)packagePBX : PJSIP, dialplan, files, messagerie vocale, ConfBridge, MixMonitor, ARI, AMI, CDR et CEL
kamailiokamailio (2 au moins en HA)packagebord SIP : TLS, WSS, NAT, anti-flood, anti-bruteforce, dispatcher vers Asterisk et LiveKit SIP
rtpenginertpenginepackageoptionnel : ancrage RTP, NAT difficile, interconnexion média ; jamais installé par défaut
livekitlivekit-serverbinary, podmanexistant, complété sans changer un déploiement qui fonctionne
livekit-siplivekit-sippodmanpasserelle SIP vers les salles LiveKit
livekit-egresslivekit-egresspodmanenregistrements LiveKit vers SeaweedFS
livekit-ingresslivekit-ingresspodmanoptionnel, inutile à la téléphonie (RTMP, WHIP)
livekit-agentslivekit-agents (workers)pythonexécution des agents vocaux IA de Navin

Valeurs par défaut des ports (le planificateur refuse un conflit sur un même hôte) :

ServicePortExposition
Kamailio5060 UDP et TCP, 5061 TLS (SIP) ; 7443 WSS (softphones)public (opérateurs, téléphones)
Kamailio5071 HTTP (JSONRPC et /metrics)réseau d'administration
Asterisk5070 UDP et TCP (SIP depuis Kamailio uniquement)réseau de signalisation interne
Asterisk8088 HTTP, 8089 HTTPS (ARI, /metrics) ; 5038 AMI, 5039 AMI TLSréseau d'administration
Asterisk10000 à 19999 UDP (RTP, SRTP, DTLS-SRTP)réseau média
LiveKit SIP5090 UDP et TCP (SIP) ; 20000 à 29999 UDP (RTP)interne et média
RTPengine2223 UDP (protocole ng) ; 30000 à 39999 UDPadministration et média
LiveKit Server7880 (signalisation), 50000 à 50100 UDP (existant)existant

AMI, ARI, JSONRPC et les ports de métriques ne sont jamais publics : ils écoutent sur l'adresse d'administration de l'hôte et le pare-feu du Manager ne les ouvre qu'aux sources déclarées.

3. Livraison de la configuration fonctionnelle​

  • Asterisk. Le Manager installe les fichiers système (asterisk.conf, modules.conf, pjsip.conf avec les transports, extensions.conf, queues.conf, voicemail.conf, confbridge.conf, manager.conf, ari.conf, http.conf, rtp.conf, prometheus.conf, cdr.conf, cel.conf) ; chacun inclut un fichier géré (#tryinclude pjsip_navin.conf, extensions_navin.conf, queues_navin.conf, voicemail_navin.conf, confbridge_navin.conf). Navin Enterprise compile ces fichiers gérés par pool PBX à partir des tenants, extensions, trunks, numéros, règles, IVR et files ; il les valide, les versionne (texte, empreinte SHA-256, auteur), les livre à chaque nœud du pool par AMI (CreateConfig, UpdateConfig), les active par AMI (pjsip reload, dialplan reload, queue reload all, voicemail reload, module reload app_confbridge.so), relit le résultat (GetConfig) et peut revenir à la version précédente. ARI sert au contrôle des appels (canaux, ponts, enregistrements, transferts) ; AMI sert aussi aux événements (CDR par cdr_manager, CEL par cel_manager, états des contacts et des files).
  • Nommage. Identifiant court du tenant tid = t suivi des 12 premiers caractères hexadécimaux de son UUID. Points de terminaison {tid}-{extension}, contextes {tid}-internal, {tid}-inbound, {tid}-outbound, {tid}-ivr-{flux}, files {tid}-{file}, accountcode = UUID du tenant, variable NAVIN_TENANT sur chaque canal. Aucun contexte d'un tenant ne référence un objet d'un autre tenant ; le compilateur le vérifie.
  • Kamailio. Le Manager écrit la liste du dispatcher à partir de la topologie (jeu 1 : pool Asterisk partagé, jeu 2 : LiveKit SIP, jeux 100 et suivants : pools dédiés). Navin Enterprise pousse le routage des tenants par JSONRPC dans les tables de hachage tenant_domains (domaine SIP vers tenant et jeu) et did_routes (numéro E.164 vers tenant, jeu et branche pbx ou ai), réconcilie à intervalle régulier et après chaque redémarrage de Kamailio (core.uptime), et pilote le drain des destinations (dispatcher.set_state). Les instances Kamailio répliquent ces tables par DMQ.
  • LiveKit SIP. Navin Enterprise crée par l'API LiveKit les trunks entrants et sortants et les règles de dispatch de chaque tenant (noms préfixés par tid, métadonnées tenant_id), lance les appels sortants des agents (CreateSIPParticipant) et les transferts vers une extension (TransferSIPParticipant, SIP REFER).
  • Deux branches distinctes. Branche PBX : Kamailio vers Asterisk. Branche IA directe : Kamailio vers LiveKit SIP (numéro routé ai). Branche IA par le PBX : Asterisk compose PJSIP/{agent}@livekit-sip depuis un IVR ou une file. Le transfert IA vers humain passe par un REFER vers Kamailio, qui route l'extension vers son Asterisk.
  • Corrélation. Asterisk pose l'en-tête X-Navin-Call-Id (UUID) ; LiveKit SIP le recopie en attribut de participant ; la session d'appel de Navin relie X-Navin-Call-Id, uniqueid et linkedid d'Asterisk, le Call-ID SIP, la salle et le participant LiveKit.

4. Données de Navin Enterprise​

Tables du schéma eai, toutes avec tenant_id, isolées par les mécanismes de tenancy existants du Control Plane : telephony_tenants (modèle shared ou dedicated, domaine SIP, pool, quotas, conservation), pbx_instances (pool partagé ou dédié, service du Manager, références de secrets AMI et ARI), sip_trunks, phone_numbers, extensions, routing_rules, ivr_flows et leurs versions, call_queues, queue_members, telephony_agents (humains), voice_agents (IA), telephony_config_versions (publications), call_sessions, call_events, call_recordings, voicemail_messages, telephony_quotas. Le journal d'audit existant du Control Plane est réutilisé, pas dupliqué. Mots de passe SIP, secrets de trunks, identifiants AMI et ARI : dans le coffre existant, jamais renvoyés par l'API (champs en écriture seule, has_secret).

5. Stockage SeaweedFS​

Un compartiment navin-telephony, clés opaques tenants/{tenant_uuid}/{catégorie}/{aaaa}/{mm}/{uuid}, catégories call-recordings, voicemail, ivr-prompts, conference-recordings, ai-voice-recordings, audio-exports. Les objets sont chiffrés par Navin Enterprise avant l'envoi. Lecture et téléchargement uniquement par Navin Enterprise : URL signées de quelques minutes, contrôle des droits, audit ; les identifiants S3 ne quittent jamais le serveur. Enregistrements Asterisk : MixMonitor écrit dans recording/navin/{tid}/ ; Navin Enterprise les récupère par ARI (GET /recordings/stored/{nom}/file), les chiffre, les dépose, puis les supprime par ARI. LiveKit Egress écrit dans le compartiment navin-livekit-egress avec des identifiants limités à ce compartiment ; à la fin d'un enregistrement (webhook signé), Navin Enterprise le range dans l'organisation des tenants.

6. Softphone WebRTC​

Le softphone du portail utilise JsSIP (MIT) en SIP sur WebSocket sécurisé vers Kamailio (WSS, path), qui relaie vers l'Asterisk du tenant ; média DTLS-SRTP avec ICE entre le navigateur et Asterisk (webrtc=yes). Le navigateur ne reçoit jamais le mot de passe SIP de l'extension : Navin Enterprise délivre des identifiants éphémères (module auth_ephemeral de Kamailio, HMAC avec un secret partagé gardé dans le coffre, une heure au plus) ; les points de terminaison WebRTC d'Asterisk n'acceptent que les adresses de Kamailio. Une salle LiveKit n'est pas une extension.

7. Multi-tenant​

Modèle shared : pool Asterisk partagé, isolation par contextes, domaines SIP, préfixes LiveKit, préfixes de stockage et autorisations. Modèle dedicated : pool Asterisk (et, au besoin, LiveKit SIP) dédié au tenant, jeu de dispatcher propre. Quotas par tenant : appels simultanés, appels par seconde (CPS, appliqués par Kamailio), destinations et pays autorisés, durée maximale, conservation des enregistrements.

8. Haute disponibilité : garanties par scénario​

PanneNouveaux appelsAppels en cours
Une instance Kamailioreprises par l'autre instance (DNS SRV, adresses multiples chez l'opérateur, ou répartiteur réseau)les dialogues routés par l'instance perdue échouent sur la requête suivante
Un nœud Asterisk du poolroutés vers les autres nœuds dès que la sonde OPTIONS du dispatcher le déclare hors serviceperdus : il n'y a pas d'état d'appel partagé entre nœuds Asterisk
Un nœud LiveKit SIP ou LiveKit Serverroutés vers les autres nœudsperdus pour les participants SIP de ce nœud
Un worker d'agent IApris par un autre workerla session de l'agent s'arrête ; la règle de secours route vers une file humaine
PostgreSQL, Redis, SeaweedFSmodes HA existants du catalogue (Patroni, Sentinel, réplication)selon le service

Une adresse IP virtuelle n'est pas une solution universelle ; aucune capacité ni survie d'appel n'est annoncée sans test.

9. Observabilité​

Métriques : res_prometheus d'Asterisk, xhttp_prom de Kamailio, ports Prometheus de LiveKit, LiveKit SIP et Egress, collectés par le Prometheus du catalogue ; journaux par Alloy ; alertes par Alertmanager ; indicateurs métier (appels, CPS, qualité, files, consommation) calculés par Navin Enterprise à partir des CDR, CEL et événements.

10. Licences​

Asterisk (GPL-2.0), Kamailio (GPL-2.0-or-later), RTPengine (GPL-3.0) et JsSIP (MIT) restent des composants séparés, utilisés par leurs interfaces réseau documentées ; aucun code GPL n'entre dans le code propriétaire de Navin. La redistribution des binaires GPL dans le bundle hors ligne s'accompagne des notices et des sources correspondantes.

Conséquences​

  • Le Manager gagne cinq services et des modèles de configuration ; Navin Enterprise gagne un domaine téléphonie, ses migrations, ses compilateurs et une section du portail.
  • Le Control Plane dépend de l'AMI, de l'ARI, du JSONRPC de Kamailio et de l'API LiveKit, joints par les liaisons du service navin-enterprise du catalogue.
  • Les tests de charge et les tests de panne multi-hôtes se font sur un environnement dédié avec SIPp ; aucun test n'est lancé vers un opérateur sans son accord.