5505 links
  • GuiGui's Show

  • Home
  • Login
  • RSS Feed
  • Tag cloud
  • Picture wall
  • Daily
Links per page: 20 50 100
page 1 / 1
  • Comment le mode promiscuous d'une carte réseau est activé par Linux ?

    Après avoir voulu me remémorer comment fonctionne une capture réseau du point de vue du noyau Linux, je me suis interrogé sur l'activation, en détail, du mode promiscuous.

    Définition

    Une carte réseau Ethernet fait remonter au système d'exploitation uniquement les trames Ethernet qui lui sont destinées. Le tri est opéré sur l'adresse MAC de destination. Sont conservés les paquets dont l'adresse MAC est celle de la carte réseau, l'adresse broadcast (FF:FF:FF:FF:FF:FF), ou l'une des adresses multicast (01:00:5E:XX:XX:XX pour IPv4, 33:33:XX:XX:XX:XX pour IPv6).

    Ce filtrage est effectué matériellement par la carte réseau.

    Le mode promiscuous permet de retirer ce filtrage, donc d'écouter tout ce qui passe sur le réseau.

    Bon, il faut relativiser :

    • À l'époque des réseaux équipés avec des hubs ou avec une topologie en bus, on recevait tout le trafic réseau de toutes les machines du réseau.

    • Sur les réseaux d'aujourd'hui, équipés avec des switchs, on reçoit uniquement le trafic destiné à la machine, broadcast, multicast ou autre (01:80:C2:XX:XX:FF pour LLDP / STP / IEEE1905, etc.). Le seul moment où un switch fait fuiter du trafic unicast, c'est quand il ne connaît pas l'association entre une adresse MAC et un port ou quand sa table de correspondance est pleine.


    Pratique

    Le mode promiscuous est global à une interface réseau : exécuter un tcpdump -p (on demande à ne pas activer le mode promiscuous) à côté d'un tcpdump (mode promiscuous activé) est vain : quel que soit l'ordre de lancement des commandes, le tcpdump -p verra les paquets qui ne sont pas destinés à la machine tant que le tcpdump (promiscuous) est en cours d'exécution.

    Voir si l'une des interfaces réseau du système est en mode promiscuous : ip -d l sh | grep -B 1 promiscuity. Si le nombre affiché est supérieur à 1, alors plusieurs applications (+ le noyau voir ligne suivante) ont activé le mode promiscuous.

    Activer le mode promiscuous sans passer par libpcap : sudo ip l set promisc on dev <INTERFACE>. Pour le désactiver : sudo ip l set promisc off dev <INTERFACE>.


    Promiscuous ne voit pas tout

    Le mode promiscuous ne permet pas de voir TOUT le trafic réseau adressé à la machine. Une carte réseau peut filtrer matériellement le trafic qu'elle juge invalide : toute trame 802.1Q quand aucun VLAN est configuré sur le système, trames réseaux trop courtes ou dont la somme de contrôle est incorrecte, etc.


    Linux filtre aussi

    Tous les paquets qui arrivent sur une interface configurée en mode promiscuous ne parviendront pas jusqu'aux logiciels "serveurs" en écoute, car le noyau fait le tri.

    Le tri le plus simple à mettre en évidence est que, si le transfert de paquets IP n'est pas activé (/proc/sys/net/ipv4/ip_forward = 0), alors tous les paquets IP dont l'adresse IP de destination n'est pas l'une des IPs de la machine (multicast inclus) seront détruits. Ils n'arriveront même pas jusqu'à la chaîne FORWARD de Netfilter/iptables. Il doit exister d'autres filtrages.


    Et donc, comment le mode promiscuous est activé par la libpcap ?

    Si l'on regarde le code, la libpcap (utilisée par tcpdump, wireshark, etc.) utilise la fonction système setsockopt() pour positionner l'option. Il ne reste plus qu'à remonter le code de Linux.

    • setsockopt() est une fonction implémentée pour chaque famille/protocole. Une socket libpcap est de type AF_PACKET / PF_PACKET, donc c'est la fonction packet_setsockopt() située dans le fichier net/packet/af_packet.c qui est utilisée. Elle appelle packet_mc_add() qui appelle packet_dev_mc(), toujours dans af_packet.c.
      • dev_set_promiscuity() dans net/core/dev.c est appelée et elle appelle __dev_set_promiscuity() toujours dans net/core/dev.c. On notera que c'est cette fonction qui journalise « device XXXX entered promiscuous mode » dans kern.log.
        • __dev_set_promiscuity() appelle dev_change_rx_flags() (toujours dans net/core/dev.c) qui appelle ndo_change_rx_flags. Le pilote peut implémenter une fonction (ou non) pour remplacer celle par défaut et l'enregistrer dans la structure netdev_ops de la structure net_device. Exemple : le pilote e1000e n'implémente pas cette fonction.

        • __dev_set_promiscuity() appelle dev_set_rx_mode() (toujours dans net/core/dev.c) qui appelle ndo_set_rx_mode(). Le pilote e1000e la remplace avec e1000e_set_rx_mode() (« .ndo_set_rx_mode = e1000e_set_rx_mode, ») dont le commentaire indique « e1000e_set_rx_mode - secondary unicast, Multicast and Promiscuous mode ». Cette fonction met à jour les registres de la carte réseau et, surtout, restaure+écrit les adresses multicast et unicast quand on sort du mode promiscuous.
    Sun Apr 18 17:06:58 2021 - permalink -
    - http://shaarli.guiguishow.info/?uTSqHg
Links per page: 20 50 100
page 1 / 1
Mentions légales identiques à celles de mon blog | CC BY-SA 3.0

Shaarli - The personal, minimalist, super-fast, database free, bookmarking service by the Shaarli community