Bonjour à tous !
Je suis actuellement en train de déployer un logiciel de scanning de vulnérabilité. Ce logiciel est composé de différents éléments qui doivent échanger entre eux, certains vont être utilisé localement et d'autres vont devoir être accessible à distance (comme par exemple le client web). La configuration de ces différents composants permet les échanges soit à travers des sockets, soit à travers un port TCP. Ma question arrive donc ici : quels sont les facteurs qui pourraient influencer le choix entre un socket ou un port TCP (sachant que je prône le côté sécurisation de l'infrastructure)? J'ai entendu que les socket étaient uniquement accessible en localhost, cela est-il vrai?
Je ne sais pas trop si j'ai bien expliqué mon questionnement, n'hésitez pas à me demande de réexpliquer.
Merci d'avance à ceux qui sauront éclairer ma lanterne :)
# Sockets UNIX?
Posté par gouttegd . Évalué à 3.
Est-ce que par “socket”, tu entends “sockets unix” ? Si oui, en effet les sockets unix sont uniquement accessibles depuis la machine locale. Du coup si certains composants doivent être accessibles à distance, ça règle la question…
(Sinon, ta question est confuse parce qu’en réalité, pour utiliser un port TCP tu utilises aussi une socket, simplement d’un type différent — AF_INET pour une socket TCP et AF_UNIX pour une socket unix.)
[^] # Re: Sockets UNIX?
Posté par Cyril Brulebois (site web personnel) . Évalué à 3.
Pour compléter un tout petit peu, une socket UNIX est accessible en connaissant son chemin dans l'arborescence locale.
Tandis qu'une socket
AF_INET
/AF_INET6
(disons « internet ») sera en général exposée via un port TCP ou UDP, qui peut être limité à une écoute locale (type127.0.0.1
) ou distante (avec une IP donnée, ou en écoutant sur toute IP). Ces dernières peuvent ensuite être firewallées à coup d'iptables
/nftables
ou autre surcouche.Debian Consultant @ DEBAMAX
[^] # Re: Sockets UNIX?
Posté par Rewen . Évalué à 1.
Merci à vous deux pour votre réponse 🙂
Je parlais en effet d'un socket Unix, je suis débutant à ce sujet, je me suis donc mal exprimé, je m'en excuse 😉
Je me demande donc quelle serait la meilleure solution à utiliser pour les composants qui doivent être joignable localement ( si possible le plus sécurisé ). J'ai l'impression qu'en général les socket Unix sont plus souvent utilisé pour ce logiciel mais je ne saurais dire pourquoi :/
Merci !
[^] # Re: Sockets UNIX?
Posté par NeoX . Évalué à 4.
la réponse est dans ta question
justement parce qu'il ne sont joignables QUE localement
et qu'ils doivent pouvoir utiliser les droits UGO ou numériques 755 par exemple pour gérer qui peut lire/ecrire dedans
[^] # Re: Sockets UNIX?
Posté par gouttegd . Évalué à 3.
À ce sujet, il faut noter que la page de manuel de unix(7) sous GNU/Linux semble erronée. Elle indique que la prise en compte des permissions de fichier sur la socket ne serait pas spécifiée par POSIX et qu’un programme portable ne devrait pas compter dessus (“POSIX does not make any statement about the effect of the permissions on a socket file, and on some systems, the socket permissions are ignored. Portable programs should not rely on this feature for security.”).
Cela semble clairement faux car le standard POSIX indique bien que les fonctions qui écrivent sur des sockets renvoient EACCES en cas de défaut de droit d’écriture sur la socket. Une rapide vérification montre que tous les *BSD modernes (e.g. Free-, Net-, Open-BSD) par exemple implémentent ce comportement, pas seulement GNU/Linux.
Une autre raison possible est que pour des communications strictement locales, les sockets Unix sont plus performantes, au moins en principe (dans les faits je ne suis pas certain que la différence soit réellement notable, à moins que le volume des communications ne soit particulièrement élevé).
En effet, sur la plupart des systèmes, les messages échangés à travers une socket AF_INET passent à travers toute la pile réseau, avec tout l’overhead que ça implique : même dans le cas où la socket n’est liée qu’à une adresse locale (et donc jamais en contact avec un « vrai » réseau), il n’y a pas de chemin privilégié qui autoriserait à « court-circuiter » la pile réseau.
À l’inverse, les messages échangés à travers une socket Unix ont un chemin beaucoup plus simple.
[^] # Re: Sockets UNIX?
Posté par Rewen . Évalué à 1.
Tout cela me semble plus claire, merci beaucoup à tous pour vos explications :)
[^] # Re: Sockets UNIX?
Posté par benoar . Évalué à 2.
Ça dépend ce que tu appelles « court-circuiter » : tout ce qui est à destination d'une adresse bindée localement passe par l'interface loopback (pas seuleument 127/8 et ::1). Les perfs ne sont pas si mauvaises :
résultat :dd if=/dev/urandom bs=4k count=50k | time socat stdin unix-listen:@foo
socat unix-connect:@foo stdio > /dev/null
versus :51200+0 enregistrements lus
51200+0 enregistrements écrits
209715200 octets (210 MB, 200 MiB) copiés, 5,37172 s, 39,0 MB/s
socat stdin unix-listen:foo 0,14s user 0,71s system 14% cpu 5,874 total
résultat :dd if=/dev/urandom bs=4k count=50k | time socat stdin tcp-listen:4242
socat tcp-connect:localhost:4242 stdio > /dev/null
J'ai certes une vitesse divisée par deux dans le cas TCP, mais avec une utilisation CPU instantanée moindre, et au final un temps user+system similaire pour les deux cas.51200+0 enregistrements lus
51200+0 enregistrements écrits
209715200 octets (210 MB, 200 MiB) copiés, 12,1192 s, 17,3 MB/s
socat stdin tcp-listen:4242 0,09s user 0,66s system 5% cpu 12,622 total
À noter que l'API, en dehors de la création de socket et du bind/connect, est strictement identique : il y a juste un changement de famille et de nom à effectuer. Et l'avantage d'utiliser AF_INET(6), c'est que le nom peut aussi bien être local (avec l'optimisation que j'évoque) ou bien distant, sans rien changer au code, juste au nom auquel se connecter, ou sur lequel se binder.
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.