Jadi dalam konfigurasi Anda, semua paket yang Anda coba kirim ke jaringan awalnya berasal 10.0.0.1
(karena mereka akan melalui tun0
antarmuka dan alamat lokalnya adalah 10.0.0.1
). Anda menangkap paket, semuanya baik-baik saja sejauh ini.
Sekarang, tun0
kirim paket lebih lanjut. Alamat sumbernya adalah 10.0.0.1
dan Anda ingin paket-paket itu pergi melalui antarmuka yang berbeda ( wlp2s0
dalam kasus Anda). Itu perutean jadi mari kita aktifkan perutean pertama:
sysctl -w net.ipv4.ip_forward=1
Setelah itu, jika Anda akan melihat tcpdump
untuk wlp2s0
Anda dapat melihat paket meninggalkan dengan alamat sumber 10.0.0.1
dan 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 FORWARD
rantai Anda memiliki ACCEPT
kebijakan 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 tun0
antarmuka ke wlp2s0
. netfilter harus mengubah IP sumber 10.0.0.1
ke wlp2s0
alamat yang ditugaskan antarmuka Anda untuk paket output. Itu menghafal semua koneksi dan ketika paket balasan kembali (jika mereka) itu mengubah alamat tujuan dari wlp2s0
antarmuka 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 OUTPUT
rantai dan kemudian dialihkan dan datang ke PREROUTING
rantai. Paling tidak kotak Debian 8 tidak berfungsi.
Cara terbaik untuk memecahkan masalah netfilter adalah TRACE
fitur:
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 FORWARD
rantai (dan tidak ditangkap oleh nat/POSTROUTING
rantai 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.c
aplikasi. 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.c
dengan 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.c
peluncuran:
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 - tun0
hanya menerima dan mengirim paket milik subnetnya. Anda juga dapat melakukan perutean berbasis sumber alih-alih berbasis antarmuka.
PENDEKATAN # 2
Itu mungkin dilakukan SNAT
sebelum tun0
antarmuka 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 tun0
perangkat. tun0.c
kode 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/POSTROUTING
rantai pada wlp2s0
antarmuka 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 SNAT
tetapi Anda akan menangkap paket hanya keluar:
Pertama kita perlu menonaktifkan reverse path penyaringan untuk tun0
karena 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
sudo ip rule add iif tun0 lookup main priority 500
untuk itu tetapi tetap tidak berhasil. Saya suka pendekatan ini, Sayang sekali saya tidak bisa mereproduksi itu.