GNU/Linux >> Znalost Linux >  >> Linux

Jak najdu všechna rozhraní, která byla nakonfigurována v Linuxu, včetně rozhraní kontejnerů?

Rozhraní v daném čase patří do jednoho síťového jmenného prostoru a pouze do jednoho. Počáteční (počáteční) síťový jmenný prostor, s výjimkou zdědění fyzických rozhraní zničených síťových jmenných prostorů, nemá žádnou zvláštní schopnost oproti jiným síťovým jmenným prostorům:nemůže přímo vidět jejich rozhraní. Dokud jste stále v init pid a mount jmenných prostorech, stále můžete najít síťové jmenné prostory pomocí různých informací dostupných z /proc a nakonec zobrazit jejich rozhraní zadáním těchto síťových jmenných prostorů.

Příklady poskytnu v shellu.

  • vyjmenujte jmenné prostory sítě

    K tomu musíte vědět, jak tyto jmenné prostory existují:pokud je zdroj udržuje. Zdroj zde může být proces (ve skutečnosti vlákno procesu), bod připojení nebo deskriptor otevřeného souboru (fd). Všechny tyto zdroje jsou uvedeny v /proc/ a ukažte na abstraktní pseudosoubor v nsfs pseudo-souborový systém s výčtem všech jmenných prostorů. Jedinou smysluplnou informací tohoto souboru je jeho inode, který představuje síťový jmenný prostor, ale s inodem nelze manipulovat samostatně, musí to být soubor. Proto později nemůžeme ponechat pouze hodnotu inodu (danou stat -c %i /proc/some/file ):ponecháme inode, abychom mohli odstraňovat duplikáty a název souboru, aby měl stále použitelnou referenci pro nsenter později.

    • proces (ve skutečnosti vlákno)

      Nejběžnější případ:pro běžné nádoby. Síťový jmenný prostor každého vlákna lze znát pomocí odkazu /proc/pid/ns/net :jen stat a vyjmenujte všechny jedinečné jmenné prostory. 2>/dev/null je skrýt, když stat už nemůže najít efemérní procesy.

      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
      

      To lze provést rychleji pomocí specializovaného lsns příkaz, který se zabývá jmennými prostory, ale zdá se, že zpracovává pouze procesy (nikoli přípojné body ani neotevírá fd, jak je vidět později):

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

      (který by musel být později přeformátován jako lsns -n -u -t net -o NS,PATH | while read inode path; do printf '%20u %s\n' $inode "$path"; done )

    • bod připojení

      Ty jsou většinou používány ip netns add příkaz, který vytváří trvalé síťové jmenné prostory jejich připojováním, čímž se vyhne jejich zmizení, když je nedrží žádný proces ani fd zdroj, a také umožňuje například spouštět router, firewall nebo most v síťovém jmenném prostoru bez jakéhokoli propojeného procesu.

      Připojené jmenné prostory (zpracování jmenných prostorů mount a možná pid je pravděpodobně složitější, ale stejně nás zajímají pouze síťové jmenné prostory) se v /proc/mounts objevují jako jakýkoli jiný přípojný bod. , s typem souborového systému nsfs . V shellu neexistuje snadný způsob, jak odlišit síťový jmenný prostor od jiného typu jmenného prostoru, ale protože dva pseudosoubory ze stejného souborového systému (zde nsfs ) nebude sdílet stejný inode, stačí je vybrat všechny a ignorovat chyby později v kroku rozhraní při pokusu použít jako síťový jmenný prostor odkaz na jiný než síťový jmenný prostor. Je nám líto, níže nebudu správně zpracovávat připojovací body se speciálními znaky, včetně mezer, protože jsou již zakódovány v /proc/mounts výstup 's (v jakémkoli jiném jazyce by to bylo jednodušší), takže se ani nebudu obtěžovat používat řádky zakončené nulou.

      awk '$3 == "nsfs" { print $2 }' /proc/mounts | while read -r mount; do
              stat -c '%20i %n' "$mount"
      done
      
    • otevřít deskriptor souboru

      Ty jsou pravděpodobně ještě vzácnější než přípojné body, kromě dočasných při vytváření jmenného prostoru, ale mohou být drženy a používány nějakou specializovanou aplikací, která zpracovává více jmenných prostorů, včetně možná nějaké technologie kontejnerizace.

      Nemohl jsem vymyslet lepší metodu než prohledat všechny dostupné fd v každé /proc/pid/fd/ , pomocí statistik ověřte, že ukazuje na nsfs jmenný prostor a opět se zatím nestarám, jestli je to opravdu síťový jmenný prostor. Jsem si jistý, že existuje více optimalizovaná smyčka, ale tato se alespoň nebude potulovat všude a nebude předpokládat žádný maximální limit procesu.

      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
      

    Nyní odstraňte všechny duplicitní odkazy na síťový jmenný prostor z předchozích výsledků. Např. použitím tohoto filtru na kombinovaném výstupu 3 předchozích výsledků (zejména z otevřené části deskriptoru souboru):

    sort -k 1n | uniq -w 20
    
  • v každém jmenném prostoru vyjmenujte rozhraní

    Nyní máme odkazy na všechny existující síťové jmenné prostory (a také některé nesíťové jmenné prostory, které budeme prostě ignorovat), jednoduše zadejte každý z nich pomocí odkazu a zobrazte rozhraní.

    Vezměte výstup předchozích příkazů jako vstup do této smyčky pro výčet rozhraní (a podle otázky OP zvolte zobrazení jejich adres), přičemž ignorujte chyby způsobené nesíťovými jmennými prostory, jak bylo vysvětleno dříve:

    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
    

Inode init sítě lze vytisknout s pid 1 jako referenci:

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

Příklad (skutečného, ​​ale redigovaného) výstupu se spuštěným kontejnerem LXC, prázdným „připojeným“ síťovým jmenným prostorem vytvořeným pomocí ip netns add ... mající nepřipojené mostové rozhraní, síťový jmenný prostor s jiným dummy0 rozhraní, udržované při životě procesem ne v tomto síťovém jmenném prostoru, ale ponechat na něm otevřený fd, vytvořený pomocí:

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 &

a běžící Firefox, který izoluje každé ze svých vláken „webového obsahu“ do nepřipojeného síťového jmenného prostoru (všechny pod lo rozhraní):

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. Jak najít soubor v Linuxu ve všech adresářích rekurzivně

  2. Jak najít všechny uživatele Sudo v Linuxu

  3. Jak najít všechny soubory vlastněné konkrétním uživatelem v Unixu/Linuxu?

  1. Jak zjistit seznam všech otevřených portů v Linuxu

  2. Jak najít všechny soubory končící na .rb s Linuxem?

  3. Jak v Linuxu najdu všechny soubory obsahující konkrétní text?

  1. Získání všech souborů, které byly upraveny ke konkrétnímu datu?

  2. Linux – Jak přesměrovat provoz mezi linuxovými síťovými jmennými prostory?

  3. Jak najít všechny soubory větší než 1 GB v Linuxu?