Linux
為什麼網路堆棧忽略來自非預設介面的 icmp 回复?
我有以下情況:
- eth0 - 預設網關 (ip: 172.28.183.100, gw: 172.28.183.1)
- eth0 - 輔助網路連接(ip:172.28.171.2,gw:172.28.171.2)。
路由看起來像這樣:
Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 172.28.183.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 172.28.171.0 0.0.0.0 255.255.255.0 U 0 0 0 eth2 172.28.173.0 0.0.0.0 255.255.255.0 U 0 0 0 eth1 78.46.78.0 172.28.171.1 255.255.255.0 UG 0 0 0 eth2 169.254.0.0 0.0.0.0 255.255.0.0 U 1000 0 0 eth0 0.0.0.0 172.28.183.1 0.0.0.0 UG 100 0 0 eth0
如您所見,78.46.78.0/24 有一條特殊路由 - 此流量應通過輔助網路 eth2。
哪個有效。我可以對 78.46.78.0/24 中的機器進行任何類型的 tcp 連接。
但是,當我嘗試 mtr 時,我得到了奇怪的結果:
root@blob:~# mtr --report --report-cycles=5 78.46.78.198 HOST: blob Loss% Snt Last Avg Best Wrst StDev 1. 172.28.171.1 0.0% 5 0.6 0.6 0.5 0.6 0.0 2. ??? 100.0 5 0.0 0.0 0.0 0.0 0.0
在 tcpdump 輸出中,我看到超過生存時間的返回回复:
10:16:28.158888 IP 172.28.171.2 > 78.46.78.198: ICMP echo request, id 2092, seq 59520, length 44 10:16:28.159363 IP 172.28.171.1 > 172.28.171.2: ICMP time exceeded in-transit, length 72 10:16:28.259153 IP 172.28.171.2 > 78.46.78.198: ICMP echo request, id 2092, seq 59776, length 44 10:16:28.359546 IP 172.28.171.2 > 78.46.78.198: ICMP echo request, id 2092, seq 60032, length 44 10:16:28.408129 IP 10.9.208.1 > 172.28.171.2: ICMP time exceeded in-transit, length 36 10:16:28.428193 IP 10.9.208.2 > 172.28.171.2: ICMP time exceeded in-transit, length 36 10:16:28.459953 IP 172.28.171.2 > 78.46.78.198: ICMP echo request, id 2092, seq 60288, length 44 10:16:28.560260 IP 172.28.171.2 > 78.46.78.198: ICMP echo request, id 2092, seq 60544, length 44 10:16:28.618138 IP 10.9.213.6 > 172.28.171.2: ICMP time exceeded in-transit, length 36 10:16:28.660678 IP 172.28.171.2 > 78.46.78.198: ICMP echo request, id 2092, seq 60800, length 44 10:16:28.708130 IP 10.9.212.253 > 172.28.171.2: ICMP time exceeded in-transit, length 36 10:16:28.730193 IP 213.158.195.13 > 172.28.171.2: ICMP time exceeded in-transit, length 36 10:16:28.761086 IP 172.28.171.2 > 78.46.78.198: ICMP echo request, id 2092, seq 61056, length 44 10:16:28.861380 IP 172.28.171.2 > 78.46.78.198: ICMP echo request, id 2092, seq 61312, length 44 10:16:28.938167 IP 213.248.89.153 > 172.28.171.2: ICMP time exceeded in-transit, length 36
但是,在 mtr 上使用 strace,我看到這些 ICMP 回复沒有發送到 mtr!
我認為原因可能是 icmp 響應的源 ip 來自“錯誤”介面” - 即 ICMP 回復來自(例如)10.9.212.253(一些中間路由器),但是這個 ip 應該通過 eth0 路由,而它涉及到 eth2。
這是合理的理由嗎?我該怎麼做才能使 mtr 甚至對我的“特殊”網路也能正常工作?
iptables 設置使用:
iptables -P INPUT DROP iptables -P FORWARD DROP iptables -P OUTPUT ACCEPT iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -A INPUT -i lo -j ACCEPT iptables -A INPUT -i eth1 -j ACCEPT iptables -A INPUT -p icmp -j ACCEPT iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -A FORWARD -i eth1 -j ACCEPT iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE iptables -t nat -A POSTROUTING -o eth2 -j MASQUERADE iptables -A INPUT -j LOG --log-prefix 'IPTABLES: ' iptables -A FORWARD -j LOG --log-prefix 'IPTABLES: '
但是我沒有看到任何帶有 kern.log 的與 icmp 相關的包。
感謝 Rafał Ramocki - 解決方案很簡單 - 你必須在 eth2 介面上關閉 rp_filter-ing:
echo 0 > /proc/sys/net/ipv4/conf/eth2/rp_filter
來自核心文件:
rp_filter --------- Integer value determines if a source validation should be made. 1 means yes, 0 means no. Disabled by default, but local/broadcast address spoofing is always on. If you set this to 1 on a router that is the only connection for a network to the net, it will prevent spoofing attacks against your internal networks (external addresses can still be spoofed), without the need for additional firewall rules.
雖然可以很好地防止欺騙攻擊(至少是一些),但如果您有更多的網際網路連接,它肯定會扼殺一些功能。