Cara Membuat Semua Lalu Lintas Untuk Melalui Satu Antarmuka Di Linux


12

Saya memiliki antarmuka tun0 yang ditulis sendiri ( berbasis TUN / TAP ) yang menampilkan apa yang diterimanya.
Saya membutuhkan semua lalu lintas sistem untuk mengalir melalui antarmuka ini.
Peran antarmuka adalah:

  1. Untuk mengetahui paket yang kemungkinan disensor dan menyalurkannya.
  2. Lewati semua lalu lintas lain yang tidak tersentuh.

Seperti yang Anda duga, saya mencoba membuat alat anti sensor.
Keputusan tentang tunneling harus diambil dalam proses tun0
karena hanya di sana kita dapat menggunakan DNS tepercaya.

Saya butuh bantuan Anda untuk menunjukkan kepada saya bagaimana membuat semua lalu lintas mengalir melalui antarmuka tulisan otomatis tun0. Jika tun0 membutuhkan perubahan, saya meminta Anda untuk memberikan perubahan tersebut.

Di bawah ini adalah bagaimana saya mencoba untuk membuat semua lalu lintas melalui tun0 dan gagal (ping gagal).

Kompilasi

  1. gcc tun0.c
  2. sudo ./a.out

Mengkonfigurasi

  1. sudo ip addr add 10.0.0.1/24 dev tun0
  2. buat tabel John

    $ cat /etc/iproute2/rt_tables 
    #
    # reserved values
    #
    255     local
    254     main
    253     default
    0       unspec
    #
    # local
    #
    #1      inr.ruhep
    
    200 John
    

Urutan itu penting:

  1. sudo ip rule add from all lookup John
  2. sudo ip route add default dev tun0 table John
  3. sudo ip rule add iif tun0 lookup main priority 500

    $ ip rule
    0:      from all lookup local 
    500:    from all iif tun0 lookup main 
    32765:  from all lookup John 
    32766:  from all lookup main 
    35000:  from all lookup default 
    

Penyelesaian masalah

  1. sudo tcpdump -i wlp2s0 -qtln icmpdan kemudian ping -I tun0 8.8.8.8menunjukkan tidak ada paket yang ditangkap, itu berarti tidak ada paket yang dikirimkan dari tun0 ke wlp2s0 melalui iif tun0 lookup mainaturan.

  2. Ketika saya diganti tun0dengan di lomana - mana maka itu berhasil untuk saya.

Juga Mencoba

  1. Mematikan penyaringan jalur terbalik, rp_filter=0di/etc/sysctl.conf

Jawab Pemecahan Masalah

iptables -I FORWARD -j LOG --log-prefix "filter/FORWARD " 
iptables -t nat -I OUTPUT -j LOG --log-prefix "nat/OUTPUT " 
iptables -t nat -I PREROUTING -j LOG --log-prefix "nat/PREROUTING " 
iptables -t nat -I POSTROUTING -j LOG --log-prefix "nat/POSTROUTNG "
tail -f /var/log/syslog

Sumber yang dimodifikasi dari jawaban juga ada di sini .

Jawaban:


10

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.


Saya harus menggunakan -j SNAT, bukan-s SNAT
ilyaigpetrov

Ini berfungsi tetapi kinerjanya sangat terputus-putus (mungkin macet selama 10 detik kemudian terus bekerja). Saya akan mencari tahu mengapa itu terjadi dan bagaimana cara memperbaikinya.
ilyaigpetrov

1
Maaf itu salah ketik saya. Saya menambahkan pendekatan lain untuk jawaban saya. Tidak tahu tentang masalah kinerja. Omong-omong, mengapa tidak menggunakan proxy transparan dengan iptables DNAT untuk memfilter dan mengalihkan lalu lintas?
tifssoft

Saya tidak dapat mereproduksi pendekatan tanda Anda, saya telah menambahkan hanya sudo ip rule add iif tun0 lookup main priority 500untuk itu tetapi tetap tidak berhasil. Saya suka pendekatan ini, Sayang sekali saya tidak bisa mereproduksi itu.
ilyaigpetrov

1
Terima kasih atas pendekatan baru Anda, saya mengikutinya langkah demi langkah dan itu berhasil dengan sempurna. Namun saya tidak mengerti mengapa kita perlu mengubah ips, yang paling penting itu berfungsi. Jika rencana saya dengan proksi TCP gagal, saya akan dapat kembali ke jawaban Anda. Anda menunjukkan banyak keterampilan jaringan di sini dan saya tidak ragu keterampilan Anda akan didambakan. Semoga berhasil!
ilyaigpetrov
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.