GNU/Linux >> Linux の 問題 >  >> Linux

コンテナーのインターフェースを含め、Linux で構成されているすべてのインターフェースを見つけるにはどうすればよいですか?

インターフェースは、ある時点で 1 つのネットワーク名前空間にのみ属します。 init (初期) ネットワーク名前空間は、破棄されたネットワーク名前空間の物理インターフェースを継承することを除いて、他のネットワーク名前空間に対して特別な能力を持っていません:それらのインターフェースを直接見ることはできません。 init の pid および mount 名前空間にいる限り、/proc から入手できるさまざまな情報を使用して、ネットワークの名前空間を見つけることができます。 最後に、これらのネットワーク名前空間を入力してインターフェイスを表示します。

シェルで例を示します。

  • ネットワーク名前空間を列挙する

    このためには、それらの名前空間がどのように存在するかを知る必要があります:リソースがそれらを維持している限り。ここでのリソースは、プロセス (実際にはプロセスのスレッド)、マウント ポイント、または開いているファイル記述子 (fd) です。これらのリソースはすべて /proc/ で参照されています nsfs 内の抽象的な疑似ファイルをポイントします。 すべての名前空間を列挙する疑似ファイルシステム。このファイルの唯一の意味のある情報は、ネットワークの名前空間を表す inode だけですが、inode は単独では操作できず、ファイルでなければなりません。そのため、後で inode 値 (stat -c %i /proc/some/file で指定) だけを保持することはできません。 ):重複を削除できるように inode を保持します and nsenter の使用可能な参照を保持するためのファイル名

    • プロセス (実際にはスレッド)

      最も一般的なケース:通常のコンテナーの場合。各スレッドのネットワーク名前空間は、参照 /proc/pid/ns/net を介して知ることができます :stat だけ それらをすべて列挙し、すべての一意の名前空間を列挙します。 2>/dev/null stat のときに非表示にする 一時的なプロセスはもう見つかりません。

      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
      

      これは、特殊化された lsns を使用するとより高速に実行できます 名前空間を処理しますが、プロセスのみを処理するように見えます (後で見られるように、マウント ポイントやオープン fd は処理しません):

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

      (後で lsns -n -u -t net -o NS,PATH | while read inode path; do printf '%20u %s\n' $inode "$path"; done として再フォーマットする必要があります) )

    • マウントポイント

      これらは主に ip netns add によって使用されます それらをマウントすることによって永続的なネットワーク名前空間を作成するコマンド。したがって、それらを維持するプロセスや fd リソースがない場合にそれらが消えるのを回避し、たとえば、リンクされたプロセスなしでネットワーク名前空間でルーター、ファイアウォール、またはブリッジを実行することもできます。

      マウントされた名前空間 (mount およびおそらく pid 名前空間の処理はおそらくもっと複雑ですが、とにかくネットワーク名前空間にのみ関心があります) は /proc/mounts の他のマウント ポイントのように見えます 、ファイルシステム タイプ nsfs .シェルでネットワーク名前空間を他のタイプの名前空間と区別する簡単な方法はありませんが、同じファイルシステムからの 2 つの疑似ファイル (ここでは nsfs ) は同じ inode を共有しません。それらをすべて選択し、ネットワーク名前空間としてネットワーク以外の名前空間参照を使用しようとしたときに、後でインターフェイス ステップでエラーを無視します。申し訳ありませんが、スペースを含む特殊文字を含むマウント ポイントは、/proc/mounts で既にエスケープされているため、正しく処理しません。 の出力 (他の言語の方が簡単です) であるため、null で終了する行を使用する必要はありません。

      awk '$3 == "nsfs" { print $2 }' /proc/mounts | while read -r mount; do
              stat -c '%20i %n' "$mount"
      done
      
    • ファイル記述子を開く

      これらはおそらく、名前空間の作成時を除いてマウント ポイントよりもさらにまれですが、コンテナ化テクノロジなど、複数の名前空間を処理する特殊なアプリケーションによって保持および使用される可能性があります。

      /proc/pid/fd/ ごとに利用可能なすべての fd を検索するよりも良い方法を考案できませんでした 、統計を使用して、それが nsfs を指していることを確認します 名前空間であり、それが本当にネットワーク名前空間であるかどうかは今のところ気にしません。より最適化されたループがあると確信していますが、これは少なくともどこでもさまよいませんし、プロセスの最大制限を想定することもありません.

      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
      

    ここで、以前の結果から重複したネットワーク名前空間の参照をすべて削除します。たとえば、前の 3 つの結果 (特に、開いているファイル記述子の部分) を組み合わせた出力に対してこのフィルターを使用すると、次のようになります。

    sort -k 1n | uniq -w 20
    
  • 各名前空間でインターフェースを列挙します

    これで、すべての既存のネットワーク名前空間 (および無視するいくつかの非ネットワーク名前空間) への参照が得られました。参照を使用してそれぞれを入力し、インターフェイスを表示するだけです。

    前のコマンドの出力をこのループへの入力として取り、インターフェイスを列挙します (そして、OP の質問に従って、それらのアドレスを表示することを選択します)。ただし、前に説明したように、ネットワーク以外の名前空間によって引き起こされたエラーは無視します:

    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
    

init ネットワークの inode は、参照として pid 1 で出力できます:

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

実行中の LXC コンテナ、ip netns add ... で作成された空の「マウントされた」ネットワーク名前空間の出力例 (実際の編集済み) 接続されていないブリッジ インターフェイス、他の dummy0 を持つネットワーク名前空間を持つ ないプロセスによって維持されるインターフェース このネットワーク名前空間にあるが、開いている fd を保持し、以下で作成:

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 &

そして 接続されていないネットワーク名前空間で「Web コンテンツ」スレッドのそれぞれを分離する実行中の Firefox (すべてダウン lo インターフェイス):

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. Linux – Linuxネットワークの名前空間間でトラフィックを転送する方法は?

  2. Unix / Linuxで特定のユーザーが所有するすべてのファイルを見つける方法は?

  3. Linux ですべてのスパース ファイルを見つける方法

  1. Linuxですべてのディレクトリのファイルを再帰的に検索する方法

  2. 利用可能なネットワーク インターフェイスを見つけるにはどうすればよいですか?

  3. Linuxでパーティションのすべてのファイルを一覧表示する方法は?

  1. Linuxで特定のファイルを提供するパッケージを見つける方法

  2. LinuxですべてのSudoユーザーを見つける方法

  3. 特定の日に変更されたすべてのファイルを取得しますか?