IPv6 link-local tidak berfungsi melalui VPN: mengapa fe80 berhenti di tautan
Alamat fe80:: hanya bermakna pada satu tautan. Lihat mengapa VPN yang dirutekan tidak dapat membawanya, seperti apa kegagalannya, dan alamat mana yang sebaiknya dipakai.
Anda menyalakan terowongan, melakukan ping fe80::1 dengan terowongan sebagai antarmuka sumber, dan tidak ada yang kembali. Ini bukan aturan firewall yang Anda lupakan. Alamat link-local hanya bermakna pada satu tautan tempat ia dibentuk, dan VPN yang dirutekan bukanlah tautan itu. fe80::1 milik router jauh berada di segmen LAN jauh; Anda berada satu lompatan di segmen lain, dan IPv6 tidak memiliki mekanisme bagi router untuk meneruskan paket link-local sama sekali.
Prefiks fe80 menjelaskan cakupan, bukan rentang
Link-local unicast adalah fe80::/10, dan sifat yang menentukan bukanlah angkanya melainkan cakupannya. Alamat itu hanya berlaku pada satu tautan, dan setiap antarmuka membentuk satu dari pengenalnya sendiri, itulah sebabnya dua mesin yang tidak terkait di dua jaringan yang tidak terkait dapat sama-sama menjawab fe80::1 tanpa benturan sedikit pun. Prefiks itu pada dasarnya mengatakan “di suatu tautan”; tautannya sendiri datang dari konteks.
Pada host, konteks itu adalah zona, atau scope ID, yang Anda tambahkan setelah tanda persen: fe80::1%eth0 di Linux, fe80::1%3 atau fe80::1%12 di Windows dan di alat yang menampilkan indeks antarmuka. Kernel menyelesaikan alamat bersama indeks antarmuka lalu mengirim. Hilangkan zona itu dan tujuan menjadi ambigu, sehingga tumpukan tidak punya cara memilih segmen.
Mengapa terowongan yang dirutekan tidak dapat mengantarkannya
VPN yang dirutekan adalah antarmuka titik-ke-titik yang membawa alamatnya sendiri, biasanya /64 dari ruang IPv6 unique-local atau privat di dalam terowongan. LAN jauh adalah tautan terpisah, yang dicapai oleh titik ujung terowongan yang merutekan dan meneruskan atas nama Anda. Itu dua segmen berbeda, jadi alamat dari satu bukan tujuan yang sah di yang lain.
Aturan penerusan itu eksplisit dalam standar, bukan keanehan klien Anda: router tidak meneruskan paket dengan sumber atau tujuan link-local. Itulah sebabnya paket mati bahkan ketika tabel rute terlihat benar. Tambahkan rute untuk fe80::/64 yang menunjuk ke terowongan dan tumpukan yang patuh entah menolaknya atau menerimanya lalu menjatuhkan setiap paket yang cocok: cakupan tujuan mengatakan “hanya tautan ini”, dan antarmuka keluar bukan tautan itu.
Penemuan tetangga memperkuat batas yang sama. Host menyelesaikan lompatan berikutnya link-local dengan permintaan tetangga yang dikirim ke multicast bercakupan tautan dengan batas lompatan 255, sehingga router dapat menolak apa pun yang diteruskan. Membuatnya bekerja melintasi terowongan berarti memproksikan penemuan untuk segmen jauh, yaitu jembatan Layer 2 dengan topi berbeda.
Ada kegagalan kedua yang lebih senyap, dan itu menjebak orang yang tetap mencoba memaksa rutenya: zona. Zona apa pun yang Anda ketik secara lokal menamai antarmuka terowongan, sedangkan alamat yang Anda inginkan terikat ke antarmuka LAN jauh. Keduanya tidak pernah cocok, sehingga paket tidak dapat diarahkan ke antarmuka yang tepat di ujung jauh.
Seperti apa kegagalan itu dalam praktik
Keluaran alat untuk kesalahan cakupan terbaca seperti kesalahan perutean atau firewall, dan itulah tepatnya mengapa orang menghabiskan satu sore di lapisan yang salah.
| What you run | What you see | What it means |
|---|---|---|
| ping fe80::1 with no zone | Invalid argument on Linux, or a transmit failure on Windows | The stack cannot pick an interface for an ambiguous destination |
| ping -6 -I tun0 fe80::1 | Destination unreachable, or a silent timeout | The address is not on the tunnel link, so there is nothing on-link to answer |
| ssh user@fe80::1 after the tunnel is up | Hangs, then no route to host | The SYN never left the machine in a deliverable form; the server logs nothing |
| ip -6 neigh show dev tun0 | Empty table | No neighbor entry can exist for a link-local host that is not on this link |
| fe80::/64 inside AllowedIPs or route-ipv6 | Config accepted, traffic still dropped | The tunnel carried the packet; the receiving stack refused to forward it |
Baris ketiga paling banyak membuang waktu, karena klien ssh tanpa keluaran tampak seperti masalah layanan yang mendengarkan. Jika Anda punya cara masuk, periksa sisi jauh dan pastikan apakah sshd terikat ke semua alamat atau hanya satu.
Gunakan alamat yang memang dimaksudkan untuk dirutekan
Untuk apa pun yang perlu Anda jangkau melalui terowongan, gunakan alamat yang diberikan kepada layanan untuk tujuan itu: alamat unicast global, atau alamat unique-local dari fc00::/7, rentang yang dicadangkan tepat untuk kasus internal ini. Pastikan pendengar benar-benar mengikatnya, dan periksa jalur kembali serta aturan firewall host mana pun.
Lihat host jauh daripada menebak. ip -6 addr show mencantumkan alamat yang ada, dan ss -6 -ltn mencantumkan tempat daemon mendengarkan. Layanan yang hanya terikat ke fe80:: hanya dapat dijangkau dari segmennya sendiri, yang biasanya merupakan bawaan yang tidak dipilih siapa pun dengan sengaja dan dapat diubah dengan persetujuan administrator.
Ketika layanan benar-benar tidak dapat diikat ulang, naikkan jembatan ke lapisan aplikasi alih-alih lapisan jaringan. Relai di host jauh yang mendengarkan pada alamat yang dapat dirutekan dan terhubung ke alamat link-local menyelesaikan masalah tanpa memperluas segmen apa pun:
socat TCP6-LISTEN:8080,bind=[fd00:1:2::10] TCP6:[fe80::1%eth0]:80Di sini zona berada di sisi yang benar, pada host yang benar-benar memiliki eth0 pada tautan itu. Klien Anda berbicara dengan fd00:1:2::10, yang dirutekan secara normal, dan relai melakukan lompatan link-local secara lokal. Trik yang sama berlaku untuk antarmuka web perangkat atau BMC lama yang hanya mengiklankan alamat link-local.
Ketika penjembatanan memang jawabannya, dan apa yang harus diperiksa
Beberapa penerapan memang memerlukan satu segmen bersama: perangkat yang hanya berbicara penemuan link-local, peralatan yang bergantung pada multicast, laboratorium yang mereproduksi LAN datar. Itu masalah Layer 2 dan perlu jawaban Layer 2, seperti perangkat tap yang dijembatani ke antarmuka jauh atau produk klien dengan mode jembatan eksplisit. Itu memakan biaya lalu lintas broadcast dan multicast yang melintasi terowongan plus penemuan tetangga yang harus bekerja ujung ke ujung.
Jangan mendekatinya dengan menambahkan fe80::/64 ke profil yang dirutekan. Itu menghasilkan keadaan terburuk: konfigurasi tampak selesai, tabel rute menampilkan entri, dan setiap paket tetap dibuang di suatu tempat antara dua tumpukan yang keduanya berperilaku benar.
Verifikasi dengan antarmuka, bukan dengan ping. ip -6 addr show tun0 memberi tahu apakah tautan terowongan membentuk alamat link-local sendiri, dan ip -6 route get fe80::1%tun0 memberi tahu apa yang sebenarnya akan dilakukan kernel dengan tujuan bercakupan. Ketika kernel mengatakan tujuan tidak terjangkau pada antarmuka itu, tidak ada pengaturan terowongan yang akan mengubahnya, dan inilah saatnya berhenti menyunting profil.
Urutan singkat yang menyelesaikan pertanyaan:
- Baca alamat pada host jauh dan catat apakah itu fe80:: atau prefiks yang dapat dirutekan.
- Jika fe80::, ikat ulang layanan, relai di host itu, atau jembatani segmennya; jika dapat dirutekan, perbaiki rute, firewall, atau alamat ikat.
- Periksa ulang zona setiap kali Anda menguji ulang, karena perintah yang disalin biasanya mempertahankan antarmuka yang salah.