Linux tidak membalas pesan permintaan ARP jika alamat IP yang diminta terkait dengan antarmuka (dinonaktifkan) lainnya

9

Saya memiliki PC (kernel 3.2.0-23-generik ) yang telah 192.168.1.2/24dikonfigurasi untuk eth0antarmuka dan juga menggunakan 192.168.1.1dan 192.168.1.2alamat untuk tun0antarmuka:

root@T42:~# ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:16:41:54:01:93 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.2/24 scope global eth0
    inet6 fe80::216:41ff:fe54:193/64 scope link
       valid_lft forever preferred_lft forever
3: bond0: <BROADCAST,MULTICAST,MASTER> mtu 1500 qdisc noop state DOWN
    link/ether 00:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff
4: irda0: <NOARP> mtu 2048 qdisc noop state DOWN qlen 8
    link/irda 00:00:00:00 brd ff:ff:ff:ff
5: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:13:ce:8b:99:3e brd ff:ff:ff:ff:ff:ff
    inet 10.30.51.53/24 brd 10.30.51.255 scope global eth1
    inet6 fe80::213:ceff:fe8b:993e/64 scope link
       valid_lft forever preferred_lft forever
6: tun0: <POINTOPOINT,MULTICAST,NOARP> mtu 1500 qdisc pfifo_fast state DOWN qlen 100
    link/none
    inet 192.168.1.1 peer 192.168.1.2/32 scope global tun0
root@T42:~# ip route show dev eth0
192.168.1.0/24  proto kernel  scope link  src 192.168.1.2 
root@T42:~# 

Seperti yang terlihat di atas, tun0secara administratif dinonaktifkan ( ip link set dev tun0 down). Sekarang ketika saya menerima permintaan ARP 192.168.1.2, PC tidak membalas permintaan itu:

root@T42:~# tcpdump -nei eth0
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
15:30:34.875427 00:1a:e2:ae:cb:b7 > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 60: Request who-has 192.168.1.2 tell 192.168.1.1, length 46
15:30:36.875268 00:1a:e2:ae:cb:b7 > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 60: Request who-has 192.168.1.2 tell 192.168.1.1, length 46
15:30:39.138651 00:1a:e2:ae:cb:b7 > 00:1a:e2:ae:cb:b7, ethertype Loopback (0x9000), length 60:
^C
3 packets captured
3 packets received by filter
0 packets dropped by kernel
root@T42:~#

Hanya setelah saya menghapus tun0antarmuka ( ip link del dev tun0) PC akan membalas permintaan ARP untuk 192.168.1.2di eth0antarmuka.

Tabel perutean tampak persis sama sebelum dan sesudah ip link del dev tun0:

root@T42:~# netstat -rn
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
0.0.0.0         10.30.51.254    0.0.0.0         UG        0 0          0 eth1
10.30.51.0      0.0.0.0         255.255.255.0   U         0 0          0 eth1
192.168.1.0     192.168.1.2     255.255.255.0   UG        0 0          0 eth0
root@T42:~# ip link del dev tun0
root@T42:~# netstat -rn
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
0.0.0.0         10.30.51.254    0.0.0.0         UG        0 0          0 eth1
10.30.51.0      0.0.0.0         255.255.255.0   U         0 0          0 eth1
192.168.1.0     192.168.1.2     255.255.255.0   UG        0 0          0 eth0
root@T42:~# 

Entri perutean di bawah sudah dihapus dengan ip link set dev tun0 downperintah:

Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
192.168.1.2     0.0.0.0         255.255.255.255 UH        0 0          0 tun0

Namun, sementara tabel routing sama persis sebelum dan sesudah ip link del dev tun0perintah, keputusan routing sebenarnya yang dibuat kernel tidak:

T42:~# ip route get 192.168.1.1
local 192.168.1.1 dev lo  src 192.168.1.1 
    cache <local> 
T42:~# ip link del dev tun0
T42:~# ip route get 192.168.1.1
192.168.1.1 dev eth0  src 192.168.1.2 
    cache  ipid 0x8390
T42:~# 

Apakah ini perilaku yang diharapkan? Mengapa kernel mengabaikan tabel routing?

Martin
sumber
Bisakah Anda menempelkan output netstat -rn untuk kedua kasus? Tabel routing biasanya adalah tempat pertama untuk mencari kesalahan semacam ini.
Clarus
@Claris Saya memperbarui posting awal saya.
Martin
Memiliki IP yang sama pada dua antarmuka dapat membuat masalah dan sebaiknya dihindari, yang mengatakan Anda harus dapat melacak masalah tersebut. Langkah selanjutnya adalah melihat cache arp, apakah arp -a menunjukkan sesuatu yang berguna?
Clarus
@Claris Sepertinya akar penyebabnya adalah bahwa kernel mengabaikan tabel routing ketika tun0antarmuka dinonaktifkan, tetapi ada. Lihat output ip route getperintah di posting awal saya yang diperbarui. Namun, mengapa kernel bersikap seperti itu?
Martin

Jawaban:

17

Tabel perutean Anda tidak diabaikan, tepatnya. Itu ditolak oleh tabel routing dengan prioritas lebih tinggi.

Apa yang sedang terjadi

Tabel perutean yang Anda lihat saat mengetik ip route showbukan satu-satunya tabel perutean yang digunakan kernel. Sebenarnya, ada tiga tabel routing secara default, dan mereka dicari dalam urutan yang ditunjukkan oleh ip ruleperintah:

# ip rule show
0:      from all lookup local
32766:  from all lookup main
32767:  from all lookup default

Tabel yang paling Anda kenal adalah main, tetapi tabel routing dengan prioritas tertinggi local. Tabel ini dikelola oleh kernel untuk melacak rute lokal dan broadcast: dengan kata lain, localtabel memberitahu kernel bagaimana cara merutekan ke alamat dari interface-nya sendiri. Itu terlihat seperti ini:

# ip route show table local
broadcast 127.0.0.0 dev lo  proto kernel  scope link  src 127.0.0.1
local 127.0.0.0/8 dev lo  proto kernel  scope host  src 127.0.0.1
local 127.0.0.1 dev lo  proto kernel  scope host  src 127.0.0.1
broadcast 127.255.255.255 dev lo  proto kernel  scope link  src 127.0.0.1
broadcast 192.168.1.0 dev eth0  proto kernel  scope link  src 192.168.1.2
local 192.168.1.1 dev tun0  proto kernel  scope host  src 192.168.1.1
local 192.168.1.2 dev eth0  proto kernel  scope host  src 192.168.1.2
broadcast 192.168.1.255 dev eth0  proto kernel  scope link  src 192.168.1.2

Lihat referensi garis itu tun0. Itulah yang menyebabkan hasil aneh Anda route get. Dikatakan 192.168.1.1 adalah alamat lokal, yang berarti jika kita ingin mengirim balasan ARP ke 192.168.1.1, itu mudah; kami kirim ke diri sendiri. Dan karena kami menemukan rute di localtabel, kami berhenti mencari rute, dan tidak perlu repot memeriksa mainatau defaulttabel.

Mengapa banyak tabel?

Minimal, senang bisa mengetik ip routedan tidak melihat semua rute "jelas" yang mengacaukan tampilan (coba ketikkan route printpada mesin Windows). Itu juga dapat berfungsi sebagai beberapa perlindungan minimal terhadap kesalahan konfigurasi: bahkan jika tabel routing utama telah tercampur, kernel masih tahu bagaimana berbicara dengan dirinya sendiri.

(Mengapa mempertahankan rute lokal di tempat pertama? Jadi kernel dapat menggunakan kode pencarian yang sama untuk alamat lokal seperti halnya untuk hal lain. Itu membuat hal-hal menjadi lebih mudah secara internal.)

Ada hal-hal menarik lainnya yang dapat Anda lakukan dengan skema multi-tabel ini. Secara khusus, Anda dapat menambahkan tabel Anda sendiri, dan menentukan aturan ketika mereka dicari. Ini disebut "perutean kebijakan", dan jika Anda ingin merutekan suatu paket berdasarkan alamat sumbernya , ini adalah bagaimana melakukannya di Linux.

Jika Anda melakukan hal-hal yang rumit atau eksperimental, Anda dapat menambah atau menghapus localrute sendiri dengan menentukan table localdalam ip routeperintah. Namun, kecuali Anda tahu apa yang Anda lakukan, Anda cenderung membingungkan kernel. Dan tentu saja, kernel masih akan terus menambah dan menghapus rute sendiri, jadi Anda harus menonton untuk memastikan Anda tidak ditimpa.

Akhirnya, jika Anda ingin melihat semua tabel routing sekaligus:

# ip route show table all

Untuk info lebih lanjut, lihat ip-rule(8)halaman manual atau dokumen iproute2 . Anda juga dapat mencoba Advanced Routing dan Traffic Control HOWTO untuk beberapa contoh yang dapat Anda lakukan.

Jander
sumber
Terima kasih! Setelah ip link set dev tun0 downitu local 192.168.1.1 dev tun0 proto kernel scope host src 192.168.1.1aturan memang masih hadir dalam localRouting-tabel. Setelah saya mengeksekusi ip link del dev tun0aturan yang disebutkan telah dihapus. Namun, satu pertanyaan - apakah saya benar bahwa semua kernel Linux modern (2.6.x, 3.x, 4.x) menggunakan RPDB untuk pencarian rute dan dengan demikian banyak tabel?
Martin
2
Ya, Anda benar dan banyak lagi. Secara mengejutkan RPDB sudah tua! "RPDB itu sendiri adalah bagian integral dari penulisan ulang tumpukan jaringan di Linux kernel 2.2." Dan dari ip(8): " ipditulis oleh Alexey N. Kuznetsof dan ditambahkan di Linux 2.2."
Jander
Ini adalah salah satu penjelasan terbaik dari beberapa tabel routing kernel yang pernah saya lihat. Terima kasih!
djluko
1

Konfigurasi pemfilteran jalur balik Anda mungkin adalah masalahnya. RFC3704 - bagian 2.4

Dalam distribusi Enterprise Linux (RHEL, CentOS, Scientific Linux, et al) cara terbaik yang mungkin untuk menyelesaikan ini adalah dengan memodifikasi /etc/sysctl.confdenganrp_filter = 2

Ketika RHEL memiliki beberapa IP yang dikonfigurasi, hanya satu yang dapat dijangkau dari jaringan jarak jauh. Atau mengapa RHEL mengabaikan paket ketika rute untuk lalu lintas keluar berbeda dari rute lalu lintas masuk?

0xSheepdog
sumber
Jika saya menggunakan cek RPF longgar (2) atau bahkan menonaktifkan pemeriksaan RPF (0) bersamaan dengan for rp_filter_file in /proc/sys/net/ipv4/conf/*/rp_filter; do echo 0 > "$rp_filter_file"; donekernel tidak menggunakan eth0antarmuka untuk paket routing ke 192.168.1.1. Hanya sekali saya menghapus tun0antarmuka dengan ip link del dev tun0kernel mulai menggunakan eth0antarmuka.
Martin