La signalisation SIP et les NAT

Le problème ici est de pouvoir joindre, pour une communication de poste à poste, un ordinateur situé dans un réseau local, raccordé à internet par une passerelle hébergeant un routeur. L’idée est d’utiliser une NAT dynamique mise en œuvre par ce routeur, pour pouvoir, de l’extérieur, joindre un poste de travail "derrière" ce routeur, bien que l’adresse IP locale de cet ordinateur ne soit pas accessible de l’extérieur.
Par hypothèse, il s’agit bien ici d’utiliser une NAT dynamique et non pas une NAT statique (voir ce point le billet précédent).

Utiliser ainsi une NAT dynamique suppose plusieurs prérequis, le premier étant que … cette NAT doit exister dans la mémoire du routeur du destinataire. Or seules des connexions initiées de l’intérieur d’un réseau local créent de telles NAT. De sorte que, formulé ainsi, le problème d’une communication initiée de l’extérieur n’aurait pas de solution…
Car, d’une façon ou d’une autre, il faut, avant le début de la communication proprement dite :
- que pour chaque poste hébergé dans son réseau local "derrière" un routeur, et susceptible d’être appelé de l’extérieur, ce routeur ait déjà en mémoire une NAT dynamique qui pourra alors être utilisée pour joindre ce poste;
- que le détail de cette NAT dynamique soit communiqué au poste appelant, à l’extérieur, pour qu’il puisse ouvrir une telle communication.
De plus, chaque participant éventuel à une telle communication doit pouvoir, selon le type de cette communication envisagée, connaître diverses autres informations techniques nécessaires : par exemple, en téléphonie sur IP, les codecs utilisables.

Pour répondre à toutes ces nécessités – ainsi qu’à quelques autres, sortant du champ du présent billet -  on utilise ce qu’on appelle un système de signalisation.

Si on compare ce dont on a besoin pour débuter une communication de poste à poste, avec ce qu’il faut pour se connecter à un serveur public :
- un serveur public est connu par son "nom de domaine". Un poste d’utilisateur peut souvent être dans un réseau local (d’un particulier ou d’une très petite entreprise) ne disposant pas de nom de domaine. Et même si un tel petit réseau dispose d’un nom de domaine, on continue à ignorer, de l’extérieur, les noms des postes à joindre;
- de plus, c’est aussi parce que l’adresse IP publique correspondant à un nom de domaine n’est changée que très rarement qu’on peut la connaître par une requête auprès d’un serveur DNS. Par contre, les réseaux locaux de particuliers ou de très petites entreprises ont très souvent une adresse IP publique "dynamique", que le FAI peut changer à sa guise. Certes, utiliser les services d’un "DNS dynamique" est alors une solution pratique, mais qui est loin d’être universellement utilisée.
- enfin, un serveur public hébergé dans un réseau local bénéficie au minimum d’une NAT statique de son routeur, qui permet presque toujours des connexions externes sur le port usuellement utilisé pour un serveur de ce type (par exemple TCP 80 pour un serveur web). Or, si on utilise "à l’envers" des NAT dynamiques pour joindre des postes d’un réseau local, les ports externes de communications ne sont généralement plus des ports standards, et l’appelant extérieur doit en être informé.

Ces différences expliquent pourquoi on ne mentionne pas la nécessité de faire appel à un système de signalisation pour se connecter à un serveur.

 

L’exemple de la signalisation SIP

Il existe plusieurs systèmes de signalisation standardisés et largement utilisés, et on pourrait aussi en imaginer de nombreux autres. Par ailleurs, l’ensemble des données nécessaires à l’établissement d’une communication n’est pas forcément fourni par un système monolithique, et encore moins décrit dans un seul protocole. Plusieurs protocoles sont utilisés, et qui peuvent être mis en œuvre par des systèmes différents.

Ce qui suit est tiré de la version 2.0 du protocole SIP ("Session Initiation Protocol"), version initialement décrite dans la RFC 3261, de juin 2002, et complétée par plusieurs RFC ultérieures. Le protocole SIP est utilisé en téléphonie et visiophonie sur IP, mais aussi par certaines messageries en ligne, et même dans certains jeux vidéo.

On peut ici laisser de côté certains aspects du protocole SIP, par exemple :
- la structure (le "SIP(S) Uniform Resource Identifier") des identifiants informatiques attribués par un serveur SIP aux différents utilisateurs enregistrés auprès de lui,
- le détail des méthodes pour impliquer plusieurs serveurs SIP communiquant entre eux, tous les utilisateurs éventuels n’ayant pas à s’enregistrer auprès d’un même unique serveur SIP,
- le contenu détaillé de certains messages SIP tels que ceux qui déclenchent une sonnerie du poste destinataire, transportent en retour son acceptation ou non de la communication, ou marquent la fin d’une communication.
Par ailleurs, le protocole SIP ne décrit pas certains aspects techniques de la communication, par exemple le codec utilisé. Une session SIP transporte certes de telles informations, mais qui sont codées selon le(s) protocole(s) d’un autre (d’autres) format(s). Ici, on utilise souvent le protocole SDP ("Session Description Protocol"), décrit dans la RFC 4566 de juillet 2006.

Pour le reste, le processus d’établissement d’une communication est en (très) gros le suivant :
- chaque participant potentiel se connecte au préalable au serveur SIP sur lequel il possède un compte, pour lui indiquer sa disponibilité pour recevoir une communication éventuelle;
- si l’un deux (nommé ici poste A) souhaite établir une communication avec un poste B, il envoie une requête au serveur SIP sur lequel il est enregistré (nommons ici ce serveur "serveur A"). On peut appeler ici cette requête une "invitation";
- dans le cas le plus général, ce serveur A transmet cette invitation à un autre serveur SIP, celui sur lequel le poste B est enregistré (nommons-le "serveur B");
- ce serveur B alerte le poste B, qui peut répondre de diverses façons à cette invitation : appel accepté, appel refusé, etc.;
- cette réponse parvient au poste A, et la communication peut alors éventuellement ensuite commencer.

Un point important est que cette invitation s’enrichit de quelques informations techniques lors de chacune des transmissions qu’elle subit pour atteindre sa destination :
- par exemple du serveur A au serveur B,
- mais aussi, éventuellement entre des serveurs intermédiaires entre les serveur A et B : divers proxies;
- ainsi que la transmission initiale entre le poste A et le serveur A, et la transmission finale entre le serveur B et le poste B.
Lors de chacune de ces transmissions, l’ordinateur relayeur ajoute un en-tête à ce message SIP (l’invitation), avec notamment le port de communication (TCP ou UDP) sur lequel il attend la réponse, lorsque, partant du poste B pour revenir au poste A, cette réponse fera le chemin inverse de celui suivi par l’invitation, et donc passera – en sens inverse – par ce relayeur. De plus, l’ordinateur auquel le relayeur aura transmis cette invitation aura complété cet en-tête en y ajoutant l’adresse IP (publique) de ce relayeur.
Parvenue au poste B, cette invitation contient donc une pile d’en-têtes, dont le "dépilage" (dernier ajouté, premier relu) permet alors de connaître le chemin à suivre par la réponse à cette invitation.
La RFC 3261 nomme :
- "Via" cet en-tête,
- et dans cet en-tête, "received" le nom du champ contenant l’adresse IP publique de chaque relais, adresse constatée et ajoutée par le relais suivant.

Pour la suite de cette session SIP :
- après avoir reçu une réponse positive à son invitation, le poste A envoie un accusé de réception au poste B. Cet envoi n’a pas besoin de passer par la même chaîne de relais qu’a suivie l’invitation, puisque les en-têtes "Via" de la réponse reçue permettent, à ce stade, l’envoi direct d’un message SIP du poste A au poste B.
- puis se déroule la communication elle-même : voir le billet suivant
- une fois cette communication terminée, un dernier échange SIP a lieu entre les postes A et B, pour signaler que l’un deux met fin à cette communication, avec réponse de l’autre poste.
Ainsi la session SIP commence avant la communication elle-même, et se termine après.

 

La traversée des NAT

Concernant la "traversée des NAT", précisons que les cas très particuliers de NAT équipés de systèmes de type AGL ("Application Level Gateways") ou SBC ("Session Border Controllers") sortent du champ d’étude de ce billet. On pourra éventuellement trouver des informations sur le fonctionnement de tels dispositifs dans les RFC 3424, 4787 et 5245.

Pour "traverser" les autres types de NAT, plusieurs problèmes sont alors à résoudre :

a) Le poste A initie la session SIP en contactant le serveur A auprès duquel il est enregistré. Cette connexion crée une NAT dynamique sur le routeur du réseau hébergeant ce poste A, qui va attendre que lui parvienne la réponse – à son invitation à communiquer – du poste B. Cette réponse devra donc pouvoir utiliser "à l’envers" cette NAT dynamique créée dans le routeur du poste A.
Or si le protocole utilisé ici est UDP, alors cette NAT n’a qu’une durée de vie faible, de l’ordre de quelques dizaines de secondes au maximum, ce qui risque de ne pas permettre d’attendre une réponse du poste B. Le logiciel client en action sur le poste A devrait se charger de l’entretien de cette session sortante, en répétant périodiquement cette invitation à communiquer (il s’agit toujours de la même session, donc le routeur ne créera aucune nouvelle NAT dynamique différente).
Plus complètement, la RFC 5626 d’octobre 2009 explique comment un poste d’utilisateur peut maintenir active une telle connexion à un serveur SIP.

b) Lors de la transmission de l’invitation, chaque relayeur ajoute un en-tête "Via" à ce message SIP. Cet en-tête "Via" contient le port de communication sur lequel ce relayeur attend que lui parvienne, en retour, la réponse à cette invitation.
Mais si un relayeur – par exemple le poste A – est derrière un routeur sans NAT statique paramétrée :
- c’est la NAT dynamique mise en œuvre lors de ce relais qui sera utilisable, au retour, quand il faudra lui faire parvenir la réponse à l’invitation;
- or si cette NAT dynamique change le port de communication, le relais suivant ne saura pas, quand il lui faudra transmettre en sens inverse la réponse, sur quel port de communication la lui adresser : à l’aller, ce relais suivant n’avait ajouté que l’adresse IP publique de ce relayeur dans le champ "received" de cet en-tête, mais rien sur la translation de port effectuée par le routeur de ce relayeur.
C’est pourquoi la RFC 3581, de août 2003, a ajouté à l’en-tête "Via" un champ "rport", similaire au champ "received", dans lequel chaque relais doit indiquer le port de communication public du relayeur précédent. Au retour, la réponse à l’invitation pourra donc utiliser de telles NAT dynamiques.

c) Le serveur SIP mandaté pour interroger le poste B doit pouvoir le joindre. Or ce serveur, en exploitant sa base de données de ses utilisateurs enregistrés, ne connaît qu’un (éventuellement plusieurs) identifiant(s) permettant de nommer cet utilisateur, mais il ne peut pas connaître en permanence l’adresse IP permettant de le joindre, car cette adresse IP peut changer :
- il peut s’agir d’un réseau local disposant d’une adresse IP gérée "dynamiquement" par son FAI (voir ci-dessus),
- surtout, rien n’empêche un utilisateur de déplacer son poste – si c’est un ordinateur portable, par exemple – d’un réseau local à l’autre, et de continuer à vouloir pouvoir communiquer avec autrui.
Cette incertitude sur l’adresse IP permettant de joindre le poste B se double d’une autre incertitude, similaire, sur le port de communication à utiliser, de l’extérieur du réseau local hébergeant ce poste.
La conséquence est que c’est à l’utilisateur d’un tel système de prendre l’initiative de se connecter à son serveur SIP, ce qui permet :
- fonctionnellement, de lui indiquer sa disponibilité pour une telle communication,
- informatiquement, de lui révéler son adresse IP et son port de communication publics du moment.
Cette connexion initiée de l’intérieur du réseau local créée donc une NAT dynamique dans le routeur de ce réseau du poste B. C’est cette NAT que pourra alors utiliser le serveur B pour lui transmettre un message SIP d’invitation à communiquer.

Enfin, un point très important est que cette chaîne de relais ne concerne que les messages SIP, pas la communication elle-même. Cette communication sera une autre session, qui s’établira en principe directement entre les postes A et B. Pour une communication audio ou/et vidéo utilisant la signalisation SIP, le protocole utilisé pour la communication elle-même est en général RTP ("Real-Time Transport Protocol"), dont la dernière version est décrite dans la RFC 3550 de juillet 2003, une RFC complétée par plusieurs autres RFC ultérieures.
Cette communication a donc elle aussi besoin d’utiliser des NAT dynamiques mises en œuvres par les routeurs concernés. Ceci fait l’objet des billets suivants.

 

 

WebRTC et les NAT
Les NAT dynamiques et les NAT statiques
La signalisation SIP et les NAT
Le protocole SDP
Les protocoles STUN et TURN
Le protocole ICE