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 vnsfs
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 (danoustat -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 pronsenter
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
:jenstat
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émunsfs
. 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 (zdensfs
) 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 nansfs
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