GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Wie finde ich alle unter Linux konfigurierten Schnittstellen, auch die von Containern?

Eine Schnittstelle gehört zu einem bestimmten Zeitpunkt zu einem Netzwerknamensraum und nur zu einem. Der init (anfängliche) Netzwerk-Namespace hat außer dem Erben physischer Schnittstellen zerstörter Netzwerk-Namespaces keine besonderen Fähigkeiten gegenüber anderen Netzwerk-Namespaces:Er kann ihre Schnittstellen nicht direkt sehen. Solange Sie sich noch in den PID- und Mount-Namespaces von init befinden, können Sie die Netzwerk-Namespaces immer noch finden, indem Sie verschiedene Informationen verwenden, die von /proc verfügbar sind und zeigen schließlich ihre Schnittstellen an, indem Sie diese Netzwerk-Namespaces eingeben.

Ich werde Beispiele in der Shell bereitstellen.

  • Zählen Sie die Netzwerk-Namespaces auf

    Dazu müssen Sie wissen, wie diese Namespaces existieren:solange eine Ressource sie aufrechterhält. Eine Ressource kann hier ein Prozess (eigentlich ein Thread eines Prozesses), ein Einhängepunkt oder ein offener Dateideskriptor (fd) sein. Diese Ressourcen werden alle in /proc/ referenziert und auf eine abstrakte Pseudodatei im nsfs zeigen Pseudo-Dateisystem, das alle Namespaces auflistet. Die einzige aussagekräftige Information dieser Datei ist ihr Inode, der den Netzwerknamensraum darstellt, aber der Inode kann nicht allein manipuliert werden, es muss die Datei sein. Deshalb können wir später nicht einfach nur den Inode-Wert behalten (gegeben durch stat -c %i /proc/some/file ):Wir behalten den Inode, um Duplikate und entfernen zu können einen Dateinamen, um noch eine brauchbare Referenz für nsenter zu haben später.

    • Prozess (eigentlich Thread)

      Der häufigste Fall:für übliche Container. Der Netzwerknamensraum jedes Threads kann über die Referenz /proc/pid/ns/net bekannt sein :nur stat sie und listen alle eindeutigen Namespaces auf. Die 2>/dev/null ist zu verstecken, wenn stat kann keine ephemeren Prozesse mehr finden.

      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
      

      Mit dem spezialisierten lsns geht das schneller Befehl, der sich mit Namespaces befasst, aber scheinbar nur Prozesse behandelt (keine Einhängepunkte oder open fd, wie später zu sehen ist):

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

      (was später in lsns -n -u -t net -o NS,PATH | while read inode path; do printf '%20u %s\n' $inode "$path"; done umformatiert werden müsste )

    • Einhängepunkt

      Diese werden hauptsächlich von ip netns add verwendet Befehl, der permanente Netzwerk-Namespaces erstellt, indem er sie einhängt, wodurch verhindert wird, dass sie verschwinden, wenn es keinen Prozess oder keine fd-Ressource gibt, die sie aufrechterhält, und es dann beispielsweise auch ermöglicht, einen Router, eine Firewall oder eine Bridge in einem Netzwerk-Namespace ohne einen verknüpften Prozess auszuführen.

      Gemountete Namespaces (die Handhabung von Mount- und vielleicht PID-Namespaces ist wahrscheinlich komplexer, aber wir interessieren uns sowieso nur für Netzwerk-Namespaces) erscheinen wie jeder andere Mount-Punkt in /proc/mounts , mit dem Dateisystemtyp nsfs . In der Shell gibt es keine einfache Möglichkeit, einen Netzwerk-Namespace von einem anderen Namespace-Typ zu unterscheiden, aber da zwei Pseudodateien aus demselben Dateisystem (hier nsfs ) nicht denselben Inode verwenden, wählen Sie einfach alle aus und ignorieren Sie Fehler später im Schnittstellenschritt, wenn Sie versuchen, eine Nicht-Netzwerk-Namespace-Referenz als Netzwerk-Namespace zu verwenden. Tut mir leid, unten werde ich Einhängepunkte mit Sonderzeichen, einschließlich Leerzeichen, nicht korrekt handhaben, da sie bereits in /proc/mounts maskiert sind 's Ausgabe (in jeder anderen Sprache wäre es einfacher), also werde ich mich auch nicht darum kümmern, nullterminierte Zeilen zu verwenden.

      awk '$3 == "nsfs" { print $2 }' /proc/mounts | while read -r mount; do
              stat -c '%20i %n' "$mount"
      done
      
    • Dateideskriptor öffnen

      Diese sind wahrscheinlich noch seltener als Einhängepunkte, außer vorübergehend bei der Namespace-Erstellung, können aber von einer spezialisierten Anwendung gehalten und verwendet werden, die mehrere Namespaces handhabt, einschließlich möglicherweise einiger Containerisierungstechnologie.

      Ich könnte mir keine bessere Methode ausdenken, als alle fd zu durchsuchen, die in jedem /proc/pid/fd/ verfügbar sind , verwenden Sie stat, um zu überprüfen, ob es auf nsfs zeigt Namespace und kümmert sich jetzt wieder nicht darum, ob es sich wirklich um einen Netzwerk-Namespace handelt. Ich bin mir sicher, dass es eine optimiertere Schleife gibt, aber diese wird zumindest nicht überall herumwandern oder eine maximale Prozessgrenze annehmen.

      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
      

    Entfernen Sie nun alle doppelten Netzwerk-Namespace-Referenzen aus den vorherigen Ergebnissen. ZB durch Verwendung dieses Filters auf die kombinierte Ausgabe der 3 vorherigen Ergebnisse (insbesondere aus dem offenen Dateideskriptorteil):

    sort -k 1n | uniq -w 20
    
  • Zählen Sie in jedem Namensraum die Schnittstellen auf

    Jetzt haben wir die Verweise auf alle existierenden Netzwerk-Namensräume (und auch einige Nicht-Netzwerk-Namensräume, die wir einfach ignorieren werden), geben Sie einfach jeden von ihnen unter Verwendung der Referenz ein und zeigen Sie die Schnittstellen an.

    Verwenden Sie die Ausgabe der vorherigen Befehle als Eingabe für diese Schleife, um Schnittstellen aufzulisten (und wählen Sie gemäß der Frage von OP, ihre Adressen anzuzeigen), während Sie Fehler ignorieren, die durch Nicht-Netzwerk-Namespaces verursacht werden, wie zuvor erläutert:

    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
    

Der Inode des Init-Netzwerks kann mit PID 1 als Referenz ausgegeben werden:

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

Beispielausgabe (echt, aber redigiert) mit einem laufenden LXC-Container, einem leeren "gemounteten" Netzwerk-Namespace, der mit ip netns add ... erstellt wurde mit einer unverbundenen Bridge-Schnittstelle, einem Netzwerk-Namensraum mit einem anderen dummy0 Schnittstelle, die von einem nicht Prozess am Leben erhalten wird in diesem Netzwerk-Namespace, aber ein offenes fd darauf, erstellt mit:

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 &

und ein laufender Firefox, der jeden seiner "Web Content"-Threads in einem unverbundenen Netzwerk-Namespace isoliert (alle diese unten lo Schnittstellen):

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. So finden Sie die Liste aller offenen Ports in Linux heraus

  2. So finden Sie das Paket, das eine bestimmte Datei in Linux bereitstellt

  3. So finden Sie alle Sudo-Benutzer in Linux

  4. Alle Dateien erhalten, die an einem bestimmten Datum geändert wurden?

  5. Wie finde ich alle Dateien, die einem bestimmten Benutzer in Unix/Linux gehören?

So finden Sie heraus, welche Geräte in Linux mit dem Netzwerk verbunden sind

So finden Sie eine Datei in Linux rekursiv in allen Verzeichnissen

So ermitteln Sie den Verbindungsstatus eines Netzwerkkabels in Linux

So finden Sie verfügbare Netzwerkschnittstellen unter Linux

So finden Sie heraus, welche Grafikkarte Sie unter Linux haben

So finden Sie alle installierten Schriftarten in Linux