Forum général.général Socket

Posté par  . Licence CC By‑SA.
Étiquettes : aucune
1
23
juin
2020

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?

Titre de l'image

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  (site web personnel) . É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  (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 (type 127.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  . É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  . Évalué à 4.

          la réponse est dans ta question

          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 :/

          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  (site web personnel) . Évalué à 3.

            et qu'ils doivent pouvoir utiliser les droits UGO ou numériques 755 par exemple pour gérer qui peut lire/ecrire dedans

            À 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.

            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 :/

            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  . Évalué à 1.

              Tout cela me semble plus claire, merci beaucoup à tous pour vos explications :)

            • [^] # Re: Sockets UNIX?

              Posté par  . Évalué à 2.

              il n’y a pas de chemin privilégié qui autoriserait à « court-circuiter » la pile réseau.

              Ç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 :

              dd if=/dev/urandom bs=4k count=50k | time socat stdin unix-listen:@foo
              socat unix-connect:@foo stdio > /dev/null
              résultat :

              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
              versus :

              dd if=/dev/urandom bs=4k count=50k | time socat stdin tcp-listen:4242
              socat tcp-connect:localhost:4242 stdio > /dev/null
              résultat :

              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
              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.

              À 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.