GNU/Linux >> Tutoriels Linux >  >> Linux

Comment retrouver toutes les interfaces qui ont été configurées sous Linux, y compris celles des conteneurs ?

Une interface, à un instant donné, appartient à un espace de noms réseau et à un seul. L'espace de noms réseau init (initial), sauf pour hériter des interfaces physiques des espaces de noms réseau détruits, n'a aucune capacité spéciale sur les autres espaces de noms réseau :il ne peut pas voir directement leurs interfaces. Tant que vous êtes toujours dans les espaces de noms pid et mount d'init, vous pouvez toujours trouver les espaces de noms réseau en utilisant différentes informations disponibles à partir de /proc et enfin afficher leurs interfaces en saisissant ces espaces de noms réseau.

Je vais fournir des exemples en shell.

  • énumérer les espaces de noms réseau

    Pour cela, vous devez savoir comment ces espaces de noms existent :tant qu'une ressource les maintient. Une ressource ici peut être un processus (en fait un thread de processus), un point de montage ou un descripteur de fichier ouvert (fd). Ces ressources sont toutes référencées dans /proc/ et pointe vers un pseudo-fichier abstrait dans le nsfs pseudo-système de fichiers énumérant tous les espaces de noms. La seule information significative de ce fichier est son inode, représentant l'espace de noms du réseau, mais l'inode ne peut pas être manipulé seul, il doit s'agir du fichier. C'est pourquoi plus tard nous ne pouvons pas garder uniquement la valeur de l'inode (donnée par stat -c %i /proc/some/file ) :nous conserverons l'inode pour pouvoir supprimer les doublons et un nom de fichier pour avoir encore une référence utilisable pour nsenter plus tard.

    • processus (en fait thread)

      Le cas le plus courant :pour les contenants usuels. L'espace de noms réseau de chaque thread peut être connu via la référence /proc/pid/ns/net  :juste stat eux et énumérer tous les espaces de noms uniques. Le 2>/dev/null est de se cacher quand stat ne trouve plus les processus éphémères.

      find /proc/ -mindepth 1 -maxdepth 1 -name '[1-9]*' | while read -r procpid; do
              stat -L -c '%20i %n' $procpid/ns/net
      done 2>/dev/null
      

      Cela peut être fait plus rapidement avec le lsns spécialisé commande qui traite des espaces de noms, mais semble ne gérer que les processus (pas les points de montage ni les fd ouverts comme on le verra plus tard) :

      lsns -n -u -t net -o NS,PATH
      

      (qui devra être reformaté pour plus tard en lsns -n -u -t net -o NS,PATH | while read inode path; do printf '%20u %s\n' $inode "$path"; done )

    • point de montage

      Ceux-ci sont principalement utilisés par le ip netns add commande qui crée des espaces de noms réseau permanents en les montant, évitant ainsi qu'ils ne disparaissent lorsqu'aucun processus ni ressource fd ne les maintient, puis permettant également par exemple d'exécuter un routeur, un pare-feu ou un pont dans un espace de noms réseau sans aucun processus lié.

      Les espaces de noms montés (la gestion des espaces de noms mount et peut-être pid est probablement plus complexe, mais nous ne nous intéressons de toute façon qu'aux espaces de noms réseau) apparaissent comme n'importe quel autre point de montage dans /proc/mounts , avec le type de système de fichiers nsfs . Il n'y a pas de moyen facile en shell de distinguer un espace de noms réseau d'un autre type d'espace de noms, mais puisque deux pseudo-fichiers du même système de fichiers (ici nsfs ) ne partageront pas le même inode, élisez-les tous et ignorez les erreurs plus tard dans l'étape d'interface lorsque vous essayez d'utiliser une référence d'espace de noms non réseau comme espace de noms réseau. Désolé, ci-dessous, je ne gérerai pas correctement les points de montage contenant des caractères spéciaux, y compris des espaces, car ils sont déjà échappés dans /proc/mounts (ce serait plus facile dans n'importe quel autre langage), donc je ne m'embêterai pas non plus à utiliser des lignes terminées par null.

      awk '$3 == "nsfs" { print $2 }' /proc/mounts | while read -r mount; do
              stat -c '%20i %n' "$mount"
      done
      
    • ouvrir le descripteur de fichier

      Ceux-ci sont probablement encore plus rares que les points de montage, sauf temporairement lors de la création de l'espace de noms, mais peuvent être détenus et utilisés par une application spécialisée gérant plusieurs espaces de noms, y compris éventuellement une technologie de conteneurisation.

      Je ne pouvais pas concevoir une meilleure méthode que de rechercher tous les fd disponibles dans chaque /proc/pid/fd/ , en utilisant stat pour vérifier qu'il pointe vers un nsfs espace de noms et encore une fois ne pas se soucier pour l'instant s'il s'agit vraiment d'un espace de noms réseau. Je suis sûr qu'il existe une boucle plus optimisée, mais celle-ci au moins ne se promènera pas partout et n'assumera aucune limite de processus maximale.

      find /proc/ -mindepth 1 -maxdepth 1 -name '[1-9]*' | while read -r procpid; do
              find $procpid/fd -mindepth 1 | while read -r procfd; do
                      if [ "$(stat -f -c %T $procfd)" = nsfs ]; then
                              stat -L -c '%20i %n' $procfd 
                      fi
              done
      done 2>/dev/null
      

    Supprimez maintenant toutes les références d'espace de noms réseau en double des résultats précédents. Par exemple en utilisant ce filtre sur la sortie combinée des 3 résultats précédents (notamment de la partie descripteur de fichier ouvert) :

    sort -k 1n | uniq -w 20
    
  • dans chaque espace de noms, énumérez les interfaces

    Nous avons maintenant les références à tous les espaces de noms réseau existants (ainsi qu'à certains espaces de noms non réseau que nous allons simplement ignorer), entrez simplement chacun d'eux en utilisant la référence et affichez les interfaces.

    Prenez la sortie des commandes précédentes comme entrée dans cette boucle pour énumérer les interfaces (et selon la question de l'OP, choisissez d'afficher leurs adresses), tout en ignorant les erreurs causées par les espaces de noms non réseau comme expliqué précédemment :

    while read -r inode reference; do
        if nsenter --net="$reference" ip -br address show 2>/dev/null; then
                printf 'end of network %d\n\n' $inode
        fi
    done
    

L'inode du réseau init peut être imprimé avec le pid 1 comme référence :

echo -n 'INIT NETWORK: ' ; stat -L -c %i /proc/1/ns/net

Exemple de sortie (réel mais expurgé) avec un conteneur LXC en cours d'exécution, un espace de nom de réseau "monté" vide créé avec ip netns add ... ayant une interface de pont non connectée, un espace de noms réseau avec un autre dummy0 interface, maintenue en vie par un processus pas dans cet espace de noms réseau mais en gardant un fd ouvert dessus, créé avec :

unshare --net sh -c 'ip link add dummy0 type dummy; ip address add dev dummy0 10.11.12.13/24; sleep 3' & sleep 1; sleep 999 < /proc/$!/ns/net &

et un Firefox en cours d'exécution qui isole chacun de ses threads "Contenu Web" dans un espace de noms réseau non connecté (tous ceux en panne lo interfaces):

lo               UNKNOWN        127.0.0.1/8 ::1/128 
eth0             UP             192.0.2.2/24 2001:db8:0:1:bc5c:95c7:4ea6:f94f/64 fe80::b4f0:7aff:fe76:76a8/64 
wlan0            DOWN           
dummy0           UNKNOWN        198.51.100.2/24 fe80::108a:83ff:fe05:e0da/64 
lxcbr0           UP             10.0.3.1/24 2001:db8:0:4::1/64 fe80::216:3eff:fe00:0/64 
virbr0           DOWN           192.168.122.1/24 
virbr0-nic       DOWN           
[email protected]   UP             fe80::fc8e:ff:fe85:476f/64 
end of network 4026531992

lo               DOWN           
end of network 4026532418

lo               DOWN           
end of network 4026532518

lo               DOWN           
end of network 4026532618

lo               DOWN           
end of network 4026532718

lo               UNKNOWN        127.0.0.1/8 ::1/128 
[email protected]        UP             10.0.3.66/24 fe80::216:3eff:fe6a:c1e9/64 
end of network 4026532822

lo               DOWN           
bridge0          UNKNOWN        fe80::b884:44ff:feaf:dca3/64 
end of network 4026532923

lo               DOWN           
dummy0           DOWN           10.11.12.13/24 
end of network 4026533021

INIT NETWORK: 4026531992

Linux
  1. Obtenir tous les fichiers qui ont été modifiés à une date précise ?

  2. Comment trouver tous les fichiers appartenant à un utilisateur spécifique sous Unix/Linux ?

  3. Comment trouver tous les fichiers de plus de 1 Go sous Linux ?

  4. Comment trouver tous les fichiers/dossiers avec la permission 777 sous Linux ?

  5. Comment trouver tous les fichiers épars sous Linux

Comment trouver les périphériques connectés au réseau sous Linux

Comment connaître l'état de connexion d'un câble réseau sous Linux

Comment trouver les interfaces réseau disponibles sous Linux

Comment trouver quelle carte graphique avez-vous sous Linux ?

Comment trouver toutes les polices installées sous Linux

Comment lister tous les fichiers d'une partition sous Linux ?