GNU/Linux >> Belajar Linux >  >> Linux

Bagaimana cara menemukan semua antarmuka yang telah dikonfigurasi di Linux, termasuk dari wadah?

Antarmuka, pada waktu tertentu, milik satu ruang nama jaringan dan hanya satu. Namespace jaringan init (awal), kecuali untuk mewarisi antarmuka fisik dari namespace jaringan yang dihancurkan tidak memiliki kemampuan khusus dibandingkan namespace jaringan lain:ia tidak dapat melihat langsung antarmuka mereka. Selama Anda masih dalam pid init dan me-mount ruang nama, Anda masih dapat menemukan ruang nama jaringan dengan menggunakan berbagai informasi yang tersedia dari /proc dan akhirnya tampilkan antarmuka mereka dengan memasukkan ruang nama jaringan tersebut.

Saya akan memberikan contoh di shell.

  • menghitung ruang nama jaringan

    Untuk ini, Anda harus tahu bagaimana ruang nama itu ada:selama sumber daya mempertahankannya. Sumber daya di sini dapat berupa proses (sebenarnya utas proses), titik pemasangan, atau deskriptor file terbuka (fd). Sumber daya tersebut semuanya dirujuk dalam /proc/ dan arahkan ke file pseudo abstrak di nsfs pseudo-filesystem menghitung semua ruang nama. Satu-satunya informasi yang berarti dari file ini adalah inode-nya, yang mewakili ruang nama jaringan, tetapi inode tidak dapat dimanipulasi sendiri, harus berupa file. Itu sebabnya nanti kita tidak bisa hanya menyimpan nilai inode saja (diberikan oleh stat -c %i /proc/some/file ):kami akan menyimpan inode untuk dapat menghapus duplikat dan nama file agar tetap memiliki referensi yang dapat digunakan untuk nsenter nanti.

    • proses (sebenarnya utas)

      Kasus paling umum:untuk wadah biasa. Namespace jaringan setiap utas dapat diketahui melalui referensi /proc/pid/ns/net :cukup stat mereka dan menghitung semua ruang nama yang unik. 2>/dev/null adalah menyembunyikan kapan stat tidak dapat menemukan proses sesaat lagi.

      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
      

      Ini dapat dilakukan lebih cepat dengan lsns khusus perintah yang berurusan dengan ruang nama, tetapi tampaknya hanya menangani proses (bukan mount point atau buka fd seperti yang terlihat nanti):

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

      (yang harus diformat ulang untuk nanti sebagai lsns -n -u -t net -o NS,PATH | while read inode path; do printf '%20u %s\n' $inode "$path"; done )

    • titik pemasangan

      Itu sebagian besar digunakan oleh ip netns add perintah yang membuat ruang nama jaringan permanen dengan memasangnya, sehingga menghindarinya menghilang ketika tidak ada proses atau sumber daya fd yang mempertahankannya, kemudian juga memungkinkan misalnya untuk menjalankan router, firewall, atau jembatan di ruang nama jaringan tanpa proses yang ditautkan.

      Ruang nama yang dipasang (menangani mount dan mungkin ruang nama pid mungkin lebih rumit tetapi kami hanya tertarik pada ruang nama jaringan) muncul seperti titik pemasangan lainnya di /proc/mounts , dengan tipe sistem file nsfs . Tidak ada cara mudah di shell untuk membedakan namespace jaringan dari tipe namespace lain, tetapi karena dua file pseudo dari sistem file yang sama (di sini nsfs ) tidak akan berbagi inode yang sama, cukup pilih semuanya dan abaikan kesalahan nanti di langkah antarmuka saat mencoba menggunakan referensi namespace non-jaringan sebagai namespace jaringan. Maaf, di bawah ini saya tidak akan menangani dengan benar titik pemasangan dengan karakter khusus di dalamnya, termasuk spasi, karena sudah di-escape di /proc/mounts output (akan lebih mudah dalam bahasa lain), jadi saya tidak akan repot-repot menggunakan baris yang diakhiri null.

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

      Itu bahkan mungkin lebih jarang daripada titik pemasangan kecuali untuk sementara saat pembuatan namespace, tetapi mungkin dipegang dan digunakan oleh beberapa aplikasi khusus yang menangani beberapa ruang nama, termasuk mungkin beberapa teknologi penampung.

      Saya tidak bisa menemukan metode yang lebih baik daripada mencari semua fd yang tersedia di setiap /proc/pid/fd/ , menggunakan stat untuk memverifikasi bahwa itu mengarah ke nsfs namespace dan sekali lagi tidak peduli sekarang apakah itu benar-benar namespace jaringan. Saya yakin ada loop yang lebih dioptimalkan, tetapi yang ini setidaknya tidak akan berkeliaran di mana-mana atau menerima batas proses maksimum apa pun.

      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
      

    Sekarang hapus semua referensi namespace jaringan duplikat dari hasil sebelumnya. Misalnya dengan menggunakan filter ini pada keluaran gabungan dari 3 hasil sebelumnya (terutama dari bagian deskriptor file terbuka):

    sort -k 1n | uniq -w 20
    
  • di setiap ruang nama sebutkan antarmuka

    Sekarang kita memiliki referensi ke semua ruang nama jaringan yang ada (dan juga beberapa ruang nama non-jaringan yang akan kita abaikan saja), cukup masukkan masing-masing menggunakan referensi dan tampilkan antarmuka.

    Ambil keluaran perintah sebelumnya sebagai input ke loop ini untuk menghitung antarmuka (dan sesuai pertanyaan OP, pilih untuk menampilkan alamatnya), sambil mengabaikan kesalahan yang disebabkan oleh ruang nama non-jaringan seperti yang dijelaskan sebelumnya:

    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 jaringan init dapat dicetak dengan pid 1 sebagai referensi:

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

Contoh keluaran (nyata tetapi disunting) dengan wadah LXC yang sedang berjalan, namepace jaringan "terpasang" kosong yang dibuat dengan ip netns add ... memiliki antarmuka jembatan yang tidak terhubung, ruang nama jaringan dengan dummy0 lainnya antarmuka, tetap hidup dengan proses bukan di ruang nama jaringan ini tetapi tetap membuka fd di atasnya, dibuat dengan:

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 &

dan Firefox yang sedang berjalan yang mengisolasi setiap utas "Konten Web" di ruang nama jaringan yang tidak terhubung (semuanya turun lo antarmuka):

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 – Bagaimana Cara Meneruskan Lalu Lintas Antara Ruang Nama Jaringan Linux?

  2. Bagaimana Menemukan Semua File yang Dimiliki oleh Pengguna Tertentu di Unix/Linux?

  3. Bagaimana menemukan semua file yang diakhiri dengan .rb dengan Linux?

  1. Bagaimana cara menemukan semua file yang berisi teks tertentu di Linux?

  2. Bagaimana saya bisa menemukan antarmuka jaringan yang tersedia?

  3. Bagaimana cara mendaftar semua file partisi di linux?

  1. Cara Menemukan File Di Linux Di Semua Direktori Secara Rekursif

  2. Cara Menemukan Paket Yang Menyediakan File Tertentu Di Linux

  3. Mendapatkan Semua File Yang Telah Dimodifikasi Pada Tanggal Tertentu?