Linux

在虛擬 IP 上發送的數據包不符合 iptables 規則

  • May 21, 2020

我有一個eth1:3帶有 IP 地址的虛擬介面222.192.124.3,我設置了一個 iptables 規則來使用介面的 IP 記錄來自該介面的數據包(我知道 iptables 不關心虛擬介面標籤),如下所示:

iptables -A INPUT -d 222.192.124.3 -j LOG --log-level warning --log-prefix "VIP3-IN: "

當我執行 tcpdump 並從另一台機器在此 IP 上發送數據包時,我看到了它們,所以我假設它們已被核心正確接收和處理,但 iptables 從不記錄這些數據包,並且當我執行時iptables -nvL,該規則的數據包計數是’沒有增加,就像他們從未達到規則一樣(或者就像 iptables 甚至沒有看到該介面上的數據包)。

我首先想到了另一個匹配數據包的規則,因此在它遇到 LOG 規則之前對其進行了處理,所以我刪除了每個 iptables 規則並只添加了日誌記錄規則,但沒有成功。

伺服器在 RHEL 6.2 上執行,核心為 2.6.32,在 VMware ESX 上虛擬化。

這是完整的輸出iptables -nvL

Chain INPUT (policy ACCEPT 40 packets, 2891 bytes)
 pkts bytes target     prot opt in     out     source               destination
 0     0    LOG        all  --  *      *       0.0.0.0/0            222.192.124.3 LOG flags 0 level 4 prefix `VIP3-IN: '

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 34 packets, 3816 bytes)
 pkts bytes target     prot opt in     out     source               destination

這是 tcpdump 輸出的範例,顯示了傳入的數據包 ( tcpdump -n -nn -vvv -i eth1 "host 203.0.59.135"):

10:26:01.259409 IP (tos 0x50, ttl 121, id 26746, offset 0, flags [DF], proto TCP (6), length 52)
   203.0.59.135.62332 > 222.192.124.3.8888: Flags [S], cksum 0x8da8 (correct), seq 3373891789, win 8192, options [mss 1460,nop,wscale 8,nop,nop,sackOK], length 0

最後,ifconfig eth1:3輸出:

eth1:3    Link encap:Ethernet  HWaddr 00:50:56:AC:35:35
     inet addr:222.192.124.3  Bcast:222.192.127.255  Mask:255.255.252.0
     UP BROADCAST RUNNING PROMISC MULTICAST  MTU:1500  Metric:1

更新:

iptables 圖

(來源:austintek.com

在上圖的幫助下,我在不同的表中設置了 iptables 規則,以查看數據包的去向。我想出了以下腳本:

IPT_FILTER="iptables -t filter"
IPT_MANGLE="iptables -t mangle"
IPT_NAT="iptables -t nat"

$IPT_FILTER -F
$IPT_FILTER -X
$IPT_FILTER -A INPUT -d 222.192.124.0/22 -j LOG --log-prefix "DEBUG filter: "
$IPT_FILTER -Z

$IPT_MANGLE -F
$IPT_MANGLE -X
$IPT_MANGLE -A PREROUTING -d 222.192.124.0/22 -j LOG --log-prefix "DEBUG mangle/prerouting: "
$IPT_MANGLE -A INPUT -d 222.192.124.0/22 -j LOG --log-prefix "DEBUG mangle/input: "
$IPT_MANGLE -Z

$IPT_NAT -F
$IPT_NAT -X
$IPT_NAT -A PREROUTING -d 222.192.124.0/22 -j LOG --log-prefix "DEBUG nat/prerouting: "
$IPT_NAT -Z

似乎數據包通過mangle/PREROUTINGandnat/PREROUTING表,但沒有命中mangle/INPUT表,所以我猜它需要“防火牆數據”上的“否”分支。而且絕不是網路或系統專家(最多是高級使用者),這就是我迷路並且不明白髮生了什麼的地方……

最終編輯(解決方案)

正如@nodens 在他們的回答中所建議的那樣,問題是由 RPF 處於“嚴格”模式引起的……對於這樣一個簡單的設置來說真是令人頭疼……

您確定其他表中沒有匹配規則,例如 mangle 或 nat 嗎?您還可以嘗試記錄 INPUT 中的每個 paquet,或者更好的是,嘗試原始表(PREROUTING 鏈)中的 TRACE 目標,如果在 RHEL 6 上可用的話

編輯(我還不能添加評論):

好的,所以數據包到達了介面,但它不被認為是應該在本地處理的。檢查您的路由表,也許您沒有到該網路的範圍連結路由,或者由於 RPF 過濾器而核心丟棄了數據包(這可能取決於網路拓撲):檢查https://access.redhat .com/site/solutions/53031

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