Réseau · Section 2
socket(2)
Crée un point de communication et renvoie un descripteur qui le référence.
Signature
#include <sys/socket.h>
int socket(int domain, int type, int protocol);- domain
- Famille de protocole : AF_INET, AF_INET6, AF_UNIX, AF_NETLINK, AF_PACKET, AF_VSOCK, AF_XDP, etc.
- type
- Sémantique. SOCK_STREAM (flux fiable), SOCK_DGRAM (datagramme), SOCK_RAW (IP brut), SOCK_SEQPACKET. OU avec SOCK_CLOEXEC et/ou SOCK_NONBLOCK pour positionner ces drapeaux à la création (évite la course fcntl).
- protocol
- Protocole précis dans la famille. 0 choisit le défaut — TCP pour SOCK_STREAM, UDP pour SOCK_DGRAM. Non-zéro pour SOCK_RAW (numéro de protocole IP) ou pour des valeurs L2/L3 spécifiques.
Description
socket() crée un point de communication réseau et renvoie un descripteur que les appels suivants (bind, connect, listen, accept, send, recv, sendto, recvfrom, shutdown, close) utilisent. domain choisit la famille de protocole — AF_INET / AF_INET6 pour IP, AF_UNIX pour l'IPC local, AF_NETLINK pour la messagerie noyau-utilisateur, AF_PACKET pour les trames brutes couche 2, AF_VSOCK pour les canaux hyperviseur-invité. type choisit la sémantique (flux, datagramme, brut, paquet séquencé), optionnellement OU avec SOCK_CLOEXEC et SOCK_NONBLOCK. protocol sélectionne un protocole précis dans la famille (0 pour le défaut — TCP pour SOCK_STREAM, UDP pour SOCK_DGRAM). Le fd retourné est ensuite configuré et utilisé comme tout autre.
Numéros par architecture
| Architecture | Numéro | ABI | Point d'entrée |
|---|---|---|---|
| x86 (i386) | 359 | i386 | sys_socket |
| x64 (x86_64) | 41 | common | sys_socket |
| ARM64 (aarch64) | 198 | — | sys_socket |
Historique noyau
Introduit dans Linux 1.0.
1.0
socket() est présent dans Linux depuis 1.0 avec l'API style BSD ; l'appel système original sur x86 passait par socketcall() (multiplexeur), raison pour laquelle i386 a encore socketcall(102) en plus de socket(359).
2.6.27
SOCK_CLOEXEC et SOCK_NONBLOCK ont été ajoutés pour positionner ces drapeaux de façon atomique à la création, supprimant les fenêtres de course qui imposaient auparavant un fcntl(F_SETFD/F_SETFL) séparé.
3.4
AF_VSOCK a été intégré pour fournir un canal hôte-invité indépendant de la configuration réseau. Largement utilisé par les outils conteneur/VM aujourd'hui.
5.6
AF_XDP a été livré pour donner à l'espace utilisateur un accès direct aux tampons de paquets via XDP, utilisé pour le réseau haute performance (alternatives DPDK, kernel-bypass avec BPF vérifié).
seccomp & conteneurs
Docker default profile
Autorisé
Podman default profile
Autorisé
socket() est autorisé par les profils Docker / Podman par défaut pour les familles standard. Le durcissement fort est le filtrage d'arguments : la plupart des charges n'ont besoin que de AF_INET, AF_INET6, AF_UNIX. Refuser AF_NETLINK (configuration), AF_PACKET (sniff), AF_VSOCK (canaux hôte), et AF_XDP (kernel-bypass) retire toute une classe de primitives post-exploitation sans casser le code applicatif. AppArmor et SELinux peuvent compléter avec des restrictions de type/peer, mais seccomp est le démarrage le moins cher.
libseccomp
// Allow only TCP/UDP over IPv4/IPv6; deny AF_PACKET, AF_NETLINK, AF_VSOCK, etc.
for (int af : { AF_INET, AF_INET6, AF_UNIX }) {
seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket),
1, SCMP_A0(SCMP_CMP_EQ, af));
}
seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EAFNOSUPPORT), SCMP_SYS(socket), 0);Exemple strace
$ strace -e socket,connect curl -s https://example.com -o /dev/null
socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = 3
connect(3, {sa_family=AF_UNIX, sun_path="/run/nscd/socket"}, 110) = -1 ENOENT
socket(AF_INET6, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, IPPROTO_TCP) = 5
connect(5, {sa_family=AF_INET6, sin6_port=htons(443), sin6_addr=…}, 28) = 0strace décode domain et type symboliquement (AF_INET, SOCK_STREAM|SOCK_CLOEXEC). Astuce de débogage réseau : `strace -e network -yy programme` affiche l'adresse résolue sur chaque fd socket. Pour distinguer DNS, TCP, UDP, observer la séquence — DNS apparaît comme socket() UDP + sendto() vers le port 53, puis socket() TCP + connect() vers l'IP résolue.
Sécurité & observabilité
socket() est la porte d'entrée de la reconnaissance et de l'exfiltration réseau. AF_PACKET permet le sniff intra-conteneur (CAP_NET_RAW requis, désactivé par défaut sous Docker) — alerter en cas de présence. AF_NETLINK est le chemin pour qu'un processus apprenne chaque interface et route de l'hôte ; les rootkits l'utilisent pour cartographier le réseau avant pivot. Le tracepoint eBPF sys_enter_socket capture domain/type/protocol ; corréler à /proc/<pid>/exe pour identifier le binaire. Pour la forensique conteneur, comparer les familles socket() utilisées à l'ensemble attendu de la charge est une base utile.
Erreurs
- EACCES
- Permission refusée pour le type/protocole demandé (par ex. SOCK_RAW sans CAP_NET_RAW).
- EAFNOSUPPORT
- La famille demandée n'est pas supportée par ce noyau ou est filtrée par seccomp.
- EINVAL
- —
- EMFILE
- Limite par processus de descripteurs atteinte.
- ENFILE
- Limite système de la table des fichiers atteinte.
- ENOBUFS
- Mémoire noyau insuffisante pour la nouvelle structure socket (épuisement du cache sk_buff).
- ENOMEM
- —
- EPROTONOSUPPORT
- Protocole non supporté dans la famille demandée.
Drapeaux
- AF_UNIX
- 1
- IPC local par sockets nommés sur le système de fichiers ou en espace abstrait. L'IPC le plus rapide sous Linux.
- AF_INET
- 2
- Sockets IPv4 — TCP, UDP, ICMP. Encore ~50% du trafic Internet ; ne pas supposer du v6 exclusif.
- AF_INET6
- 10
- Sockets IPv6. Avec IPV6_V6ONLY=0 (défaut) accepte connexions v4 et v6, simplifiant les serveurs dual-stack.
- AF_NETLINK
- 16
- Canal de contrôle noyau ↔ utilisateur. Utilisé par iproute2, audit, nfnetlink (pare-feu), et nombreux sous-systèmes.
- AF_PACKET
- 17
- Trames brutes couche 2. Requis pour tcpdump, dhclient, lldpd. Privilégié (CAP_NET_RAW).
- AF_VSOCK
- 40
- Communication virtio hyperviseur-invité. Utilisé par Firecracker, qemu virtio-vsock ; parfois pour RPC bac-à-sable vers hôte.
- AF_XDP
- 44
- —
- SOCK_STREAM
- 1
- Flux d'octets fiable, bidirectionnel, ordonné. TCP pour INET ; SCTP aussi.
- SOCK_DGRAM
- 2
- Non fiable, orienté message. UDP pour INET.
- SOCK_RAW
- 3
- —
- SOCK_SEQPACKET
- 5
- —
- SOCK_CLOEXEC
- 0x80000
- Positionne close-on-exec à la création de la socket. Indispensable contre les fuites de fd à travers execve().
- SOCK_NONBLOCK
- 0x800
- Positionne le drapeau non-bloquant à la création.