Comprendre les sockets

Introduction

Les sockets sont un moyen de permettre la communication inter-processus entre des programmes s’exécutant sur un serveur, ou entre des programmes s’exécutant sur des serveurs séparés. La communication entre les serveurs repose sur des sockets réseau, qui utilisent le protocole Internet (IP) pour encapsuler et gérer l’envoi et la réception de données.

Les sockets réseau sur les clients et les serveurs sont désignés par leur adresse de socket. Une adresse est une combinaison unique d’un protocole de transport comme le protocole de contrôle de transmission (TCP) ou le protocole de datagramme utilisateur (UDP), une adresse IP et un numéro de port.

Dans ce tutoriel, vous apprendrez les différents types de sockets utilisés pour la communication inter-processus, notamment :

  • Les sockets de flux, qui utilisent TCP comme protocole de transport sous-jacent
  • Les sockets de datagramme, qui utilisent UDP comme protocole de transport sous-jacent
  • Les sockets de domaine Unix, qui utilisent des fichiers locaux pour envoyer et recevoir des données au lieu d’interfaces réseau et de paquets IP.

Dans chaque section de ce tutoriel, vous apprendrez également comment énumérer les différents types de sockets sur un système Linux. Vous examinerez chaque type de socket à l’aide d’une variété d’outils en ligne de commande.

Prérequis

Les exemples de ce tutoriel ont été validés sur un serveur Ubuntu 20.04. Vous pouvez suivre ce tutoriel en utilisant la plupart des distributions Linux modernes sur un ordinateur local ou un serveur distant, tant que vous avez la version équivalente de chacun des outils requis pour votre distribution installée.

Pour commencer à utiliser Ubuntu 20.04, vous aurez besoin d’un serveur qui a été configuré en suivant notre guide Configuration initiale du serveur pour Ubuntu 20.04.

Vous aurez également besoin de quelques autres paquets pour examiner les sockets sur votre système. Assurez-vous que le cache des paquets de votre système est à jour en utilisant la commande apt update:

  1. sudo apt update

Ensuite, installez les paquets requis en utilisant cette commande :

  1. sudo apt install iproute2 netcat-openbsd socat

Le paquet iproute2 contient l’utilitaire ss, que nous utiliserons pour inspecter les sockets. Nous utiliserons le paquet netcat-openbsd pour installer netcat. Notez que netcat est abrégé en nc lorsqu’il est invoqué en ligne de commande. Enfin, nous utiliserons le paquet socat pour créer des sockets d’exemple.

Qu’est-ce qu’un socket de flux?

Les sockets de flux sont orientés connexion, ce qui signifie que les paquets envoyés à et reçus depuis un socket réseau sont livrés par le système d’exploitation hôte pour être traités par une application. Les sockets de flux basés sur le réseau utilisent généralement le protocole de contrôle de transmission (TCP) pour encapsuler et transmettre des données sur une interface réseau.

Le TCP est conçu pour être un protocole réseau fiable qui repose sur une connexion étatique. Les données envoyées par un programme utilisant un socket de flux basé sur TCP seront reçues avec succès par un système distant (en supposant qu’il n’y a pas de problèmes de routage, de pare-feu ou d’autres problèmes de connectivité). Les paquets TCP peuvent arriver sur une interface réseau physique dans n’importe quel ordre. Dans le cas où les paquets arrivent dans le désordre, l’adaptateur réseau et le système d’exploitation hôte veilleront à ce qu’ils soient réassemblés dans la séquence correcte pour être traités par une application.

A typical use for a TCP-based stream socket would be for a web server like Apache or Nginx handling HTTP requests on port 80, or HTTPS on port 443. For HTTP, a socket address would be similar to 203.0.113.1:80, and for HTTPS it would be something like 203.0.113.1:443.

Création de sockets de flux basés sur TCP

Dans l’exemple suivant, vous utiliserez la commande socat (abrégée de SOcket CAT) pour émuler un serveur web écoutant les demandes HTTP sur le port 8080 (le port HTTP alternatif). Ensuite, vous examinerez le socket à l’aide des commandes ss et nc.

Tout d’abord, exécutez les commandes socat suivantes pour créer deux sockets TCP en attente de connexions sur le port 8080, en utilisant les interfaces IPv4 et IPv6 :

  1. socat TCP4-LISTEN:8080,fork /dev/null&
  2. socat TCP6-LISTEN:8080,ipv6only=1,fork /dev/null&
  • Les arguments TCP4-LISTEN:8080 et TCP6-LISTEN:8080 sont le type de protocole et le numéro de port à utiliser. Ils indiquent à socat de créer des sockets TCP sur le port 8080 sur toutes les interfaces IPv4 et IPv6, et d’écouter chaque socket pour les connexions entrantes. socat peut écouter sur n’importe quel port disponible sur un système, donc n’importe quel port de 0 à 65535 est un paramètre valide pour l’option de socket.
  • L’option fork est utilisée pour garantir que socat continue de s’exécuter après avoir géré une connexion, sinon il se terminerait automatiquement.
  • Le chemin /dev/null est utilisé à la place d’une adresse de socket distante. Dans ce cas, il indique à socat d’imprimer toute entrée entrante dans le fichier /dev/null, qui la supprime silencieusement.
  • Le drapeau ipv6only=1 est utilisé pour le socket IPv6 pour indiquer au système d’exploitation que le socket n’est pas configuré pour envoyer des paquets à des adresses IPv4 mappées en IPv6. Sans ce drapeau, socat se liera à la fois aux adresses IPv4 et IPv6.
  • Le caractère & indique au shell d’exécuter la commande en arrière-plan. Ce drapeau garantira que socat continue de s’exécuter pendant que vous invoquez d’autres commandes pour examiner le socket.

Vous recevrez une sortie comme celle ci-dessous, qui indique les deux ID de processus socat qui s’exécutent en arrière-plan de votre session shell. Vos ID de processus seront différents de ceux mis en évidence ici:

Output
[1] 434223 [2] 434224

Maintenant que vous avez deux processus socat écoutant sur le port TCP 8080 en arrière-plan, vous pouvez examiner les sockets en utilisant les utilitaires ss et nc.

Examiner les sockets de flux basés sur TCP

Pour examiner les sockets TCP sur un système Linux moderne en utilisant la commande ss, exécutez-la avec les indicateurs suivants pour limiter la sortie:

  • Les indicateurs -4 et -6 indiquent à ss d’examiner uniquement les sockets IPv4 ou IPv6 respectivement. L’omission de cette option affichera les deux ensembles de sockets.
  • L’indicateur t limite la sortie aux sockets TCP. Par défaut, l’outil ss affichera tous les types de sockets utilisés sur un système Linux.
  • L’indicateur l limite la sortie aux sockets en écoute. Sans cet indicateur, toutes les connexions TCP seraient affichées, ce qui inclurait des choses comme SSH, des clients pouvant être connectés à un serveur web, ou des connexions que votre système peut avoir à d’autres serveurs.
  • L’indicateur n garantit que les numéros de port sont affichés au lieu des noms de service.

Exécutez d’abord la commande ss -4 -tln pour examiner les sockets TCP IPv4 en écoute sur votre système:

  1. ss -4 -tln

Vous recevrez une sortie comme celle-ci:

Output
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process . . . LISTEN 0 1 0.0.0.0:8080 0.0.0.0:* . . .

Il peut y avoir d’autres lignes avec d’autres ports dans votre sortie en fonction des services qui s’exécutent sur votre système. La partie en surbrillance 0.0.0.0:8080 de la sortie indique que le socket TCP IPv4 écoute sur toutes les interfaces IPv4 disponibles sur le port 8080. Un service qui n’écoute que sur une adresse IPv4 spécifique affichera uniquement cette IP dans le champ en surbrillance, par exemple 203.0.113.1:8080.

Exécutez maintenant la même commande ss avec le drapeau -6:

  1. ss -6 -tln

Vous recevrez une sortie comme suit:

Output
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process . . . LISTEN 0 5 [::]:8080 [::]:* . . .

Il peut y avoir d’autres lignes avec d’autres ports dans votre sortie en fonction des services qui s’exécutent sur votre système. La partie en surbrillance [::]:8080 de la sortie indique que le socket TCP IPv6 écoute sur toutes les interfaces IPv6 disponibles sur le port 8080 (comme indiqué par les caractères ::, qui sont une notation IPv6 pour une adresse composée de tous les zéros). Un service qui n’écoute que sur une adresse IPv6 spécifique affichera uniquement cette IP dans le champ en surbrillance, par exemple [2604:a880:400:d1::3d3:6001]:8080.

Connexion aux sockets de flux basés sur TCP

Jusqu’à présent, vous avez appris à créer et à énumérer des sockets TCP sur des interfaces IPv4 et IPv6. Maintenant que vous avez deux sockets en écoute pour les connexions, vous pouvez expérimenter en vous connectant aux sockets en utilisant l’utilitaire netcat.

Utiliser netcat pour tester les connexions TCP aux sockets locaux et distants est une technique de dépannage très utile qui peut aider à isoler les problèmes de connectivité et de pare-feu entre les systèmes.

Pour vous connecter au socket IPv4 sur l’adresse de bouclage local en utilisant netcat, exécutez la commande suivante :

  1. nc -4 -vz 127.0.0.1 8080
  • Le drapeau -4 indique à netcat d’utiliser IPv4.
  • Le drapeau -v est utilisé pour afficher une sortie détaillée sur votre terminal.
  • L’option -z garantit que netcat se connecte uniquement à un socket, sans envoyer de données.
  • L’adresse IP de bouclage local 127.0.0.1 est utilisée car votre système aura sa propre adresse IP unique. Si vous connaissez l’IP de votre système, vous pouvez également effectuer un test en utilisant cette adresse. Par exemple, si l’adresse IP publique ou privée de votre système est 203.0.113.1, vous pouvez l’utiliser à la place de l’adresse de bouclage.

Vous recevrez une sortie comme suit :

Output
Connection to 127.0.0.1 (127.0.0.1) 8080 port [tcp/http-alt] succeeded!

La ligne en surbrillance est la sortie de netcat. Elle indique que netcat s’est connecté au socket TCP en écoute sur l’adresse IPv4 de bouclage local 127.0.0.1 sur le port 8080. Vous pouvez ignorer la deuxième ligne, elle provient du processus socat s’exécutant en arrière-plan dans votre terminal.

Maintenant, vous pouvez répéter le même test de connexion mais en utilisant IPv6. Exécutez la commande netcat suivante :

  1. nc -6 -vz ::1 8080

Vous devriez recevoir une sortie comme suit :

Output
Connection to ::1 8080 port [tcp/http] succeeded!

La ligne en surbrillance est la sortie de netcat. Elle indique que netcat s’est connecté au socket TCP en écoute sur l’adresse IPv6 de bouclage local ::1 sur le port 8080. Encore une fois, vous pouvez ignorer la deuxième ligne de sortie.

Pour nettoyer vos sockets, vous devrez exécuter la commande fg (foreground) pour chaque processus socat que vous avez créé. Ensuite, vous utiliserez CTRL+C pour fermer chaque socat. fg ramènera les processus au premier plan de votre terminal dans l’ordre inverse où vous les avez exécutés, donc lorsque vous l’exécutez, la deuxième instance socat sera celle avec laquelle vous interagirez en premier.

Exécutez fg pour ramener la deuxième instance IPv6 socat au premier plan de votre terminal. Ensuite, exécutez CTRL+C pour la fermer.

  1. fg

Vous recevrez une sortie comme suit:

Output
socat TCP6-LISTEN:8080,ipv6only=1,fork /dev/null

Appuyez sur CTRL+C pour arrêter le processus.

Exécutez maintenant fg à nouveau pour nettoyer le premier socket IPv4. Vous devriez avoir une sortie comme suit:

Output
socat TCP4-LISTEN:8080,fork /dev/null

Appuyez sur CTRL+C pour arrêter le processus.

Vous avez maintenant créé, examiné et connecté des sockets IPv4 et IPv6 sur votre système. Ces techniques et outils fonctionneront sur les systèmes de développement locaux ou les serveurs de production distants, alors essayez d’expérimenter avec chaque outil pour devenir plus familier avec la manière dont ils peuvent être utilisés pour tester et dépanner les sockets TCP.

Qu’est-ce qu’un Socket Datagramme?

Les sockets datagrammes sont sans connexion, ce qui signifie que les paquets envoyés et reçus à partir d’un socket sont traités individuellement par les applications. Les sockets datagrammes basés sur le réseau utilisent généralement le protocole User Datagram Protocol (UDP) pour encapsuler et transmettre des données.

UDP ne code pas les informations de séquence dans les en-têtes de paquets, et il n’y a pas de correction d’erreur intégrée dans le protocole. Les programmes qui utilisent des sockets réseau basés sur les datagrammes doivent intégrer leur propre gestion d’erreur et leur propre logique de commande de données pour assurer une transmission de données réussie.

Les sockets UDP sont couramment utilisés par les serveurs de système de noms de domaine (DNS). Par défaut, les serveurs DNS utilisent le port 53 pour envoyer et recevoir des requêtes de noms de domaine. Un exemple d’adresse de socket UDP pour un serveur DNS serait similaire à 203.0.113.1:53.

Remarque: Bien que le protocole ne soit pas inclus dans la version lisible par l’homme de l’adresse de socket, les systèmes d’exploitation différencient les adresses de socket en incluant les protocoles TCP et UDP comme partie de l’adresse. Ainsi, une adresse de socket lisible par l’homme comme 203.0.113.1:53 pourrait utiliser l’un ou l’autre protocole. Des outils comme ss, et l’ancienne utilitaire netstat, sont utilisés pour déterminer quel type de socket est utilisé.

Le protocole Network Time Protocol (NTP) utilise un socket UDP sur le port 123 pour synchroniser les horloges entre les ordinateurs. Un exemple de socket UDP pour le protocole NTP serait 203.0.113.1:123.

Création de sockets de datagramme

Comme dans l’exemple précédent de socket TCP, dans cette section, vous utiliserez à nouveau socat pour émuler un serveur NTP écoutant les demandes sur le port UDP 123. Ensuite, vous examinerez les sockets que vous créez à l’aide des commandes ss et nc.

Tout d’abord, exécutez les commandes socat suivantes pour créer deux sockets UDP écoutant les connexions sur le port 123, en utilisant les interfaces IPv4 et IPv6:

  1. sudo socat UDP4-LISTEN:123,fork /dev/null&
  2. sudo socat UDP6-LISTEN:123,ipv6only=1,fork /dev/null&

Vous recevrez une sortie semblable à celle ci-dessous, qui indique les deux identifiants de processus socat qui s’exécutent en arrière-plan de votre session shell. Vos identifiants de processus seront différents de ceux mis en évidence ici:

Output
[1] 465486 [2] 465487
  • Chaque commande est précédée de sudo, car les ports 0 à 1024 sont réservés sur la plupart des systèmes. sudo exécute une commande avec des autorisations d’administrateur, ce qui permet à socat de se lier à n’importe quel port dans la plage réservée.
  • Les arguments UDP4-LISTEN:123 et UDP6-LISTEN:123 sont le type de protocole et le port à utiliser. Ils indiquent à socat de créer des sockets basés sur UDP sur le port 123 sur les interfaces IPv4 et IPv6, et d’écouter les données entrantes. Encore une fois, n’importe quel port dans toute la plage de 0 à 65535 est un paramètre valide pour les sockets UDP.
  • Les arguments fork, ipv6only=1 et /dev/null sont utilisés de la même manière que décrit dans l’exemple TCP précédent.

Maintenant que vous avez deux processus socat écoutant sur le port UDP 123, vous pouvez examiner les sockets à l’aide des utilitaires ss et nc.

Examen des sockets de datagramme

Pour examiner les sockets UDP sur un système Linux moderne en utilisant la commande ss, exécutez-la avec les drapeaux suivants -4, -6 et uln pour restreindre la sortie :

Le drapeau u limite la sortie aux sockets UDP.
Les autres drapeaux sont les mêmes que ceux utilisés dans l’exemple TCP précédent.

Exécutez d’abord la commande ss -4 -uln pour examiner les sockets UDP IPv4 qui écoutent les connexions sur votre système :

  1. ss -4 -uln

Vous recevrez une sortie comme suit :

Output
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process . . . UNCONN 0 0 0.0.0.0:123 0.0.0.0:* . . .

Il peut y avoir d’autres lignes avec d’autres ports dans votre sortie en fonction des services en cours d’exécution sur votre système. La partie soulignée 0.0.0.0:123 de la sortie indique que le socket UDP IPv4 est disponible sur toutes les interfaces IPv4 sur le port 123. Un service qui n’est disponible que sur une adresse IPv4 spécifique affichera uniquement cette IP dans le champ souligné, par exemple 203.0.113.1:123.

Maintenant, exécutez à nouveau la même commande ss mais avec le drapeau -6 :

  1. ss -6 -uln

Vous recevrez une sortie comme suit :

Output
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process . . . UNCONN 0 0 [::]:123 [::]:* . . .

Il peut y avoir d’autres lignes avec d’autres ports dans votre sortie en fonction des services en cours d’exécution sur votre système. La partie en surbrillance [::]:123 de la sortie indique que le socket TCP IPv6 est disponible sur toutes les interfaces IPv6 sur le port 123 (comme indiqué par les caractères ::). Un service qui n’est disponible que sur une adresse IPv6 spécifique affichera uniquement cette adresse IP dans le champ en surbrillance, par exemple [2604:a880:400:d1::3d3:6001]:123.

Test des sockets de datagramme

Maintenant que vous savez comment créer et énumérer des sockets UDP sur les interfaces IPv4 et IPv6, vous pouvez expérimenter en vous y connectant. Comme avec les sockets TCP, vous pouvez expérimenter avec les sockets UDP en utilisant l’utilitaire netcat.

Pour vous connecter au socket UDP d’exemple sur le port 123 que vous avez créé dans la section précédente de ce tutoriel, exécutez la commande netcat suivante :

  1. nc -4 -u -vz 127.0.0.1 123
  • Le drapeau -4 indique à netcat d’utiliser IPv4.
  • L’option -u indique à netcat d’utiliser UDP au lieu de TCP.
  • Le drapeau -v est utilisé pour afficher une sortie détaillée sur votre terminal.
  • L’option -z garantit que netcat se connecte uniquement à un socket, sans envoyer de données.
  • L’adresse IP de bouclage locale 127.0.0.1 est utilisée car votre système aura sa propre adresse IP unique. Si vous connaissez l’IP de votre système, vous pouvez également effectuer un test avec celle-ci. Par exemple, si l’adresse IP publique ou privée de votre système est 203.0.113.1, vous pouvez l’utiliser à la place de l’adresse IP de bouclage.

Vous recevrez une sortie comme suit :

Output
Connection to 127.0.0.1 123 port [udp/ntp] succeeded!

La sortie indique que netcat n’a pas reçu d’erreur depuis le socket UDP en écoute sur l’adresse IPv4 de bouclage 127.0.0.1 sur le port 123. Ce manque de réponse d’erreur est utilisé pour déduire que le socket à 127.0.0.1:123 est disponible. Ce comportement est différent des sockets TCP, qui doivent échanger des paquets pour confirmer si un socket est disponible.

Remarque : Si le socket dans cet exemple n’était pas disponible, le système distant renverrait un message ICMP de type 3 (Destination inaccessible) avec un code 3, indiquant que le port est inaccessible sur l’hôte distant.

Déduire qu’un socket est disponible sur la base d’une absence de réponse d’erreur suppose qu’il n’y a pas de pare-feu ou de problèmes de connectivité bloquant le trafic ICMP. Sans envoyer, recevoir et vérifier les données d’application sur un socket UDP, il n’y a aucune garantie qu’un port UDP distant est ouvert et accepte les paquets.

Maintenant, vous pouvez répéter le même test de connexion mais en utilisant IPv6. Exécutez la commande netcat suivante :

  1. nc -6 -u -vz ::1 123

Vous devriez recevoir une sortie comme suit :

Output
Connection to ::1 123 port [udp/ntp] succeeded!!

La sortie indique que netcat n’a pas reçu d’erreur du socket UDP en écoute sur l’adresse IPv6 de boucle locale ::1 sur le port 123. Encore une fois, cette absence de réponse d’erreur est utilisée pour déduire que le socket à ::1:123 est disponible.

Pour nettoyer vos sockets, vous devrez exécuter la commande fg (premier plan) pour chaque processus socat que vous avez créé. Ensuite, vous utiliserez CTRL+C pour fermer chaque socat.

Exécutez fg pour ramener la deuxième instance IPv6 de socat au premier plan de votre terminal. Ensuite, exécutez CTRL+C pour le fermer.

  1. fg

Vous recevrez une sortie comme suit:

Output
sudo socat UDP6-LISTEN:123,ipv6only=1,fork /dev/null

Appuyez sur CTRL+C pour arrêter le processus.

Maintenant, exécutez à nouveau fg pour nettoyer le premier socket IPv4. Vous aurez une sortie comme suit:

Output
sudo socat UDP4-LISTEN:123,fork /dev/null

Appuyez sur CTRL+C pour arrêter le processus.

Vous avez maintenant créé, examiné et testé les sockets UDP IPv4 et IPv6 sur votre système. Essayez d’expérimenter avec chaque outil pour devenir plus familier avec la façon dont ils peuvent être utilisés pour tester et résoudre les problèmes de sockets UDP.

Qu’est-ce qu’un socket de domaine Unix?

Les programmes qui s’exécutent sur le même serveur peuvent également communiquer entre eux en utilisant les sockets de domaine Unix (UDS). Les sockets de domaine Unix peuvent être basés sur le flux ou basés sur les datagrammes. Lors de l’utilisation de sockets de domaine, les données sont échangées entre les programmes directement dans le noyau du système d’exploitation via des fichiers sur le système de fichiers hôte. Pour envoyer ou recevoir des données à l’aide de sockets de domaine, les programmes lisent et écrivent dans leur fichier de socket partagé, contournant entièrement les sockets et protocoles basés sur le réseau.

Les sockets de domaine Unix sont largement utilisés par les systèmes de bases de données qui n’ont pas besoin d’être connectés à une interface réseau. Par exemple, MySQL sur Ubuntu utilise par défaut un fichier nommé /var/run/mysqld/mysql.sock pour la communication avec les clients locaux. Les clients lisent et écrivent sur le socket, tout comme le serveur MySQL lui-même.

PostgreSQL est un autre système de base de données qui utilise un socket pour la communication locale, non réseau. En général, il utilise par défaut /run/postgresql/.s.PGSQL.5432 comme fichier de socket.

Création de sockets de domaine Unix

Dans les sections précédentes, vous avez exploré comment TCP est utilisé avec des sockets de flux, et comment UDP est utilisé avec des sockets de datagramme. Dans cette section, vous utiliserez socat pour créer à la fois des sockets Unix basés sur des flux et des datagrammes sans utiliser TCP ou UDP pour encapsuler les données à envoyer sur les réseaux. Ensuite, vous examinerez les sockets que vous créez en utilisant les commandes ss et nc. Enfin, vous apprendrez à tester les sockets Unix en utilisant netcat.

Pour commencer, exécutez les commandes socat suivantes pour créer deux fichiers de socket :

  1. socat unix-listen:/tmp/stream.sock,fork /dev/null&
  2. socat unix-recvfrom:/tmp/datagram.sock,fork /dev/null&
  • La première commande indique à socat de créer un socket en utilisant le type d’adresse unix-listen, ce qui créera un UDS basé sur un flux.
  • La deuxième commande spécifie unix-recvfrom comme type de socket, ce qui créera un UDS basé sur des datagrammes.
  • Les deux commandes spécifient un nom de fichier après le séparateur :. Le nom de fichier est l’adresse du socket lui-même. Pour le premier exemple de flux, il s’agit de /tmp/stream.sock et pour le deuxième exemple de datagramme, il s’agit de /tmp/datagram.sock. Notez que le nom d’un socket est arbitraire mais il est utile s’il est descriptif lorsque vous effectuez un dépannage.
  • Les arguments fork et /dev/null sont utilisés de la même manière que décrit dans les sections d’exemple de socket de flux et de datagramme.

Maintenant que vous avez créé vos deux sockets UDS, vous pouvez les examiner à l’aide des utilitaires ss et nc.

Examiner les sockets de domaine Unix

Pour répertorier tous les sockets de domaine Unix en écoute, exécutez la commande ss -xln. Le drapeau x garantit que seuls les sockets de domaine sont affichés.

  1. ss -xln

Vous recevrez une sortie comme suit:

Output
Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port Process . . . u_str LISTEN 0 5 /tmp/stream.sock 436470 * 0 u_dgr UNCONN 0 0 /tmp/datagram.sock 433843 * 0 . . .

Remarquez la partie u_str en surbrillance de la ligne /tmp/stream/sock. Ce champ indique que le type de socket est basé sur un flux (stream-based UDS). La deuxième ligne montre que le type est u_dgr, ce qui signifie que le type de socket est basé sur un datagramme (datagram-based).

Puisque les sockets de domaine Unix sont des fichiers, les autorisations utilisateur et groupe Linux habituelles ainsi que les contrôles d’accès peuvent être utilisés pour restreindre qui peut se connecter au socket. Vous pouvez également utiliser des outils de système de fichiers tels que ls, mv, chown et chmod pour examiner et manipuler les fichiers UDS. Des outils comme SELinux peuvent également être utilisés pour étiqueter les fichiers UDS avec différents contextes de sécurité.

Pour vérifier si un fichier est un socket UDS, utilisez les utilitaires ls, file ou stat. Cependant, il est important de noter que aucun de ces outils ne peut déterminer si un UDS est basé sur un flux ou un datagramme. Utilisez l’outil ss pour obtenir les informations les plus complètes sur un socket de domaine Unix.

Pour examiner un socket sur le système de fichiers, l’utilitaire stat affiche les informations les plus pertinentes. Exécutez-le sur les sockets que vous avez créés précédemment:

  1. stat /tmp/stream.sock /tmp/datagram.sock

Vous recevrez une sortie comme suit :

Output
File: /tmp/stream.sock Size: 0 Blocks: 1 IO Block: 131072 socket Device: 48h/72d Inode: 1742 Links: 1 Access: (0755/srwxr-xr-x) Uid: ( 0/ root) Gid: ( 0/ root) Access: 2021-03-01 18:10:25.025755168 +0000 Modify: 2021-03-01 18:10:25.025755168 +0000 Change: 2021-03-01 18:22:42.678231700 +0000 Birth: - File: /tmp/datagram.sock Size: 0 Blocks: 1 IO Block: 131072 socket Device: 48h/72d Inode: 1743 Links: 1 Access: (0755/srwxr-xr-x) Uid: ( 0/ root) Gid: ( 0/ root) Access: 2021-03-01 18:10:25.025755168 +0000 Modify: 2021-03-01 18:10:25.025755168 +0000 Change: 2021-03-01 18:10:25.025755168 +0000 Birth: -

Remarquez que pour chaque fichier, le type est socket (mis en évidence à l’extrême droite de la sortie) et le mode d’accès a un caractère s précédant les permissions du fichier.

L’utilitaire ls indiquera également si un fichier est un socket. Exécutez ls -l pour examiner les fichiers :

  1. ls -l /tmp/stream.sock /tmp/datagram.sock

Vous recevrez une sortie comme suit. Notez encore une fois que pour les sockets, le mode du fichier inclut le caractère s avant les champs d’autorisation du fichier :

Output
srwxr-xr-x 1 root root 0 Mar 1 18:10 /tmp/datagram.sock srwxr-xr-x 1 root root 0 Mar 1 18:10 /tmp/stream.sock

Maintenant que vous avez créé des sockets de domaine Unix et appris à les examiner à l’aide de ss et de divers outils basés sur le système de fichiers, la prochaine étape consiste à tester les sockets à l’aide d’un outil tel que netcat.

Tester les sockets de domaine Unix

L’utilitaire netcat peut être utilisé pour se connecter à des sockets de domaine Unix, ainsi qu’à des sockets TCP et UDP que vous avez déjà appris précédemment dans ce tutoriel. Pour vous connecter aux sockets d’exemple que vous avez créés, vous devrez spécifier un drapeau supplémentaire -U lors de l’exécution de la commande netcat. Ce drapeau indique à netcat de se connecter à un UDS, par opposition à un socket réseau basé sur TCP ou UDP.

De plus, si le socket est basé sur des datagrammes, vous utiliserez le drapeau -u pour indiquer à netcat d’utiliser des datagrammes comme nous l’avons appris dans la section sur les sockets de datagrammes de ce tutoriel.

Commençons par examiner les sockets UDS en se connectant au socket basé sur le flux avec la commande suivante :

  1. nc -U -z /tmp/stream.sock

L’option -U indique à netcat qu’il se connecte à un socket de domaine Unix.
L’option -z garantit que netcat ne se connecte qu’à un socket sans envoyer de données.
/tmp/stream.sock est l’adresse du socket sur le système de fichiers.

Vous ne recevrez aucune sortie de netcat lorsque vous exécutez la commande. Cependant, si un socket n’est pas disponible, netcat affichera un message d’erreur comme suit :

Output
nc: unix connect failed: No such file or directory nc: /tmp/stream.sock: No such file or directory

Donc, l’absence de sortie de netcat lors du test d’un socket UDS basé sur le flux signifie que la connexion a réussi.

Répétez le processus de test, cette fois-ci pour l’UDS basé sur le datagramme :

  1. nc -uU -z /tmp/datagram.sock

Le drapeau supplémentaire -u est ajouté pour indiquer à netcat que le socket distant est un socket de datagramme. Encore une fois, vous ne recevrez aucune sortie si le test est réussi.

S’il n’y a pas de socket à l’adresse, vous recevrez une erreur comme suit :

Output
nc: unix connect failed: No such file or directory nc: /tmp/datagram.sock: No such file or directory

Pour nettoyer vos sockets, vous devrez exécuter la commande fg (foreground) pour chaque processus socat que vous avez créé. Ensuite, vous utiliserez CTRL+C pour fermer chaque socat.

Exécutez fg pour mettre l’instance socat basée sur le datagramme au premier plan de votre terminal :

  1. fg

Vous recevrez une sortie comme suit :

Output
socat unix-recvfrom:/tmp/datagram.sock,fork /dev/null

Appuyez sur CTRL+C pour le fermer. Vous ne recevrez aucune sortie.

Maintenant, exécutez à nouveau fg pour nettoyer le premier socket UDS basé sur le flux.

Encore une fois, vous devriez avoir une sortie comme suit :

Output
socat unix-listen:/tmp/stream.sock,fork /dev/null

Exécutez CTRL+C pour mettre fin au processus. Vous ne recevrez aucune sortie.

Vous avez maintenant créé, examiné et testé les sockets de datagramme Unix sur votre système. Essayez d’expérimenter avec netcat et socat pour devenir plus familier avec la façon dont vous pouvez envoyer et recevoir des données sur un UDS, ainsi que la manière dont vous pouvez tester et dépanner les sockets de domaine Unix.

Conclusion

Dans ce tutoriel, vous avez exploré comment différents types de sockets sont utilisés sur un système Linux. Vous avez appris les sockets basés sur les flux, qui utilisent généralement TCP pour la communication réseau. Vous avez également appris les sockets basés sur les datagrammes, qui utilisent UDP pour envoyer des données sur les réseaux. Enfin, vous avez exploré comment les sockets de domaine Unix peuvent être soit basés sur des flux, soit basés sur des datagrammes sur un serveur local.

Dans chaque section, vous avez utilisé l’utilitaire ss pour recueillir des informations sur les sockets d’un système Linux. Vous avez appris comment les différents indicateurs fournis par l’outil ss peuvent vous aider à limiter sa sortie à des types spécifiques de sockets lorsque vous examinez les sockets sur un système.

Finalement, vous avez utilisé les outils netcat et socat pour créer et vous connecter à chacun des trois types de sockets différents abordés dans ce tutoriel. L’utilitaire netcat est largement utilisé pour se connecter aux sockets, mais il peut également créer des sockets. Sa documentation (man nc) contient de nombreux exemples de la manière dont il peut être utilisé dans l’un ou l’autre mode. L’utilitaire socat est un outil plus avancé qui peut être utilisé pour se connecter à de nombreux types de sockets différents qui ne sont pas couverts dans ce tutoriel. Sa documentation (man socat) contient également de nombreux exemples des différentes façons dont il peut être utilisé.

Comprendre ce que sont les sockets et comment ils fonctionnent est une compétence fondamentale en administration système. Les outils et techniques que vous avez expérimentés dans ce tutoriel vous aideront à devenir plus familier avec les sockets et comment les dépanner si vos serveurs et applications ne communiquent pas correctement entre eux.

Source:
https://www.digitalocean.com/community/tutorials/understanding-sockets