偶然發現 RHEL 的一個詭異現象,如果在有兩個活躍網路裝置的情況下,分到同一個段的 IP 地址,那麼之後最後發出 DHCP DISCOVER 的裝置的 IP 可以被 ping 通;但是從系統發出去的包通過兩個 IP 都可以被對方收到。一開始懷疑是防火牆的問題,但是完全關閉後依然沒有解決。後來和一名 Kernel QE 交流,給到的答覆是把 rp_filter 設定爲 0,運行
# echo "0">/proc/sys/net/ipv4/conf/all/rp_filter
就可以解決了。
關於 rp_filter,在 Kernel 的 ip-sysctl 文檔以及 TLDP 的高階路由設定章節都有說明,作用是驗證反向網路包的流向,以期阻止僞裝 IP、DDoS 等攻擊。
rp_filter - INTEGER 0 - No source validation. 1 - Strict mode as defined in RFC3704 Strict Reverse Path Each incoming packet is tested against the FIB and if the interface is not the best reverse path the packet check will fail. By default failed packets are discarded. 2 - Loose mode as defined in RFC3704 Loose Reverse Path Each incoming packet's source address is also tested against the FIB and if the source address is not reachable via any interface the packet check will fail. Current recommended practice in RFC3704 is to enable strict mode to prevent IP spoofing from DDos attacks. If using asymmetric routing or other complicated routing, then loose mode is recommended. The max value from conf/{all,interface}/rp_filter is used when doing source validation on the {interface}. Default value is 0. Note that some distributions enable it in startup scripts.
Kernel 文檔中說明,預設應該是 0,即不驗證反向路徑。但是十幾測試了一下,在 Debian 上預設確實爲 0 即不驗證;在 Fedora Server 上預設卻是 1 即嚴格驗證,任何反向路徑非最佳路由路徑的資料包都會被丟棄,可以說是很安全了,但同時也會導致一些令人頭凸的問題。