Paksa lalu lintas IP lokal ke antarmuka eksternal

30

Saya memiliki mesin dengan beberapa antarmuka yang dapat saya konfigurasi seperti yang saya inginkan, misalnya:

  • eth1: 192.168.1.1
  • eth2: 192.168.2.2

Saya ingin meneruskan semua lalu lintas yang dikirim ke salah satu alamat lokal ini melalui antarmuka lainnya. Misalnya, semua permintaan ke server iperf, ftp, http di 192.168.1.1 seharusnya tidak hanya dirutekan secara internal, tetapi diteruskan melalui eth2 (dan jaringan eksternal akan mengurus perutean ulang paket ke eth1).

Saya mencoba dan melihat beberapa perintah, seperti iptables, ip route, dll ... tetapi tidak ada yang berhasil.

Perilaku terdekat yang bisa saya lakukan adalah dengan:

ip route change to 192.168.1.1/24 dev eth2

yang mengirim semua 192.168.1.x pada eth2, kecuali untuk 192.168.1.1 yang masih dialihkan secara internal. Mungkin saya kemudian dapat melakukan penerusan NAT dari semua lalu lintas yang diarahkan ke 192.168.1.2 palsu pada eth1, dialihkan ke 192.168.1.1 secara internal? Saya sebenarnya berjuang dengan iptables, tetapi itu terlalu sulit bagi saya.

Tujuan dari pengaturan ini adalah untuk melakukan pengujian driver antarmuka tanpa menggunakan dua PC.

Saya menggunakan Linux, tetapi jika Anda tahu cara melakukannya dengan Windows, saya akan membelinya!

Edit:

Jaringan eksternal hanyalah kabel crossover antara eth1 dan eth2. Katakanlah saya memiliki server http di komputer saya. Sekarang saya ingin mengakses server ini dari mesin yang sama, tetapi saya ingin memaksa lalu lintas TCP / IP untuk melewati kabel eth1 / eth2 ini. Bagaimana cara saya mengkonfigurasi antarmuka saya untuk ini?

calandoa
sumber
Apakah Anda ingin semua lalu lintas dicerminkan melalui antarmuka 1 dan 2 tetapi hanya dikembalikan ke antarmuka 2 dari router lain? Tidak bisakah itu melakukan beberapa hal aneh di jaringan? Akankah lebih baik untuk mengarahkan lalu lintas cermin dari antarmuka 2 ke sistem lain yang hanya menjatuhkan lalu lintas dan kemudian Anda dapat memonitornya, atau menggunakan perangkat lunak virtualisasi untuk menangkap lalu lintas? Mungkin saya kehilangan sesuatu dalam deskripsi.
Bart Silverstrim
Sepertinya dia ingin membuat paket, katakanlah, 192.168.1.1 yang merupakan IP dari eth1. Tetapi alih-alih tumpukan Linux yang menerima paket itu sepenuhnya secara internal, ia ingin paket itu dipaksa keluar eth2 (yang akan dikirim secara eksternal kembali ke eth1 dan kemudian tumpukan Linux). Saya tidak yakin apakah ini mungkin; setelah lapisan jaringan mendeteksi alamat adalah antarmuka internal, ia akan memiliki sedikit alasan untuk melihat tabel routing. Orang lain mungkin lebih tahu.
PP.

Jawaban:

14

Saya memperluas jawaban caladona karena saya tidak bisa melihat paket respons. Untuk contoh ini:

  1. Pada PC lokal saya, saya memiliki NIC pada subnet yang berbeda, 192.168.1 / 24 , 192.168.2 / 24
  2. Ada router / PC eksternal yang memiliki akses ke kedua subnet.
  3. Saya ingin mengirim lalu lintas dua arah melalui NIC di PC lokal.
  4. Konfigurasi ini memerlukan dua alamat IP yang tidak digunakan untuk setiap subnet.

Rute iptable PC lokal diatur ke lalu lintas keluar SNAT dan DNAT ke IP 'palsu'.

iptables -t nat -A POSTROUTING -d 192.168.1.100 -s 192.168.2.0/24 -j SNAT --to-source      192.168.2.100
iptables -t nat -A PREROUTING  -d 192.168.1.100 -i eth0           -j DNAT --to-destination 192.168.1.1
iptables -t nat -A POSTROUTING -d 192.168.2.100 -s 192.168.1.0/24 -j SNAT --to-source      192.168.1.100
iptables -t nat -A PREROUTING  -d 192.168.2.100 -i eth1           -j DNAT --to-destination 192.168.2.1

Aturannya lakukan sebagai berikut:

  1. Tulis ulang sumber 192.168.2.1 ke 192.168.2.100 pada paket keluar
  2. Tulis ulang tujuan 192.168.1.100 menjadi 192.168.1.1 pada paket yang masuk
  3. Tulis ulang sumber 192.168.1.1 ke 192.168.1.100 pada paket keluar
  4. Tulis ulang 192.168.2.100 tujuan menjadi 192.168.2.1 pada paket yang masuk

Untuk meringkas, sistem lokal sekarang dapat berbicara dengan mesin 'virtual' dengan alamat 192.168.1.100 dan 192.168.2.100.

Selanjutnya Anda harus memaksa PC lokal Anda untuk menggunakan router eksternal untuk mencapai IP palsu Anda. Anda melakukan ini dengan membuat rute langsung ke IP melalui router. Anda ingin memastikan bahwa Anda memaksa paket ke kebalikan dari subnet tujuan.

ip route 192.168.1.100 via $ROUTER_2_SUBNET_IP 
ip route 192.168.2.100 via $ROUTER_1_SUBNET_IP

Akhirnya untuk membuat semua ini berfungsi, router eksternal perlu tahu cara mencapai IP palsu di PC lokal Anda. Anda dapat melakukannya dengan menyalakan ARP proxy untuk sistem Anda.

echo 1 | sudo tee /proc/sys/net/ipv4/conf/all/proxy_arp
echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward

Dengan pengaturan ini, Anda sekarang dapat memperlakukan IP palsu sebagai sistem nyata pada PC lokal Anda. Mengirim data ke subnet .1 akan memaksa paket keluar dari antarmuka .2. Mengirim data ke subnet .2 akan memaksa paket keluar dari antarmuka .1.

ping 192.168.1.100
ping 192.168.2.100
cmcginty
sumber
Cara Anda jauh lebih baik! Perhatikan bahwa saya juga memerlukan ip_forward agar ARP berfungsi: echo 1> / proc / sys / net / ipv4 / ip_forward
calandoa
28

Saya berhasil menggunakan yang berikut ini di Linux untuk menguji throughput pada kartu 10Gbps dual-port baru dalam mode "loopback", yaitu, satu port terhubung langsung ke yang lain. Ini semua hanya sedikit voodoo hanya untuk memaksa paket keluar dari kabel, tetapi jika tidak, Linux hanya akan melakukan hubungan arus pendek traffic melalui kernel (maka pertanyaan OP). Dalam jawaban Casey di atas, saya tidak yakin apakah benar-benar perlu memiliki router eksternal atau tidak di atas, tetapi yang berikut ini sepenuhnya mandiri. Dua antarmuka adalah eth2 dan eth3.

Berikan IP ke antarmuka, dan letakkan di jaringan terpisah:

ifconfig eth2 10.50.0.1/24
ifconfig eth3 10.50.1.1/24

Selanjutnya kita akan membuat skenario NAT ganda: dua jaringan palsu baru yang digunakan untuk mencapai yang lain. Di jalan keluar, sumber NAT ke jaringan palsu Anda. Dalam perjalanan, perbaiki tujuan. Dan sebaliknya untuk jaringan lain:

# nat source IP 10.50.0.1 -> 10.60.0.1 when going to 10.60.1.1
iptables -t nat -A POSTROUTING -s 10.50.0.1 -d 10.60.1.1 -j SNAT --to-source 10.60.0.1

# nat inbound 10.60.0.1 -> 10.50.0.1
iptables -t nat -A PREROUTING -d 10.60.0.1 -j DNAT --to-destination 10.50.0.1

# nat source IP 10.50.1.1 -> 10.60.1.1 when going to 10.60.0.1
iptables -t nat -A POSTROUTING -s 10.50.1.1 -d 10.60.0.1 -j SNAT --to-source 10.60.1.1

# nat inbound 10.60.1.1 -> 10.50.1.1
iptables -t nat -A PREROUTING -d 10.60.1.1 -j DNAT --to-destination 10.50.1.1

Sekarang beri tahu sistem cara menuju ke setiap jaringan palsu, dan siapkan entri arp sebelumnya (pastikan untuk mengganti alamat MAC Anda, jangan gunakan milikku):

ip route add 10.60.1.1 dev eth2
arp -i eth2 -s 10.60.1.1 00:1B:21:C1:F6:0F # eth3's mac address

ip route add 10.60.0.1 dev eth3 
arp -i eth3 -s 10.60.0.1 00:1B:21:C1:F6:0E # eth2's mac address

Ini bodoh Linux cukup untuk benar-benar meletakkan paket ke kabel. Sebagai contoh:

ping 10.60.1.1

keluar eth2, sumber IP 10.50.0.1 mendapat NATted ke 10.60.0.1, dan ketika datang ke eth3 tujuan 10.60.1.1 mendapat NATted ke 10.50.1.1. Dan jawabannya mengambil perjalanan yang serupa.

Sekarang gunakan iperf untuk menguji throughput. Ikat IP yang benar, dan pastikan IP mana yang Anda hubungi (alamat palsu ujung lainnya):

# server
./iperf -B 10.50.1.1 -s

# client: your destination is the other end's fake address
./iperf -B 10.50.0.1 -c 10.60.1.1 -t 60 -i 10

Pastikan lalu lintas benar-benar keluar ke kawat:

tcpdump -nn -i eth2 -c 500

Anda juga dapat menonton / proc / menyela hanya untuk benar-benar yakin kartu sedang digunakan:

while true ; do egrep 'eth2|eth3' /proc/interrupts ; sleep 1 ; done

Bagaimanapun, saya menemukan posting ini mencari cara melakukan ini, terima kasih untuk teman-teman T&J, dan berharap ini membantu orang lain menemukan posting ini di masa depan.

Steve Kehlet
sumber
+1 Solusi hebat - ini bahkan tidak perlu mengaktifkan ip-forwarding! Inilah yang saya butuhkan saat ini (untuk pengujian 10GB melalui loopback).
Nils
16

Seperti biasa - saya sedikit terlambat - tetapi saat ini orang dapat menggunakan ruang nama jaringan untuk mengisolasi antarmuka dan mencegah penerusan lokal (dan mengutak-atik iptables :)).

Buat ruang nama (semua dilakukan dengan izin yang diperlukan, misalnya sebagai root):

ip netns add ns_server
ip netns add ns_client

Perhatikan bahwa status antarmuka / konfigurasi sekarang harus diakses dalam konteks namespace yang ditugaskan - sehingga mereka tidak akan muncul jika Anda menjalankan tautan ip telanjang karena ini dijalankan dalam konteks namespace default. Menjalankan perintah di dalam namespace dapat dilakukan menggunakan

ip netns exec <namespace-name> <command>

sebagai awalan.

Sekarang tetapkan ruang nama untuk antarmuka, terapkan konfigurasi dan atur antarmuka:

ip link set eth1 netns ns_server
ip netns exec ns_server ip addr add dev eth1 192.168.1.1/24
ip netns exec ns_server ip link set dev eth1 up
ip link set eth2 netns ns_client
ip netns exec ns_client ip addr add dev eth2 192.168.1.2/24
ip netns exec ns_client ip link set dev eth2 up

Sekarang Anda dapat menjalankan aplikasi di dalam namespace - untuk menjalankan server iperf

ip netns exec ns_server iperf -s -B 192.168.1.1

dan klien:

ip netns exec ns_client iperf -c 192.168.1.1 -B 192.168.1.2

Lalu lintas sekarang akan dikirim melalui antarmuka fisik karena seluruh jaringan, antarmuka, perutean ... diisolasi oleh ruang nama sehingga kernel tidak dapat mencocokkan alamat yang digunakan dalam lalu lintas dengan antarmuka lokal (tersedia).

Jika Anda selesai dengan eksperimen, cukup hapus ruang nama:

ip netns del <namespace-name>

Antarmuka akan dipindahkan ke namespace default dan semua konfigurasi yang dilakukan dalam namespace menghilang (mis. Tidak perlu menghapus alamat IP yang ditugaskan).

Thomas Tannhäuser
sumber
Ini jauh lebih mudah daripada sihir double-nat yang disarankan, dan tidak memerlukan koordinasi dari komputer lain di jaringan atau mengasumsikan topologi fisik apa pun. Satu-satunya permintaan saya adalah Anda menambahkan perintah untuk menambahkan rute.
Huckle
2

Ok, akhirnya saya berhasil mengatur konfigurasi saya.

Idenya adalah menggunakan alamat palsu lain, untuk memaksa rute alamat palsu ini ke antarmuka 2, lalu menerjemahkan alamat palsu dengan alamat asli 2 dengan NAT / iptables.

Pengaturan saya sebenarnya terbuat dari satu router yang saya bisa telnet antara IF1 (antarmuka 1) dan IF2

Dalam pengaturan saya, FAKE_ADDR dan IF1_ADDR berada di subnet yang sama.

ifconfig $IF1 $IF1_ADDR netmask 255.255.255.0
ifconfig $IF2 $IF2_ADDR netmask 255.255.255.0

iptables -t nat -A PREROUTING -d $FAKE_ADDR -i $IF2 -j DNAT --to-destination $IF2_ADDR
iptables -t nat -A POSTROUTING -s $IF2_ADDR -d $IF1_ADDR/24 -j SNAT --to-source $FAKE_ADDR

route add $FAKE_ADDR gw $ROUTER_ADDR

Dan di router:

route add $FAKE_ADDR gw $IF2_ADDR

Jika saya mengirim sesuatu ke FAKE_ADDR, pkt diteruskan melalui IF1 ke router, diteruskan lagi ke IF2, maka FAKE_IP digantikan oleh IF2_ADDR. Paket diproses oleh server, hasilnya dikirim kembali ke IF1_ADDR, dari IF2_ADDR yang digantikan oleh FAKE_ADDR.

Mungkin dimungkinkan untuk menggunakan konfigurasi yang lebih sederhana dengan hanya satu kabel crossover, tetapi karena saya tidak mencoba, saya lebih suka memberikan solusi kerja saya.

calandoa
sumber
jika router mengirim $ FAKE_ADDR ke $ IF2_ADDR, bukankah aturan DNAT Anda harus "-i $ IF2" bukannya "-i $ IF1"?
cmcginty
Anda benar Casey, koreksi dilakukan.
calandoa
1

Jawaban yang diberikan di atas oleh Thomas Tannhäuser sangat tepat!

Saya memiliki situasi yang serupa: mesin tunggal dengan dua antarmuka enet. Rencana saya adalah menggunakan satu antarmuka sebagai server (penerima) dan yang lainnya sebagai klien (pengirim). Setiap antarmuka akan dilampirkan ke router dan iperf akan mengarahkan lalu lintas melalui router untuk mengukur throughput, PPS, delay, dll.

Sayangnya, pendekatan iptables tidak intuitif dan penuh dengan masalah. Setelah beberapa jam yang membuat frustrasi, saya meninggalkan rencana serangan ini. Terinspirasi oleh saran Thomas, saya melakukan sedikit pekerjaan rumah di Linux IP Namespaces dan mulai menghargai kesederhanaan dan keanggunan solusi ini.

Di bawah ini adalah daftar perintah persis yang saya gunakan untuk mengkonfigurasi Fedora FC26 saya untuk melayani dalam kapasitas ini. Kedua antarmuka tersebut adalah enp1s0 dan enp3s0. Router memiliki dua antarmuka dengan alamat 192.168.2.112 dan 172.16.16.2. Setiap konektor EN26 FC26 dihubungkan langsung ke antarmuka router yang sesuai.

# How to configure the IP Namespaces
ip netns add iperf-server
ip netns add iperf-client
ip link set enp1s0 netns iperf-server
ip link set enp3s0 netns iperf-client
ip netns exec iperf-server ip addr add dev enp1s0 192.168.2.139/20
ip netns exec iperf-client ip addr add dev enp3s0 172.16.16.2/24
ip netns exec iperf-client ip link set dev enp3s0 up
ip netns exec iperf-server ip link set dev enp1s0 up
ip netns exec iperf-server route add default gw 192.168.2.112
ip netns exec iperf-client route add default gw 172.16.16.1

# Test the interfaces and network using ping
ip netns exec iperf-client ping -c1 172.16.16.1
ip netns exec iperf-server ping -c1 192.168.2.112
ip netns exec iperf-server ping -c1 172.16.16.2
ip netns exec iperf-client ping -c1 192.168.2.139

# Start Iperf Server for UDP test
ip netns exec iperf-server iperf -u -s
# Run Client against Iperf server for UDP test
ip netns exec iperf-client iperf -u -c 192.168.2.139
RarkyMan
sumber
0

Sepertinya Anda ingin mengubah kotak linux Anda menjadi jenis kotak router / jembatan / gateway / firewall. Sumber daya berikut mungkin apa yang Anda cari:

Proyek Router Linux

Daftar distribusi router atau firewall

Linux LiveCD Router

Linux Journal - The Linux Router

Pembaruan berdasarkan informasi lebih lanjut:

Saya tidak berpikir Anda akan dapat melakukan apa yang Anda inginkan. OS akan selalu melihat tabel routing internal dan 'melihat' kedua alamat IP secara lokal. Kemudian akan merutekan traffic di dalam OS dan tidak pernah memasangnya. Anda memerlukan mesin kedua atau dua mesin virtual (lihat Xen ).

Peter
sumber
0

Banyak hal yang harus dilalui di sini, jadi saya tidak bisa sepenuhnya menjamin keakuratan saya, tetapi pertanyaan awalnya tampaknya mencari apa yang dikenal sebagai teknik "kirim ke diri sendiri" . Pencarian yang terhubung menunjukkan apa yang saya pikir merupakan patch kernel yang paling baik dipertahankan terhubung sebagai link + diskusi teratas dan patch dengan pendekatan lain pada berbagai milis, esp. LKML.

Saya pikir kita juga harus melihat namespace jaringan , dilakukan dengan iproute2 "ip netns" . Ini juga membutuhkan beberapa antarmuka tambahan dan sulap perutean, jadi mungkin bahkan tidak kalah rumit dari kehebohan iptables besar dalam jawaban lainnya.

Komentar pasti disambut jika ada yang menemukan sesuatu yang berguna dengan ini - bagaimana, apa, di mana tentang implementasi Anda.

lkraav
sumber
-1

di sini adalah bagaimana saya membuatnya bekerja untuk IPV6

ips statis yang ditetapkan

/sbin/ifconfig eth1 inet6 add 2001:db8::1/127 
/sbin/ifconfig eth3 inet6 add 2001:db8::2/127 

mengatur rute host saja ke alamat "FAKE"

ip -6 route add 2001:db8::2/128 dev eth1 metric 1
ip -6 route add 2001:db8::1/128 dev eth3 metric 1

mengisi tabel Neighbor ... seperti arp

ip -6 neighbor add 2001:db8::1 lladdr 90:e2:ba:0d:75:e8 dev eth3 # eth1's mac address
ip -6 neighbor add 2001:db8::2 lladdr 90:e2:ba:0d:75:e9 dev eth1 # eth3's mac address

menambahkan entri ip6tables

ip6tables -t nat -A POSTROUTING -s 2001:db8::1 -d 2013::2 -j SNAT --to-source 2001:db8::1
ip6tables -t nat -A PREROUTING -d 2001:db8::1 -j DNAT --to-destination 2001:db8::1
ip6tables -t nat -A POSTROUTING -s 2001:db8::2 -d 2013::1 -j SNAT --to-source 2001:db8::2
ip6tables -t nat -A PREROUTING -d 2001:db8::2 -j DNAT --to-destination 2001:db8::2
robm
sumber
Distribusi apa yang Anda gunakan? Terakhir kali saya memeriksa, kernel tidak memiliki tabel NAT untuk IPv6.
fukawi2