Semantik :: dan 0.0.0.0 dalam OS dual-stack

10

Kembali pada hari-hari IPv4 saja, koneksi LISTEN yang ditampilkan netstatsebagai mendengarkan 0.0.0.0akan menanggapi koneksi pada antarmuka IPv4 dalam sistem.

Seperti yang saya pahami, idiom IPv6 yang baru ::mendengarkan semua antarmuka IPv6 dan IPv4 yang tersedia. Apakah ini benar, untuk semua OS (Unix, Windows, Mac)? Apakah ada idiom untuk mendengarkan hanya pada antarmuka IPv6?

Alex J
sumber

Jawaban:

17

Sayangnya, ini berbeda tergantung pada sistem operasi apa yang Anda gunakan.

Di Microsoft Windows, mengikat soket ::hanya mengikat ke port IPv6. Jadi untuk mendengarkan semua alamat di kedua IPv4 dan IPv6, Anda harus mengikat 0.0.0.0juga ::. Ekstrak berikut ini dari kotak Vista:

C:\>netstat -an | find "445"
  TCP    0.0.0.0:445            0.0.0.0:0              LISTENING
  TCP    [::]:445               [::]:0                 LISTENING

Contoh yang saya berikan adalah port 445, digunakan untuk lalu lintas SMB ketika NetBIOS tidak digunakan. Seperti yang Anda lihat, itu mengikat keduanya 0.0.0.0dan ::membuat, masing-masing, baik klien IPv4 dan IPv6 bekerja.

Di Linux, ::sudah termasuk alamat yang kompatibel dengan IPv4, seperti yang sudah Anda tebak, sehingga mengikat 0.0.0.0juga tidak perlu. Saya menulis program Python sederhana yang hanya mengikat ke AF_INET6soket ::. Meskipun saya juga tidak mengikat ke AF_INETsoket (IPv4), ia masih menerima koneksi dari klien IPv4. Jika, katakanlah, 10.1.1.3terhubung ke sana, itu akan muncul sebagai terhubung dari ::ffff:10.1.1.3.

Kecuali bahwa itu menjadi berbulu. Di atas tidak berlaku di Linux jika /proc/sys/net/ipv6/bindv6onlydiatur ke 1, dalam hal perilaku persis sama dengan Windows - mengikat ::hanya akan mendengarkan permintaan IPv6. Jika Anda ingin mendengarkan permintaan IPv4 juga, Anda harus membuat AF_INETsoket dan mendengarkan 0.0.0.0juga. Untungnya, default untuk bindv6onlyadalah 0, jadi ada kemungkinan sangat kecil Anda harus berurusan dengan ini (kecuali jika Anda menggunakan Debian, yang sebenarnya default untuk bindv6only = 1).

Semua ini berguna untuk diketahui dalam memeriksa untuk melihat apakah suatu layanan diaktifkan IPv6, dan apakah itu juga mendukung IPv4. Ini server SSH saya:

$ netstat -64ln | grep 22
tcp6    0    0 :::22    :::*    LISTEN

Seperti yang Anda lihat, SSH hanya mendengarkan pada ::port 22. Namun, ini bukan hanya mendengarkan klien IPv6 - ini berfungsi dengan baik dari klien IPv4, karena pengikatan yang kompatibel dengan IPv4. Untuk membuktikan ini, jika Anda melihat ini:

$ cat /proc/sys/net/ipv6/bindv6only 
0

bindv6onlydinonaktifkan (default). Jika itu diatur 1, maka saya harus mendorong SSH untuk mendengarkan 0.0.0.0juga (atau sebaliknya).

Permintaan maaf karena tidak memiliki informasi tentang sisi Mac OS X. Saya telah menggunakannya di masa lalu, tetapi saya lebih suka estetika GNOME, jadi saya belum menggunakannya dalam waktu yang sangat lama. Namun, saya kira perilaku itu sama dengan Linux.

Semoga ini membantu.

Jeremy Visser
sumber
4

Ini tidak mungkin, karena segmen ruang alamat IPv6 sama dengan ruang IPv4, jadi meskipun Anda bisa menonaktifkan soket IPv4, Anda masih dapat mengirim paket IPv4 ke soket IPv6. Periksa bagian transisi IPv4 di halaman wikipedia IPv4 .

Sunting: Ah, sedikit lebih jauh ke bawah dikatakan:

Beberapa tumpukan IPv6 umum tidak mendukung fitur alamat IPv4 yang dipetakan, baik karena tumpukan IPv6 dan IPv4 adalah implementasi terpisah (Microsoft Windows sebelum Vista / Longhorn: mis. XP / 2003), atau karena masalah keamanan (OpenBSD). Pada sistem operasi ini, perlu untuk membuka soket terpisah untuk setiap protokol IP yang akan didukung. Pada beberapa sistem (mis. Linux, NetBSD, FreeBSD) fitur ini dikendalikan oleh opsi soket IPV6_V6ONLY seperti ditentukan dalam RFC 3493
David Pashley
sumber
-1

Anda mungkin dapat melakukannya dengan ID jaringan Anda, AAAA: BBBB: CCCC: DDDD :: atau apa pun itu untuk Anda. Itu akan menjamin bahwa hanya antarmuka IPv6 yang akan mengambilnya. Kupikir. Saya bukan master IPv6.

Matt Simmons
sumber