# SOCKS

SOCKS est un protocole réseau qui permet à des applications client-serveur d'employer les services d'un pare-feu. SOCKS est l'abréviation du terme anglophone « sockets ».
Les applications du réseau protégées derrière le pare-feu qui souhaitent accéder à des serveurs extérieurs doivent se connecter via un serveur proxy utilisant le protocole SOCKS. Un tel serveur décide de l'éligibilité du client à accéder au serveur externe et transmet sa requête au serveur. Le protocole peut également être employé de manière inverse, permettant aux applications à l'extérieur de se connecter aux serveurs derrière le pare-feu.

## Histoire

Le protocole est à l'origine développé par David Koblas, un des administrateurs système de la société MIPS. L'année du rachat de MIPS par Silicon Graphics, en 1992, Koblas présente un papier sur SOCKS à un colloque sur la sécurité Usenix, et SOCKS devient de fait un protocole public. Le protocole est amélioré dans sa version 4 par Ying-Da Lee de la société NEC.
La version 4a, « officieuse », ajoute le support des serveurs de résolution de noms à SOCKS.
L'actuelle version 5 du protocole, spécifiée dans la RFC 1928, étend la version précédente en ajoutant la possibilité de transmettre de l'UDP, permet l'authentification, la résolution des noms de domaines par le serveur SOCKS lui-même, et IPv6.
L'architecture et l'application cliente de référence sont la propriété de Permeo Technologies.

## Classification

D'après le modèle OSI, le protocole SOCKS est une couche intermédiaire entre la couche applicative et la couche transport.

## Serveurs SOCKS

Liste de logiciels serveur SOCKS :
* Dante Socks Server : open source et gratuit, plateformes POSIX ;
* WinSocks : Socks Proxy Server WinSocks, propriétaire, évaluation de 30 jours, uniquement sous Windows ;
* FreeProxy inclut un serveur SOCKS : non open source, gratuit, uniquement sous Windows ;
* AnalogX Proxy inclut un serveur SOCKS : non open source, gratuit, uniquement sous Windows ;
* Java Socks Server : open source, gratuit, toutes plateformes ;
* Socks4 Server : open source, gratuit, toutes plateformes ;
* SS5 Socks Server : open source, gratuit, Fedora, FreeBSD ;
* nylon : open source et gratuit, OpenBSD ;
* 3proxy : open source, gratuit, toutes plateformes ;
* WinGate : non open source, Payant, uniquement sous Windows ;
* OpenSSH : open source, gratuit, plateformes POSIX ;
* DeleGate : Propriétaire, gratuit, toutes plateformes ;
* Antinat : open source, gratuit, toutes plateformes ;
* srelay : open source, gratuit, plateformes POSIX ;
* sSocks : open source, gratuit, plateformes POSIX ;
* PuTTY Tunnel de type Dynamic : open source, gratuit, uniquement sous Windows.

## Clients SOCKS

Il existe des programmes permettant de socksifier d'autres applications, ce qui permet à n'importe quel logiciel possédant des capacités réseau d'utiliser SOCKS, même s'il n'est pas prévu pour supporter SOCKS.
Liste de clients SOCKS :
| Client | Licence | Version | Date de création | Plateforme | Version de protocole |
| ProxyCap | Shareware | 5.26 | 03/2007 | Windows, Mac OS X | v4, v5, HTTPS, SSH tunnel, HTTP |
| socat | GPL | 1.6 | 03/2007 | POSIX | multi-optional tunnel |
| WideCap | Shareware | 1.4 | 12/2007 | Windows | v4, v5, HTTPS |
| Proxifier | Shareware | 3.21 | 02/2007 | Windows, Mac OS X | v4, v5, HTTPS, HTTP |
| HTTP-Tunnel Client | Freeware | 4.4.400 | 01/2007 | Windows | v4, v5, HTTP |
| dsocks | GPL | 1.6 | 10/2006 | *BSD, Mac OS X | v4, v5 |
| connect | GPL | 1.95 | 08/2006 | Windows, POSIX | v4, v5, HTTPS |
| nylon | 3-clause BSD | 1.2.1 | 07/2006 | OpenBSD | v4, v5 |
| proxychains | GPL | 3.1 | 05/2006 | POSIX (source) | v4, v5, HTTPS |
| FreeCap | GPL | 3.18 | 02/2006 | Windows | v4, v5, HTTPS |
| Dante client | BSD/Carnegie Mellon University | 1.1.19 | 01/2006 | POSIX | v4, v5, HTTP |
| TunnelIt | Shareware | 1.4 | 06/2005 | Windows | SSH tunnel |
| GNet Library | GPL | 2.0.7 | 02/2005 | POSIX (source) | v4, v5 |
| Hummingbird SOCKS | Freeware | 8.0 | 10/2003 | Windows | v4, v5 |
| tsocks | GPL | 1.8 | 10/2002 | POSIX (source) | v4, v5 |
| Kernel Socks Bouncer | GPL | 0.0.4 | 1/2005 | POSIX (source) | v5 |

## SOCKS v4

Une connexion SOCKS normale consiste à échanger les trames TCP suivantes :
Du client vers le serveurs SOCKS
* champ 1 : Version du protocole, 1 octet, 0x04 pour cette version
* champ 2 : octet de commande, 1 octet:
** 0x01 = établir un pipe TCP/IP
** 0x02 = établir une correspondance de port TCP
* champ 3 : numéro de port, (sur 2 octets, big endian)
* champ 4 : adresse IPv4 (sur 4 octets)
* champ 5 : chaîne d'authentification de l'utilisateur (ascii, longueur variable, terminée par un caractère NULL 0x00)
Puis du serveur vers le client
* champ 1 : constante 0x0, 1 octet
* champ 2 : octet de statut :
** 0x5a = requête acceptée
** 0x5b = requête rejetée ou erreur
** 0x5c = requête échouée car le client n'a pas lancé le démon identd (ou identd n'est pas accessible par le serveur)
** 0x5d = requête échouée car le service identd du client n'a pas authentifié la chaîne envoyée dans la requête.
* champ 3 : 2 octets, ignoré
* champ 4 : 4 octets, ignoré
Exemple :
Voici la requête SOCKS qui permet de connecter un client Fred à l'adresse 66.102.7.99:80, dans cet exemple le serveur répond par un "OK" :
* Client: 0x04 | 0x01 | 0x00 0x50 | 0x42 0x66 0x07 0x63 | 0x46 0x72 0x65 0x64 0x00
** Le dernier champ contient la chaine "Fred\0" en ASCII
* Réponse serveur SOCKS : 0x00 | 0x5a | 0xDE 0xAD | 0xBE 0xEF 0xFF 0xFF
** Les deux derniers champs contiennent des valeurs arbitraires, que le protocole invite a ignorer.
À partir de ce point toutes les données, envoyées dans ce flux TCP seront transférées sur le port 80 à l'adresse 66.102.7.99
La valeur 0x02 ("bind") pour le deuxième champ de la requête permet l'ouverture de connexions entrantes pour les protocoles tels que le FTP en mode actif.

### SOCKS v4a

SOCKS 4a est une simple extension au protocole SOCKS 4 qui permet à un client qui ne peut pas résoudre le nom de domaine de l'hôte de destination de l'indiquer dans sa requête.
Le client doit mettre les trois premiers octets de l'adresse IP de destination à NULL et le dernier octet à une valeur différente de NULL (cela correspond à une adresse IP du type 0.0.0.x, avec x une valeur différente de 0, ce qui n'est pas une adresse valide et qui n'aurait donc jamais pu être utilisée si le client avait pu résoudre le nom de domaine). Le client doit ensuite envoyer le nom de domaine de destination après l'octet NULL qui termine le nom d'utilisateur et le terminer par un autre octet NULL. Cela est utilisé de la même manière pour les requêtes "connect" et "bind".
Une connexion SOCKS avec demande de résolution de nom de domaine se présente comme suit :
Du client vers le serveur
* champ 1 : Version du protocole, 1 octet, 0x04 pour cette version
* champ 2 : octet de commande, 1 octet:
** 0x01 = établir un pipe TCP/IP
** 0x02 = établir une correspondance de port TCP
* champ 3 : numéro de port, (sur 2 octets, big endian)
* champ 4 : adresse IPv4 (sur 4 octets) délibérément invalide, les premiers octets doivent être 0x00 et le dernier doit être différent de 0x00
* champ 5 : chaîne d'authentification de l'utilisateur (ascii, longueur variable, terminée par un NULL)
* champ 6 : nom de domaine de l'hôte à contacter (ascii, longueur variable, terminé par un NULL)
Puis du serveur vers le client
* champ 1 : constante 0x0
* champ 2 : octet de statut :
** 0x5a = requête acceptée
** 0x5b = requête rejetée ou erreur
** 0x5c = requête échouée car le client n'a pas lancé le démon identd (ou identd n'est pas accessible par le serveur)
** 0x5d = requête échouée car le service identd du client n'a pas authentifié la chaîne envoyée dans la requête.
* champ 3 : numéro de port, 2 octets
* champ 4 : adresse IPv4, 4 octets
Un serveur supportant le protocole 4a doit examiner l'adresse IP de destination dans la requête. S'il s'agit d'une adresse 0.0.0.x avec x non nul, le serveur doit lire le nom de domaine indiqué par le client dans le paquet. Il doit ensuite résoudre lui-même le nom de domaine et établir la connexion si possible.

## SOCKS v5

SOCKS v5 est une extension de SOCKS v4 qui offre davantage de possibilités d'authentification ainsi que le support de l'UDP. La poignée de main initiale consiste en la procédure suivante :
* Le client se connecte et envoie une annonce qui inclut une liste de méthodes d'authentification qu'il supporte.
* Le serveur choisit l'une de ces méthodes ou envoie une erreur si aucune méthode n'est acceptable.
* Plusieurs messages sont alors échangés selon la méthode d'authentification choisie.
* Une fois authentifié le client envoie une requête de connexion similaire mais différente du protocole SOCKS v4.
* Le serveur répond d'une manière similaire à SOCKS v4.
Les méthodes d'authentification supportées sont numérotées comme suit :
* 0x00 - Pas d'authentification
* 0x01 - GSSAPI
* 0x02 - Nom d'utilisateur/Mot de passe
* 0x03-0x7F - méthodes définies par l'IANA
* 0x80-0xFE - méthodes réservée pour des utilisations privées.
La requête initiale du client vers le serveur est :
* champ 1 : numéro de version de SOCKS (0x05 pour cette version), sur un octet
* champ 2 : nombre de méthodes d'authentification supportées, sur un octet
* champ 3 : liste des méthodes d'authentification supportées (un octet par méthode), de taille variable
Le serveur communique alors son choix :
* champ 1 : numéro de version de SOCKS (0x05 pour cette version), sur un octet
* champ 2 : méthode d'authentification choisie, sur un octet, ou 0xFF si aucune des méthodes proposées n'est convenable
La suite de l'authentification dépend de la méthode choisie.
Après l'authentification, le client envoie sa demande de connexion :
* champ 1 : numéro de version de SOCKS (devrait être 0x05 pour cette version), sur un octet
* champ 2 : code de commande sur un octet :
** 0x01 = établir une connexion TCP/IP
** 0x02 = mettre en place une correspondance de port TCP
** 0x03 = associer un port UDP
* champ 3 : réservé, doit être 0x00
* champ 4 : type de l'adresse de destination, sur un octet :
** 0x01 = adresse IPv4 (le champ adresse sera de longueur 4 octets)
** 0x03 = nom de domaine (le champ adresse sera de longueur variable)
** 0x04 = adresse IPv6 (le champ adresse sera de longueur 16 octets)
* champ 5 : adresse de destination, de longueur 4 ou 16 octets, ou de la longueur du nom de domaine + 1.
** Si le type d'adresse est 0x03 alors l'adresse est constituée d'un octet indiquant la longueur du nom de domaine suivi du nom lui-même
* champ 6 : numéro de port, sur 2 octets
Le serveur transmet sa réponse :
* champ 1 : numéro de version de SOCKS (devrait être 0x05 pour cette version), sur un octet
* champ 2 : statut, sur un octet :
** 0x00 = requête acceptée
** 0x01 = échec
** 0x02 = connexion interdite
** 0x03 = réseau injoignable
** 0x04 = hôte de destination injoignable
** 0x05 = connexion refusée par l'hôte de destination
** 0x06 = TTL expiré
** 0x07 = commande non supportée/erreur de protocole
** 0x08 = type d'adresse non supporté
* champ 3 : réservé, doit être 0x00
* champ 4 : type de l'adresse d'association sur socks proxy, sur un octet :
** 0x01 = adresse IPv4 (le champ adresse sera de longueur 4 octets)
** 0x03 = nom de domaine (le champ adresse sera de longueur variable)
** 0x04 = adresse IPv6 (le champ adresse sera de longueur 16 octets)
* champ 5 : adresse d'association sur socks proxy, de longueur 4 ou 16 octets, ou de la longueur du nom de domaine + 1.
** Si le type d'adresse est 0x03 alors l'adresse est constituée d'un octet indiquant la longueur du nom de domaine suivi du nom lui-même
* champ 6 : numéro de port d'association sur socks proxy, sur deux octets