Networking

Linux伺服器忽略來自網關的數據包

  • January 30, 2022

我有一個 Proxmox Linux 伺服器,它能夠向本地網路上的主機發送和接收數據包,但不會處理來自網關的數據包。這會導致網際網路流量失敗,因此我無法執行 apt 來更新軟體包。所有協議似乎都受到影響。

伺服器上執行的虛擬機可以正常訪問網關。

我的 /etc/network/interfaces 文件包含:

auto lo
iface lo inet loopback

iface enp10s0 inet manual

auto vmbr0
iface vmbr0 inet static
   address 10.0.1.200/24
   gateway 10.0.1.1
   bridge_ports enp10s0
   bridge_stp off
   bridge_fd 0

auto wlp7s0
iface wlp7s0 inet static
   hostapd /etc/hostapd/hostapd.conf
   address 10.0.2.1
   netmask 255.255.255.0

auto vmbr1
iface vmbr1 inet static
   address 10.1.2.1
   netmask 255.255.255.0
   bridge_ports none
   bridge-stp off
   bridge-fd 0

   post-up   echo 1 > /proc/sys/net/ipv4/ip_forward
   post-up   iptables -t nat -A POSTROUTING -s '10.1.2.0/24' -o wlp7s0 -j MASQUERADE
   post-down iptables -t nat -D POSTROUTING -s '10.1.2.0/24' -o wlp7s0 -j MASQUERADE

wlp7s0 和 vmbr1 進行了 NAT,以允許 VM 訪問不應訪問一般網路/網際網路的無線 IOT 設備。

我的路由表:

$ ip route
default via 10.0.1.200 dev vmbr0 metric 100 
10.0.1.0/24 dev vmbr0 proto kernel scope link src 10.0.1.200 
10.0.2.0/24 dev wlp7s0 proto kernel scope link src 10.0.2.1 
10.1.2.0/24 dev vmbr1 proto kernel scope link src 10.1.2.1

經過一番閱讀,我嘗試更改 rp_filter,但將值從 2 更改為 0 並沒有幫助。預設設置(移除 VM 介面):

$ sysctl -a | grep \\.rp_filter
net.ipv4.conf.all.rp_filter = 2
net.ipv4.conf.default.rp_filter = 0
net.ipv4.conf.enp10s0.rp_filter = 0
net.ipv4.conf.lo.rp_filter = 0
net.ipv4.conf.vmbr0.rp_filter = 0
net.ipv4.conf.vmbr1.rp_filter = 0
net.ipv4.conf.wlp7s0.rp_filter = 0

ip_forward 已設置:

$ cat /proc/sys/net/ipv4/ip_forward
1

我已通過 tcpdump 驗證,當我嘗試從伺服器 ping 到網關或從伺服器到網關時,正在從網關接收數據包。此範例使用 ping:

# tcpdump -n -i vmbr0 host 10.0.1.1 and icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on vmbr0, link-type EN10MB (Ethernet), capture size 262144 bytes
22:42:37.136341 IP 10.0.1.200 > 10.0.1.1: ICMP echo request, id 22073, seq 1, length 64
22:42:37.136478 IP 10.0.1.1 > 10.0.1.200: ICMP echo reply, id 22073, seq 1, length 64
22:42:38.142240 IP 10.0.1.200 > 10.0.1.1: ICMP echo request, id 22073, seq 2, length 64
22:42:38.142429 IP 10.0.1.1 > 10.0.1.200: ICMP echo reply, id 22073, seq 2, length 64

ping -v 的輸出只是空的:

$ ping -v 10.0.1.1
PING 10.0.1.1 (10.0.1.1) 56(84) bytes of data.
^C
--- 10.0.1.1 ping statistics ---
22 packets transmitted, 0 received, 100% packet loss, time 511ms

ip 表中的唯一條目是 NAT:

# iptables-save -c
# Generated by iptables-save v1.8.2 on Sat Jan 29 22:45:46 2022
*raw
:PREROUTING ACCEPT [1828405583:1847667077335]
:OUTPUT ACCEPT [10762322:981310704]
COMMIT
# Completed on Sat Jan 29 22:45:46 2022
# Generated by iptables-save v1.8.2 on Sat Jan 29 22:45:46 2022
*filter
:INPUT ACCEPT [10597558:1212589593]
:FORWARD ACCEPT [1782904005:1841102268241]
:OUTPUT ACCEPT [10762351:981313827]
COMMIT
# Completed on Sat Jan 29 22:45:46 2022
# Generated by iptables-save v1.8.2 on Sat Jan 29 22:45:46 2022
*nat
:PREROUTING ACCEPT [29808561:4940456833]
:INPUT ACCEPT [2456738:231340403]
:OUTPUT ACCEPT [1168080:75403202]
:POSTROUTING ACCEPT [2829337:181352732]
[190:11400] -A POSTROUTING -s 10.1.2.0/24 -o wlp7s0 -j MASQUERADE
COMMIT
# Completed on Sat Jan 29 22:45:46 2022

感謝 Nikita Kipriyanov 為我指明了正確的方向,我已經解決了這個問題。

跑步時

tcpdump -en host 10.0.1.1

我注意到 ping 響應來自系統上不存在的介面:

# tcpdump -en host 10.0.1.1
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on enp10s0, link-type EN10MB (Ethernet), capture size 262144 bytes
10:01:49.233889 24:4b:fe:4a:11:96 > 02:29:9a:f3:0a:00, ethertype IPv4 (0x0800), length 98: 10.0.1.200 > 10.0.1.1: ICMP echo request, id 5544, seq 1, length 64
10:01:49.234053 02:29:9a:f3:0a:00 > 00:26:18:e2:68:f9, ethertype IPv4 (0x0800), length 98: 10.0.1.1 > 10.0.1.200: ICMP echo reply, id 5544, seq 1, length 64

這意味著系統在 tcpdump 下看到了具有正確 IP 地址的傳入數據包,但正確地忽略了它們以根據 MAC 地址進行處理。

我檢查了網關路由器上的配置,發現它有一個固定的 ARP 條目,地址錯誤(可能是舊配置)。將網關設置更改為 enp10s0 的 MAC 地址解決了該問題。

引用自:https://serverfault.com/questions/1091568