Linux không trả lời tin nhắn yêu cầu ARP nếu địa chỉ IP được yêu cầu được liên kết với giao diện (bị tắt) khác


9

Tôi có một PC (kernel 3.2.0-23-generic ) đã được 192.168.1.2/24cấu hình để eth0giao diện và cũng sử dụng 192.168.1.1192.168.1.2địa chỉ cho tun0giao diện:

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:~# 

Như đã thấy ở trên, tun0bị vô hiệu hóa về mặt hành chính ( ip link set dev tun0 down). Bây giờ khi tôi nhận được yêu cầu ARP 192.168.1.2, PC không trả lời các yêu cầu đó:

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:~#

Chỉ sau khi tôi xóa các tun0giao diện ( ip link del dev tun0) PC sẽ trả lời yêu cầu ARP cho 192.168.1.2trên eth0giao diện.

Bảng định tuyến trông giống hệt nhau trước và sau 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:~# 

Mục định tuyến dưới đây đã được gỡ bỏ bằng ip link set dev tun0 downlệnh:

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

Tuy nhiên, trong khi các bảng định tuyến hoàn toàn giống nhau trước và sau ip link del dev tun0lệnh, hạt nhân quyết định định tuyến thực tế sẽ không:

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:~# 

Đây có phải là một hành vi dự kiến? Tại sao kernel bỏ qua bảng định tuyến?


Bạn có thể dán đầu ra của netstat -rn cho cả hai trường hợp không? Bảng định tuyến thường là nơi đầu tiên để tìm các loại lỗi này.
Clarus

@Claris Tôi đã cập nhật bài viết ban đầu của tôi.
Martin

Có cùng một IP trên hai giao diện có thể tạo ra các vấn đề và tốt nhất nên tránh, điều đó được nói rằng bạn sẽ có thể theo dõi vấn đề. Bước tiếp theo là xem xét bộ đệm arp, arp -a có hiển thị gì hữu ích không?
Clarus

@Claris Hình như nguyên nhân gốc là kernel bỏ qua bảng định tuyến khi tun0giao diện bị vô hiệu hóa, nhưng hiện tại. Xem đầu ra của ip route getcác lệnh trong bài viết ban đầu được cập nhật của tôi. Tuy nhiên, tại sao kernel lại hành xử như vậy?
Martin

Câu trả lời:


17

Bảng định tuyến của bạn không bị bỏ qua, chính xác. Nó đang bị ghi đè bởi một bảng định tuyến ưu tiên cao hơn.

Chuyện gì đang xảy ra

Bảng định tuyến bạn thấy khi bạn nhập ip route showkhông phải là bảng định tuyến duy nhất mà kernel sử dụng. Trong thực tế, có ba bảng định tuyến theo mặc định và chúng được tìm kiếm theo thứ tự được hiển thị bởi ip rulelệnh:

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

Bảng mà bạn quen thuộc nhất là main, nhưng bảng định tuyến ưu tiên cao nhất là local. Bảng này được quản lý bởi kernel để theo dõi các tuyến địa phương và quảng bá: nói cách khác, localbảng cho hạt nhân biết cách định tuyến đến các địa chỉ của các giao diện của chính nó. Nó trông giống như thế này:

# 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

Kiểm tra tham chiếu dòng đó tun0. Đó là những gì gây ra kết quả kỳ lạ của bạn từ route get. Nó nói 192.168.1.1 là một địa chỉ cục bộ, có nghĩa là nếu chúng tôi muốn gửi trả lời ARP tới 192.168.1.1, thật dễ dàng; chúng tôi gửi nó cho chính chúng ta. Và vì chúng tôi đã tìm thấy một tuyến đường trong localbảng, chúng tôi dừng tìm kiếm tuyến đường và không bận tâm kiểm tra các bảng mainhoặc default.

Tại sao nhiều bảng?

Ở mức tối thiểu, thật tuyệt khi có thể nhập ip routevà không thấy tất cả các tuyến đường "rõ ràng" đó làm lộn xộn màn hình (thử gõ route printtrên máy Windows). Nó cũng có thể phục vụ như một số bảo vệ tối thiểu chống lại cấu hình sai: ngay cả khi bảng định tuyến chính bị lẫn lộn, kernel vẫn biết cách nói chuyện với chính nó.

(Tại sao giữ các tuyến cục bộ ở vị trí đầu tiên? Vì vậy, kernel có thể sử dụng cùng mã tra cứu cho các địa chỉ cục bộ giống như mọi thứ khác. Nó làm cho mọi thứ đơn giản hơn trong nội bộ.)

Có những điều thú vị khác bạn có thể làm với sơ đồ nhiều bảng này. Cụ thể, bạn có thể thêm các bảng của riêng mình và chỉ định quy tắc khi chúng được tìm kiếm. Đây được gọi là "định tuyến chính sách" và nếu bạn đã từng muốn định tuyến gói dựa trên địa chỉ nguồn của nó , thì đây là cách thực hiện trong Linux.

Nếu bạn đang thực hiện những điều đặc biệt khó khăn hoặc thử nghiệm, bạn có thể tự thêm hoặc xóa localcác tuyến đường bằng cách chỉ định table localtrong ip routelệnh. Trừ khi bạn biết những gì bạn đang làm, mặc dù, bạn có thể nhầm lẫn kernel. Và tất nhiên, kernel vẫn sẽ tiếp tục thêm và xóa các tuyến riêng của nó, vì vậy bạn phải xem để đảm bảo rằng kernel của bạn không bị ghi đè.

Cuối cùng, nếu bạn muốn xem tất cả các bảng định tuyến cùng một lúc:

# ip route show table all

Để biết thêm thông tin, hãy xem ip-rule(8)trang man hoặc tài liệu iproute2 . Bạn cũng có thể thử Điều khiển lưu lượng và định tuyến nâng cao HOWTO cho một số ví dụ về những gì bạn có thể làm.


Cảm ơn! Sau khi ip link set dev tun0 downcác local 192.168.1.1 dev tun0 proto kernel scope host src 192.168.1.1quy tắc đã thực sự vẫn còn hiện diện trong localrouting-table. Khi tôi thực hiện ip link del dev tun0quy tắc được đề cập đã được gỡ bỏ. Tuy nhiên, một câu hỏi - tôi có đúng không khi tất cả các nhân Linux hiện đại (2.6.x, 3.x, 4.x) sử dụng RPDB để tra cứu tuyến đường và do đó có nhiều bảng?
Martin

2
Vâng, bạn đúng và nhiều hơn nữa. RPDB là đáng ngạc nhiên cũ! "Bản thân RPDB là một phần không thể thiếu trong việc viết lại ngăn xếp mạng trong nhân Linux 2.2." Và từ ip(8): " ipđược viết bởi Alexey N. Kuznetsof và được thêm vào Linux 2.2."
Jander

Đây là một trong những giải thích tốt nhất về các bảng định tuyến nhiều kernel mà tôi đã thấy. Cảm ơn!
djluko

1

Cấu hình lọc đường dẫn ngược của bạn có lẽ là vấn đề. RFC3704 - phần 2.4

Trong các bản phân phối Enterprise Linux (RHEL, CentOS, Science Linux, et al), cách tốt nhất có thể để giải quyết vấn đề này là sửa đổi /etc/sysctl.confvớirp_filter = 2

Khi RHEL có nhiều IP được cấu hình, chỉ có thể truy cập một IP từ một mạng từ xa. Hoặc tại sao RHEL bỏ qua các gói khi tuyến đường cho lưu lượng truy cập đi khác với tuyến đường của lưu lượng đến?


Nếu tôi sử dụng kiểm tra RPF lỏng lẻo (2) hoặc thậm chí vô hiệu hóa kiểm tra RPF (0) hoàn toàn với for rp_filter_file in /proc/sys/net/ipv4/conf/*/rp_filter; do echo 0 > "$rp_filter_file"; donekernel không sử dụng eth0giao diện để định tuyến các gói đến 192.168.1.1. Chỉ một lần tôi xóa tun0giao diện với ip link del dev tun0kernel bắt đầu sử dụng eth0giao diện.
Martin
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.