标记的数据包未按预期路由


0

更新:解决方案:我本应该使用OUTPUT链 - 而不是PREROUTING链。这个例子仍然不起作用,但我会尽快更新。

在我看来,这似乎应该有效。我将所有路由规则从主表移动到表4然后MARK并将发往端口80/443的数据包定向到表4.我希望端口80的工作方式与我没有做任何事情一样,但gethostbyname失败了吗?

#!/bin/bash -x
#
# Reset/Flush iptables
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT

# Reset/Flush table 4
ip route flush table 4

# move all routing rules from the main table to table 4
ip route show table main | grep -v linkdown |
while read ROUTE
do
  ip route add table 4 $ROUTE
  ip route del table main $ROUTE
done

# MARK all HTTP(S) destination packets with a 4
iptables -t mangle -A PREROUTING -p tcp --dport 80  -j MARK --set-mark 4
iptables -t mangle -A PREROUTING -p tcp --dport 443 -j MARK --set-mark 4
iptables -t mangle -A PREROUTING -p udp --dport 53  -j MARK --set-mark 4

# packets marked as 4 find their routes via table 4
ip rule add fwmark 4 table 4
ip route flush cache

1
您的iptables规则将无法访问,因为主表中没有路由。因为它们不会执行,所以它们永远不会设置标记告诉使用表4.所以你没有任何路线......现在你能告诉你实际上打算用这一切解决什么问题吗?
AB于19年

那么在路由预执行之前必须找到一条路线?这似乎是错误的事情,因为规则可以做一些改变路由的事情(就像在我的情况下)?
GroovyDotCom

至于问题:我需要通过TUN设备为HTTP,DNS之外的所有端口做透明代理。所以这意味着如果一个应用程序向foo.com发送了一些内容:22它需要实际转到TUN设备,我的代理应用程序需要真正发送到foo.com:22。所以上面没有显示的是main中的默认规则,它将所有内容发送到我的TUN设备。所以我在主表中确实有一条路线,但它没有帮助。
GroovyDotCom

好的。我现在明白了。我本来应该使用OUTPUT链 - 而不是PREROUTING链。
GroovyDotCom

在回答之前我也试过了。没变。如果没有路由,则不使用PREROUTING,也不使用OUTPUT。你应该投资iptables'TPROXY,看看你能用它做什么。或者你可以保持主要路线,因此iptables应该触发,设置fwmark,最后将使用表4
AB

Answers:


2

iptables(和/或netfilter)在路由堆栈中有各种钩子。当数据包通过路由堆栈中的某个步骤时,如果有一个iptables挂钩,则运行iptables的hook。当然,如果数据包没有达到这样的步骤,则不运行iptables挂钩。如果存在“无主机路由”,则路由堆栈会提前放弃,但不会达到这些步骤。这是你删除(主表的)路由并留下依赖于iptables的路由表之后在你的例子中发生的事情。这是一个鸡和蛋的问题,但不需要这样做。您只需要一条路线,任何路线,这样您的规则就会触发并改变这条路线。

我运行了你的脚本,并得到了我的设置:

# ip route
(nothing)
# ip route show table 4
default via 10.0.3.1 dev eth0 
10.0.3.0/24 dev eth0 proto kernel scope link src 10.0.3.66 

添加了OUTPUT规则:

iptables -t mangle -A OUTPUT -p udp -m udp --dport 53 -j MARK --set-xmark 0x4/0xffffffff
iptables -t mangle -A OUTPUT -p tcp -m tcp --dport 53 -j MARK --set-xmark 0x4/0xffffffff
iptables -t mangle -A OUTPUT -p tcp -m tcp --dport 443 -j MARK --set-xmark 0x4/0xffffffff
iptables -t mangle -A OUTPUT -p tcp -m tcp --dport 80 -j MARK --set-xmark 0x4/0xffffffff

什么都行不通。

添加了LAN路由和一个不存在的虚假错误网关10.0.3.9:

# ip route
default via 10.0.3.9 dev eth0 
10.0.3.0/24 dev eth0 scope link 

# ip neigh flush dev eth0
# ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
^C
--- 8.8.8.8 ping statistics ---
2 packets transmitted, 0 received, 100% packet loss, time 1006ms
# ip neigh
10.0.3.9 dev eth0  FAILED
# ip neigh del 10.0.3.9 dev eth0
# dig +short @8.8.8.8 google.com.
172.217.22.142
# ip neigh
10.0.3.1 dev eth0 lladdr fe:d6:50:75:27:c9 REACHABLE

请注意,现在使用了表4中的路由。但它首先需要一个工作路线(“即使没有真正起作用”在纸上),否则单独的路由决定将阻止OUTPUT规则的使用。您可以iptables-save -c通过查看计数器来查看它。


非常正确。改为OUTPUT解决了我的问题,因为那里确实有一个地址。我没有在我的问题中显示它,因为我试图做一个较小的问题示例,并没有想象这个细节是相关的。谢谢!
GroovyDotCom
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.