Lors de notre précédent article, nous avions discuté de STUN, dont les fonctionnalités offrent déjà une gamme de services intéressantes. Il avait cependant été question que cette traversée de NAT, si elle est efficace, n’est pas exhaustive, puisque seuls les NAT dont les associations sont créées indépendamment de la destination sont supportés. Malheureusement, beaucoup de NAT à l’heure actuelle ne fonctionnent pas de cette manière, étant bien souvent des NAT symétriques ou, plus manière plus générique, dépendants de la destination. TURN (Traversal Using Relays around NAT) a été étudié comme un extension à STUN venant particulièrement combler ce problème en proposant une approche se basant sur un serveur relai servant de pont entre les deux parties.
Fonctionnement général
Se reposant sur STUN, la nouvelle méthode introduite par TURN, allocate, réserve un couple adresse/port au niveau du serveur STUN qui sera utilisé à la fois pour contacter l’hôte distant, mais aussi pour que ce dernier puisse nous contacter. Malheureusement, et bien qu’il s’avère particulièrement important à l’heure actuelle, ce procédé met en péril le fonctionnement même d’un protocole peer to peer mettant en relation deux hôtes directement, en essayant de passer le moins possible par des serveurs intermédiaires.
Le cadre qui nous intéresse ici, soit les communications en temps réel audio et/ou vidéo, est relativement gourmand en ressources pour les ordinateurs. Dès lors, les serveurs relais, puisqu’ils font transiter les communications, doivent être en mesure de supporter cette charge, et doivent dès lors être dimensionnés de manière adéquate (haute disponibilité, partage de charge, évolutivité …). Lorsque ses capacités ne suffisent plus ou qu’il a atteint certaines limites (par utilisateur par exemple), un serveur peut transmettre, en réponse à une requête allocate, des messages d’erreur spécifiques (486 Allocation Quota Reached et 508 Insufficient Capacity). Que se passe-t-il néanmoins lors des communications lorsque TURN est utilisé ?
Le premier point qu’il est important de noter ici est l’usage de la méthode allocate en lieu et place de la méthode binding. Comme son nom le laisse suggérer, cette méthode alloue, réserve un couple adresse et port auprès du serveur, par lequel le client TURN peut être contacté. Pourtant, en tant qu’extension à STUN, TURN fournit aussi les informations relatives à la MAPPED-ADDRESS. Ce protocole ne modifie en rien le fonctionnement de celui sur lequel il se repose, mais par les services qu’il offre, ne peut que difficilement ne pas devenir un incontournable.
La méthode allocate ne diffère pratiquement pas de binding. Les plus grosses différences tiennent en deux point majeurs :
- L’authentification
TURN requière l’usage de l’authentification à long terme défini par STUN, et discutée lors de notre précédent billet. En effet, il est essentiel de limiter l’accès aux ressources du serveur aux seuls utilisateurs légitimes. Seul les utilisateurs auxquels un mot de passe aura été fourni, par une méthode qui n’est pas définie ici, seront en mesure de créer une réservation sur le serveur.
- La réponse
En lieu et place de la simple XOR-MAPPED-ADDRESS, le serveur TURN fournit l’adresse de relai par laquelle transitera la communication future. Cette adresse est obscurcie de la même manière que pour STUN, en utilisant le magic cookie, sous la forme de l’attribut XOR-RELAYED-ADDRESS.
Le client TURN pourra transmettre les informations de relai reçues à sa destination, via un protocole de signalisation (SIP), de manière à ce que celle-ci essaie de le contacter non pas sur son adresse publique, mais sur la réservation faite auprès du serveur TURN.
Sa différence de conception par rapport à STUN, et notamment la consommation de ressource que son usage implique, le serveur TURN ne garde pas les réservations indéfiniment afin notamment de libérer autant de ressources que possible. De ce fait, il est essentiel pour le client de les rafraîchir régulièrement, avec la méthode refresh prévue dans ce but, contenant la nouvelle durée de vie souhaitée (que le serveur adaptera en fonction de ses limites) au sein de l’attribut LIFETIME. Il est intéressant de noter que, puisque il faut prolonger les réservations, il est aussi possible de les annuler, toujours en utilisant ce même attribut, mais cette fois-ci avec une valeur de zéro.
Permissions
A cause de sa consommation en ressources, il est essentiel de limiter l’usage de la réservation par les hôtes distant au strict minimum. Partant de ce constat, un filtrage similaire au filtrage dépendant des NAT a été mis en place en ce sens que toutes les requêtes à destination de notre client TURN n’ayant pas été autorisées précédemment seront refusées. Un client TURN peut créer une réservation sans créer de permission pour son destinataire, ce qui aura pour effet de consommer des ressources (des adresses et ports, dans le cas présent) pour rien. La création de permission peut s’effectuer au travers de deux méthodes différentes, CreatePermission et ChannelBind.
Chaque méthode dispose de ses spécificités, mais toutes deux aboutissent au même résultat :
- CreatePermission & Send/Data
Cette méthode crée une permission pour la destination mentionnée (XOR-PEER-ADDRESS), d’une durée de 5 minutes. Lorsque cette permission est créée, la communication transitera pas le biais d’indications (requêtes n’attendant aucune réponse) Send (entre le client et le serveur) et Data (entre le serveur et le client).
- ChannelBind & ChannelData
Similaire à la méthode précédente, elle offre de sensibles améliorations qui tendent à la préférer. Outre une durée de vie supérieure (10 minutes), elle permet de s’affranchir, lorsque le canal est établit, d’un grand nombre d’entêtes dont la méthode précédente a besoin : l’adresse de la destination, etc. Ici, rien de tel, et lorsque la permission est créée, le serveur relai est capable de déterminer quelle connexion utiliser par l’identifiant du canal lui-même. De plus, cette méthode définit une unique indication par laquelle tous les messages et tous les paquets vont transiter. Ce mécanisme limite autant que possible l’utilisation des ressources du serveur.
Il est intéressant de noter que ces méthodes et indications ne concernent que les clients TURN : un participant n’ayant pas à utiliser un serveur relai pour communiquer contacter le serveur TURN à l’aide d’un simple et classique datagramme UDP.
Cette extension apporte un ajout indéniable à STUN puisqu’il se place en complément direct, étant capable d’appréhender la grosse majorité les cas de figures que le protocole original ne supportait pas. Profitant de la modularité de son aîné, il est facilement adaptable aux nouvelles situations et offre un niveau de services et de sécurité intéressant dont il serait dommage de se priver. Il n’existe à l’heure actuelle que peu d’implémentations valides, et les rares sont issues du monde de l’Open Source, au travers notamment des servers STUN/TURN turnserver et reTURN.
Toutefois, si le couple STUN/TURN propose une solution intéressante, l’IETF propose depuis peu un concept intéressant, sous la forme d’ICE, qui facilite et renforce encore la traversée de NAT de STUN et TURN. Mais ceci est une autre histoire dont il sera question prochainement, so stay tuned !