為什麼某些 iptables DNAT 規則在重新啟動之前不起作用?
我的 iptables DNAT 規則在重新啟動之前不起作用。如果我重新啟動伺服器,所有規則都會起作用。
架構描述:
數十台主機(發送方)向我的 Linux 路由器發送一些 UDP 數據包(在特定埠 9999 上單向)。這個 Linux 路由器使用 iptables 將這些數據包轉發到多個主機(接收器)。
senderX 10.0.0.X ====> 帶有 iptables 的 Linux 路由器 ====> receiverY 10.0.1.Y
linux路由器有兩個網卡eth1 10.0.0.1/24(發送方)和eth0 10.0.1.1/24(接收方)。
iptables 設置:
- ip_forwarding 已啟動
- 所有預設策略都設置為接受
- 每個發件人存在一個 iptables 規則,這是一個範例:
iptables -t nat -A PREROUTING -s 10.0.0.2 -i eth1 -j DNAT --to-destination 10.0.1.123
網路設置 :
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 mq state UP qlen 1000 link/ether 54:9f:35:0a:16:38 brd ff:ff:ff:ff:ff:ff inet 10.0.1.1/24 brd 10.0.1.255 scope global eth0 inet6 fe80::569f:35ff:fe0a:1638/64 scope link valid_lft forever preferred_lft forever 3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000 link/ether 54:9f:35:0a:16:3a brd ff:ff:ff:ff:ff:ff inet 10.0.0.1/24 brd 10.0.0.255 scope global eth1 inet6 fe80::569f:35ff:fe0a:163a/64 scope link valid_lft forever preferred_lft forever
症狀:
添加一組規則後,某些規則不起作用。我可以通過 tcpdump 看到 UDP 數據包不再被路由並且數據包被拒絕。
tcpdump -n -i eth1 host 10.0.0.2 tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on eth1, link-type EN10MB (Ethernet), capture size 65535 bytes 16:12:58.241225 IP 10.0.0.2.56859 > 10.0.0.1.9999: UDP, length 1464 16:12:58.241285 IP 10.0.0.1 > 10.0.0.2: ICMP 10.0.0.1 udp port 9999 unreachable, length 556
- 如果我刷新所有規則並將它們重新註入 iptables,則不起作用的規則仍然不起作用。
- 如果我重新啟動伺服器,所有規則都可以正常工作。
分析完成:
我添加了一個規則來記錄一個不工作的特定發件人:
iptables -t nat -A PREROUTING -s 10.0.0.2 -i eth1 -j LOG --log-prefix='PREROUTING LOG :'
但是這條規則不記錄任何東西。數據包來了,因為我在 tcpdump 中看到了那些,但它們沒有被記錄。同樣使用
-v
iptables 中的選項,我看不到此規則的計數器增加。如果我在它停止工作之前應用相同的規則,我有一些日誌。
問題 :
- iptables 中的 UDP 轉發是否有任何限制?
- 我該如何解決這個問題?
您描述的症狀與 NAT 規則和連接跟踪條目之間存在衝突時看到的症狀相匹配。
例如,當一個數據包被匹配時
-A PREROUTING -s 10.0.0.2 -i eth1 -j DNAT --to-destination 10.0.1.123
需要創建一個新的連接跟踪條目。這會將傳入端的源和目標 IP 和埠的元組映射到傳出端的類似元組。
不能存在與傳入端匹配的現有連接跟踪條目,因為如果存在,它將被使用而不是規則。但是,一旦元組的目標 IP 已被替換以構造傳出方的元組,該元組可能與現有的連接跟踪條目發生衝突。
如果您安裝該
conntrack
實用程序,您可以鍵入conntrack -L
以查看現有連接跟踪條目的列表。該實用程序還具有僅列出與特定條件匹配的連接跟踪條目以及刪除選定條目的功能。如果這確實是您面臨的問題,那麼刪除有問題的連接跟踪條目將使問題消失。永久修復通常涉及為兩個方向的數據包配置相關的 NAT 規則,以便您始終獲得所需的連接跟踪條目,即使第一個數據包碰巧以與通常情況相反的方向發送。