Tiga host Linux, satu rancangan: hub OpenVPN yang dapat dijangkau publik, laptop konsumen, dan mesin pintu keluar di balik router rumah biasa yang tidak meneruskan apa pun ke dalam. Pintu keluar menghubungi hub sendiri. Lalu lalu lintas internet konsumen masuk ke terowongan di laptop dan keluar melalui uplink milik pintu keluar. Semua yang mengejutkan dalam tatanan ini berasal dari satu detail: pintu keluarlah yang memulai koneksi, jadi jalur ke dalam sudah ada dan tidak perlu port forward untuk membuatnya.

Uraian berikut menelusuri jalur paket, bukan urutan konfigurasi, karena konfigurasi baru masuk akal setelah Anda tahu komponen mana yang memegang keputusan mana. Setiap lapisan memegang tepat satu keputusan, dan kesalahan menumpuk di tempat dua lapisan dianggap satu.

Dua sesi transport, satu jalur dalam

Setiap host menyimpan koneksi luarnya sendiri ke hub, dan tak satu pun dari koneksi itu tahu tentang yang lain. Lalu lintas konsumen ke internet adalah aliran dalam yang terpisah, yang kebetulan dibawa di dalam terowongan konsumen lalu dipancarkan ulang dari terowongan pintu keluar. Aliran dalam itulah yang harus dirutekan hub, dan itulah yang harus diteruskan pintu keluar.

outer: consumer --TLS--> hub
outer: exit     --TLS--> hub
inner: consumer --tun--> hub --internal--> exit --tun--> uplink

Karena kedua koneksi luar berangkat dari sisi klien, router pintu keluar tidak pernah melihat SYN masuk dan tidak pernah perlu aturan NAT tujuan. Ia hanya perlu menjaga transport yang sudah terbentuk tetap hidup, yang sudah dilakukannya untuk koneksi berumur panjang apa pun. Tidak ada apa pun di internet publik yang perlu mencapai pintu keluar lebih dulu, itulah sebabnya alamat dinamis pada uplink itu bukan masalah. Router tetap harus mengizinkan sesi keluar, tetapi itu izin yang sama dengan yang sudah dipakai peramban.

Apa yang sebenarnya dipasang iroute di dalam server

Hub adalah satu-satunya perangkat yang memutuskan peer mana memiliki tujuan mana, dan keputusan itu diambilnya di tabel routing ruang pengguna miliknya sendiri, bukan di tabel kernel. Entri client-config-dir untuk pintu keluar bernama exit-node dapat mengklaim prefiks bawaan di sana:

# /etc/openvpn/server/ccd/exit-node
iroute 0.0.0.0 0.0.0.0

Baris itu memberi tahu proses server "paket dalam dengan tujuan apa pun milik klien ini". Baris itu tidak menambahkan rute bawaan ke sistem operasi hub dan tidak menjadikan hub gateway internet. Referensi OpenVPN 2.6 menjaga routing internal khusus klien dan routing kernel sebagai mekanisme terpisah, dan pemisahan itulah alasan rancangan ini bekerja tanpa menyentuh rute bawaan hub.

Konsumen memerlukan instruksi cermin, yang dikirim sebagai push, agar lalu lintasnya sendiri masuk ke terowongan alih-alih keluar lewat gateway lokalnya. Dengan topologi subnet, pool adalah rute terhubung pada perangkat tun pintu keluar, jadi arah balik tidak memerlukan push tambahan; yang tidak boleh diterima pintu keluar adalah pengalihan di bawah, yang akan mengirim lalu lintas uplinknya sendiri kembali ke terowongan yang hendak dipakainya. Kirimkan hanya ke konsumen dan bacalah rute yang diterapkan pada klien alih-alih percaya bahwa berkas CCD sudah dipilih.

# /etc/openvpn/server/ccd/consumer-01
push "redirect-gateway def1"

Kernel pintu keluarlah yang meneruskan

Di dalam pintu keluar, paket dari konsumen tiba di antarmuka tun dengan alamat suatu host internet. Kernel memeriksa tabel routingnya, menemukan uplink sebenarnya sebagai kecocokan terbaik, lalu menerapkan dua kebijakan yang independen: bolehkah paket ini diteruskan sama sekali, dan bolehkah ia keluar lewat antarmuka itu dengan alamat sumber itu. Penerusan adalah sysctl, dan di banyak distribusi mati secara bawaan.

Jadi pintu keluar memerlukan penerusan IPv4 yang aktif secara tetap, aturan penerusan yang mengizinkan sumber terowongan konsumen menuju uplink, dan jalur balasan kembali lewat tun. Mengaktifkan penerusan untuk seluruh host juga mengubah perilaku apa pun yang dirutekan melaluinya, karena itu aturannya harus menyebut sumber dan antarmuka alih-alih menerima semuanya.

Jalur balik dibeli oleh penerjemahan sumber

Host internet tidak memiliki rute ke alamat 10.90.0.x, jadi balasan akan dibuang sebelum pernah mencapai pintu keluar. Menulis ulang sumber saat paket meninggalkan uplink menyelesaikan itu, dan pelacakan koneksi membalik penulisan ulang itu di jalur kembali.

sysctl -w net.ipv4.ip_forward=1
iptables -t nat -A POSTROUTING -s 10.90.0.0/24 -o enp1s0 -j MASQUERADE
ip -4 route get 10.90.0.9   # run on the exit: must point at the tun

Aturan di atas adalah titik awal untuk satu antarmuka uplink, bukan kebijakan firewall. Persempit sumber ke penetapan yang benar-benar Anda izinkan, dan pisahkan kebijakan masukan pintu keluar sendiri agar penyamaran untuk lalu lintas terowongan tidak diam-diam membuka layanan lokal. Pada host dengan alamat uplink dinamis, penyamaran juga membebaskan Anda dari melacak alamat secara manual.

Di mana hub dapat menegakkan dan di mana tidak

Dengan client-to-client dan jalur data ruang pengguna tradisional, hub menyerahkan paket dalam antarpir di dalam proses server. Paket itu tidak pernah melintasi rantai FORWARD kernel hub, jadi aturan kernel di sana tidak dapat membatasi transit antarpir, seberapa pun cermat ditulisnya. Penegakan harus hidup dalam kebijakan server itu sendiri: siapa yang boleh terhubung, berkas CCD mana yang diterimanya, dan apakah kepemilikan bawaan pintu keluar diberikan sama sekali.

Itulah sebabnya iroute bawaan adalah keputusan kepercayaan yang luas. Pintu keluar harus menerima secara sah lalu lintas balik dari alamat internet mana pun, dan ia harus mesin yang Anda kendalikan, tambal, dan pantau. Memberikan kepemilikan yang sama kepada pir yang tidak akan Anda beri router adalah kesalahan yang diundang rancangan ini.

Keanggotaan adalah kendali sesungguhnya. Klien mana pun yang dapat mengonfigurasi rutenya sendiri dapat mencoba memakai pintu keluar, jadi membatasi siapa yang boleh terhubung, atau pir mana yang akan dilayani pintu keluar, adalah bagian dari rancangan, bukan renungan belakangan.

Gagal dengan aman saat pintu keluar hilang

Matikan pintu keluar dan kepemilikan bawaan internal hilang bersama sesinya. Yang tidak boleh terjadi adalah hub diam-diam menjadi pintu keluar pengganti: tidak ada rute bawaan dari pool VPN ke uplink hub, dan tidak ada aturan penyamaran luas di hub yang dengan senang hati meneruskan lalu lintas yang sama. Uji kegagalan itu dengan sengaja, lalu uji pemulihan dengan aliran baru, bukan halaman yang sudah terbuka.

# on the consumer, with the exit up and then down
ip -4 route get 1.1.1.1
curl -sS -o /dev/null -w '%{http_code}\n' https://example.com

Jika lalu lintas konsumen masih mencapai internet setelah pintu keluar hilang, ada hal lain yang membawanya dan batas yang Anda maksud tidak ada. Perlakukan DNS dan IPv6 juga sebagai keputusan terpisah: rute IPv4 plus penyamaran tidak mengatakan apa pun tentang lalu lintas AAAA, dan resolver yang didorong hub akan menjawab dari tempat kueri benar-benar keluar.

Artikel terkait