Menumpuk klien OpenVPN kedua di satu host Linux gagal di salah satu dari dua tempat. Entah klien dalam tidak dapat menjangkau servernya sendiri karena terowongan luar telah menangkap transport tersebut, atau klien kedua menulis ulang tabel rute dan terowongan pertama berhenti berfungsi. Kedua masalah berada pada perutean, bukan enkripsi, dan keduanya diselesaikan sebelum terowongan baru membawa lalu lintas aplikasi apa pun. Alamat di sini bersifat ilustratif: tun0 adalah terowongan luar, 203.0.113.9 adalah server dalam, dan TCP 9999 adalah aliran yang harus memakai jalur dalam.

Dua mode kegagalan, satu tabel rute

Klien dalam membuka soket UDP ke servernya, dan soket itu mengikuti tabel rute saat ini seperti soket lain. Jika terowongan luar sudah memiliki rute default, paket handshake masuk ke terowongan luar. Itu hanya berhasil bila server luar dapat menjangkau server dalam dan sisi seberang bersedia membawa aliran tersebut; jika tidak, handshake macet dan klien mencoba lagi.

Kegagalan kedua berasal dari push server. Push yang biasa adalah redirect-gateway def1, yang memasang 0.0.0.0/1 dan 128.0.0.0/1 alih-alih mengganti rute default. Dua klien yang masing-masing memasang pasangan /1 miliknya sendiri karena itu bertabrakan, dan pasangan terbaru menang untuk hampir semua tujuan. Periksa kedua prefiks itu di tabel ketika terowongan mati setelah yang kedua tersambung, karena rute default itu sendiri mungkin tidak pernah berubah.

Tandai aliran dan beri ia tabel

Arahkan lalu lintas terpilih dengan menandainya di tabel mangle dan mencocokkan tanda itu di aturan kebijakan. Aturan menunjuk ke tabel khusus yang rute default-nya adalah perangkat dalam, sehingga hanya paket bertanda yang menempuh jalur dalam.

iptables -t mangle -A PREROUTING -p tcp -m multiport --dport 9999 -j MARK --set-mark 0x9999
ip rule add fwmark 0x9999 table 200 pref 1000
ip route add default dev tun1 table 200

Sebagian besar kegagalan dalam kumpulan aturan ini berasal dari dua kesalahan. Nilai tanda yang dipasang firewall dan nilai yang dicocokkan aturan harus identik, karena ketidakcocokan tidak menghasilkan galat maupun efek. Dan PREROUTING hanya melihat paket yang datang dari luar, jadi koneksi yang dimulai di host ini memerlukan aturan OUTPUT dengan pencocokan yang sama sebelum ditandai sama sekali.

Ambil alih kepemilikan rute dari klien kedua

Dua opsi mencegah klien kedua menyunting tabel, dan keduanya bekerja di titik berbeda. route-nopull mengabaikan opsi rute yang didorong, sehingga tidak ada yang dipasang. route-noexec menerima opsi yang didorong ke lingkungan klien tetapi menyerahkan perubahan tabel kepada hook, dan itulah yang Anda inginkan ketika perlu melihat apa yang ditawarkan server.

Hook berjalan dengan nilai yang didorong di lingkungannya, dan seharusnya hanya menambahkan entri yang Anda setujui. Buatlah idempoten: kosongkan tabel yang dimilikinya sebelum membangun ulang, dan jangan menganggap jalannya sebelumnya meninggalkan keadaan bersih. Penyambungan ulang memanggil hook lagi, dan hook yang menambahkan tanpa membersihkan akan menumpuk rute duplikat.

Pilih satu pemilik dan catat. Profil yang menyetel kedua opsi, atau hook yang bersaing dengan skrip manual, menghasilkan tabel yang tidak dapat dijelaskan siapa pun nanti.

Kunci kedua alamat server

Server dalam memerlukan rute host melalui perangkat luar sebelum klien dalam tersambung. Entri itulah yang menjaga transport dalam tetap di dalam terowongan luar alih-alih membiarkannya mengikuti rute default.

ip route add 203.0.113.9/32 dev tun0
ip route get 203.0.113.9

Tambahkan juga rute host yang cocok untuk server luar di tabel utama, atau penyambungan ulang dapat merutekan transport klien luar itu sendiri ke dalam terowongannya sendiri. Urutannya tidak opsional: tambahkan entri ini setelah antarmuka terkait ada, artinya hook atau skrip yang berjalan pasca-sambung. Rute yang menunjuk ke perangkat yang mati dihapus atau diabaikan, jadi entri yang ditulis saat boot tidak bertahan melewati urutan yang Anda asumsikan.

Periksa pencarian alih-alih membaca seluruh tabel. Keluaran pencarian rute menyebutkan perangkat dan alamat sumber yang akan dipakai kernel, dan itulah tepatnya yang didapat klien ketika membuka soketnya.

Uji rangkaian dan buat kegagalan terlihat

Tangkap pada antarmuka luar saat klien dalam tersambung. Handshake dalam seharusnya tampil sebagai muatan terenkripsi di dalam terowongan luar; jika tampil sebagai UDP polos ke 203.0.113.9, rute host hilang dan rangkaian tidak pernah terbangun.

Rangkaian yang diam-diam kembali ke uplink fisik adalah hasil terburuk, karena keadaan antarmuka tidak mengumumkan apa pun dan lalu lintas dalam keluar dari alamat sumber yang salah. Jika klien kedua dapat menyambung ulang secara langsung saat terowongan luar putus, nonaktifkan jalur itu atau ikat ke antarmuka luar agar kegagalannya terlihat.

Akhiri dengan dua aliran dan satu dump aturan: koneksi bertanda dan yang tidak bertanda seharusnya menempuh jalur berbeda, dan ip rule show seharusnya mendaftar prioritas yang Anda maksudkan. Jika kedua aliran menempuh jalur yang sama, tanda tidak diterapkan di tempat yang Anda kira.

Artikel terkait