Jadi dalam konfigurasi Anda, semua paket yang Anda coba kirim ke jaringan awalnya berasal 10.0.0.1(karena mereka akan melalui tun0antarmuka dan alamat lokalnya adalah 10.0.0.1). Anda menangkap paket, semuanya baik-baik saja sejauh ini.
Sekarang, tun0kirim paket lebih lanjut. Alamat sumbernya adalah 10.0.0.1dan Anda ingin paket-paket itu pergi melalui antarmuka yang berbeda ( wlp2s0dalam kasus Anda). Itu perutean jadi mari kita aktifkan perutean pertama:
sysctl -w net.ipv4.ip_forward=1
Setelah itu, jika Anda akan melihat tcpdumpuntuk wlp2s0Anda dapat melihat paket meninggalkan dengan alamat sumber 10.0.0.1dan tidak dengan alamat sumber dari interface wlan (apa yang Anda harapkan kurasa). Jadi kita perlu mengubah alamat sumber dan itu disebut sumber NAT . Di linux mudah dengan bantuan netfilter / iptables :
iptables -t nat -A POSTROUTING -o wlp2s0 -s 10.0.0.1 -j MASQUERADE
Harap periksa juga apakah FORWARDrantai Anda memiliki ACCEPTkebijakan atau Anda perlu mengizinkan penerusan dengan sesuatu seperti:
iptables -A FORWARD -i tun0 -o wlp2s0 -s 10.0.0.1 -j ACCEPT
iptables -A FORWARD -i wlp2s0 -o tun0 -d 10.0.0.1 -j ACCEPT
Semuanya harus berfungsi sekarang: kernel linux melakukan routing, itu memindahkan paket dari tun0antarmuka ke wlp2s0. netfilter harus mengubah IP sumber 10.0.0.1ke wlp2s0alamat yang ditugaskan antarmuka Anda untuk paket output. Itu menghafal semua koneksi dan ketika paket balasan kembali (jika mereka) itu mengubah alamat tujuan dari wlp2s0antarmuka yang ditugaskan untuk 10.0.0.1(fitur "conntrack").
Yah, seharusnya tapi tidak. Tampaknya, netfilter menjadi bingung dengan konfigurasi perutean yang rumit ini dan fakta bahwa paket yang sama pertama kali melalui OUTPUTrantai dan kemudian dialihkan dan datang ke PREROUTINGrantai. Paling tidak kotak Debian 8 tidak berfungsi.
Cara terbaik untuk memecahkan masalah netfilter adalah TRACEfitur:
modprobe ipt_LOG
iptables -t raw -A OUTPUT -p icmp -j TRACE
iptables -t raw -A PREROUTING -p icmp -j TRACE
Saya hanya mengaktifkan pelacakan paket ICMP, Anda dapat menggunakan filter lain untuk debug.
Ini akan menunjukkan tabel dan rantai apa yang dilalui paket. Dan saya dapat melihat bahwa paket tersebut tidak melanjutkan FORWARDrantai (dan tidak ditangkap oleh nat/POSTROUTINGrantai yang sebenarnya SNAT).
Di bawah ini adalah beberapa pendekatan untuk membuat ini bekerja.
PENDEKATAN # 1
Cara terbaik untuk tidak mengacaukan netfilter adalah dengan mengubah alamat IP sumber paket dalam tun0.caplikasi. Itu juga cara yang paling alami. Kita perlu mengubah 10.0.0.1 ke 10.0.0.2 di jalan keluar dan 10.0.0.2 ke 10.0.0.1 di jalan kembali.
Saya telah dimodifikasi tun0.cdengan kode perubahan alamat sumber. Ini adalah file baru dan ini adalah patchfile untuk Anda tun0.c. Perubahan ke header IP juga melibatkan koreksi checksum , jadi saya mengambil beberapa kode dari proyek OpenVPN . Berikut adalah daftar lengkap perintah yang saya jalankan setelah reboot bersih dan tun0_changeip.cpeluncuran:
ifconfig tun0 inet 10.0.0.1/30 up
sysctl -w net.ipv4.ip_forward=1
ip route add default dev tun0 table John
ip rule add from all lookup John
ip rule add from 10.0.0.2 lookup main priority 500
iptables -t nat -A POSTROUTING -o wlp2s0 -s 10.0.0.2 -j MASQUERADE
Harap dicatat bahwa Anda tidak perlu mematikan pemfilteran jalur balik dalam kasus itu, karena semuanya legal - tun0hanya menerima dan mengirim paket milik subnetnya. Anda juga dapat melakukan perutean berbasis sumber alih-alih berbasis antarmuka.
PENDEKATAN # 2
Itu mungkin dilakukan SNATsebelum tun0antarmuka jangkauan paket . Itu tidak terlalu benar. Anda harus mematikan pemfilteran jalur balik dalam kasus ini:
sysctl -w net.ipv4.conf.tun0.rp_filter=0
# It won't work without also changing the "all" value
sysctl -w net.ipv4.conf.all.rp_filter=0
Sekarang, lakukan SNAT: iptables -t nat -A POSTROUTING -o tun0 -s 10.0.0.1 -j SNAT --to-source ip.address.of.your.wlan.interface
Di sini kita mengubah alamat sumber sesaat sebelum paket mencapai tun0perangkat. tun0.ckode kirim ulang paket-paket ini "sebagaimana adanya" (dengan alamat sumber yang diubah) dan mereka berhasil dialihkan melalui antarmuka wlan. Tetapi Anda mungkin memiliki IP dinamis pada antarmuka wlan dan ingin menggunakan MASQUERADE(agar tidak menentukan alamat antarmuka secara eksplisit). Inilah cara Anda dapat memanfaatkan MASQUERADE:
iptables -t nat -A POSTROUTING -o tun0 -s 10.0.0.1 -j SNAT --to-source 10.0.55.1
iptables -t nat -A POSTROUTING -o wlp2s0 -s 10.0.55.1 -j MASQUERADE
Harap perhatikan " 10.0.55.1" alamat IP - ini berbeda. Anda dapat menggunakan IP apa pun di sini, tidak masalah. Paket mencapai nat/POSTROUTINGrantai pada wlp2s0antarmuka jika kita mengubah IP sumber sebelumnya. Dan sekarang ini tidak tergantung pada IP statis untuk antarmuka wlan.
PENDEKATAN # 3
Anda juga bisa menggunakan fwmark. Dengan cara itu Anda tidak perlu SNATtetapi Anda akan menangkap paket hanya keluar:
Pertama kita perlu menonaktifkan reverse path penyaringan untuk tun0karena akan meneruskan paket yang termasuk ke jaringan lain:
sysctl -w net.ipv4.conf.tun0.rp_filter=0
# It won't work without also changing the "all" value
sysctl -w net.ipv4.conf.all.rp_filter=0
Now let's alter the routing rules a bit:
# Delete old rules
ip rule del iif tun0 lookup main
ip rule del from all lookup John
# Packets will start going from wlan interface so they will have source address of it
iptables -t mangle -A OUTPUT -o wlp2s0 -j MARK --set-mark 1
ip rule add fwmark 0x1 lookup John
Itu adalah "retasan" lain untuk perutean dan netfilter yang berfungsi pada kotak Debian 8 saya, tetapi saya tetap menyarankan untuk mengambil pendekatan pertama karena lebih alami dan tidak menggunakan peretasan.
Anda juga dapat mempertimbangkan untuk membangun aplikasi Anda sebagai proxy transparan . Saya pikir ini akan jauh lebih mudah daripada menganalisis paket dari perangkat tun.
-j SNAT, bukan-s SNAT