为什么 iptables mangle 表不捕获数据包?

为什么 iptables mangle 表不捕获数据包?

我正在尝试在 docker 容器中设置代理服务器,以便将一些数据包路由出 VPN(某些站点不响应 VPN 的 IP,它们已被国家/地区锁定)。为了做到这一点,我尝试标记发送到和来自 docker 容器接口的数据包。

我使用代理服务器容器连接到用户定义的桥接 docker 网络 (172.18.0.0/16),虚拟接口名为br-43cb854b8af8.我的 PC 上的物理网络接口的名称是enp3s0。还有标准的 docker 网桥接口,docker0网络为 172.17.0.0/16,因此虽然它包含在 iptables 规则中,但并未使用。

在 PC 开始时,raw 和 mangle 表是空的,

过滤表:

-P INPUT ACCEPT
-P FORWARD DROP
-P OUTPUT ACCEPT
-N DOCKER
-N DOCKER-ISOLATION-STAGE-1
-N DOCKER-ISOLATION-STAGE-2
-N DOCKER-USER
-A FORWARD -j DOCKER-USER
-A FORWARD -j DOCKER-ISOLATION-STAGE-1
-A FORWARD -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -o docker0 -j DOCKER
-A FORWARD -i docker0 ! -o docker0 -j ACCEPT
-A FORWARD -i docker0 -o docker0 -j ACCEPT
-A FORWARD -o br-43cb854b8af8 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -o br-43cb854b8af8 -j DOCKER
-A FORWARD -i br-43cb854b8af8 ! -o br-43cb854b8af8 -j ACCEPT
-A FORWARD -i br-43cb854b8af8 -o br-43cb854b8af8 -j ACCEPT
-A DOCKER -d 172.18.0.2/32 ! -i br-43cb854b8af8 -o br-43cb854b8af8 -p tcp -m tcp --dport 3128 -j ACCEPT
-A DOCKER-ISOLATION-STAGE-1 -i docker0 ! -o docker0 -j DOCKER-ISOLATION-STAGE-2
-A DOCKER-ISOLATION-STAGE-1 -i br-43cb854b8af8 ! -o br-43cb854b8af8 -j DOCKER-ISOLATION-STAGE-2
-A DOCKER-ISOLATION-STAGE-1 -j RETURN
-A DOCKER-ISOLATION-STAGE-2 -o docker0 -j DROP
-A DOCKER-ISOLATION-STAGE-2 -o br-43cb854b8af8 -j DROP
-A DOCKER-ISOLATION-STAGE-2 -j RETURN
-A DOCKER-USER -j RETURN

NAT表:

-P PREROUTING ACCEPT
-P INPUT ACCEPT
-P OUTPUT ACCEPT
-P POSTROUTING ACCEPT
-N DOCKER
-A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
-A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER
-A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE
-A POSTROUTING -s 172.18.0.0/16 ! -o br-43cb854b8af8 -j MASQUERADE
-A POSTROUTING -s 172.18.0.2/32 -d 172.18.0.2/32 -p tcp -m tcp --dport 3128 -j MASQUERADE
-A DOCKER -i docker0 -j RETURN
-A DOCKER -i br-43cb854b8af8 -j RETURN
-A DOCKER ! -i br-43cb854b8af8 -p tcp -m tcp --dport 3128 -j DNAT --to-destination 172.18.0.2:3128

问题是如果我添加

iptables -t mangle -A PREROUTING -i br-43cb854b8af8 -j MARK --set-mark 1
iptables -t mangle -A PREROUTING -i enp3s0 -s 172.18.0.0/16 -j MARK --set-mark 1

为了标记来自代理服务器的传出数据包,第二条规则不适用于任何数据包,而第一个规则则适用,并且伪装通过enp3s0也适用。换句话说,数据包按其应有的方式运行,但 iptables -t mangle -A PREROUTING -i enp3s0 -s 172.18.0.0/16 -j MARK --set-mark 1 由于某种原因未应用规则。除了默认的之外,也没有打开 VPN 或任何应用的 ip 路由或规则。

答案1

首先,正如问题评论中所回答的那样,第二条规则不适用,因为 -i 表示数据包是从接口接收的enp3s0。因此,为了标记来自代理的所有传出数据包,第一条规则就足够了。为了对传入的数据包执行相同的操作,我们需要添加

iptables -t mangle -A FORWARD -i enp3s0 -d 172.18.0.0/16 -j MARK --set-mark 1

因此,现在所有来自和来自的数据包br-43cb854b8af8都被标记(但从浏览器发送到代理的数据包),这是时间设置的路由。

第一组命令是

ip rule add to 172.18.0.0/16 pref 100 table 1
ip rule add fwmark 0x0001 pref 101 table 1
ip route add table 1 to 172.18.0.0/16 dev br-43cb854b8af8

它们允许来自浏览器的流量和代理的传入流量直接进入 Docker 网络。使用选项 pref 是因为 VPN 还设置了其规则,只有当上述规则不适用于数据包时我们才希望检查这些规则。

第二组命令是

ip rule add fwmark 0x0001 pref 102 table main

它设置它,以便如果数据包带有标记并且不前往 docker 的网络(这意味着它是从 docker 的网络传出),它将避开 VPN 规则并按其标准路由移动,无需 VPN。

最终剧本

#!/bin/sh

iptables -t mangle -A PREROUTING -i br-43cb854b8af8 -j MARK --set-mark 1
iptables -t mangle -A FORWARD -i enp3s0 -d 172.18.0.0/16 -j MARK --set-mark 1

ip rule add to 172.18.0.0/16 pref 100 table 1
ip rule add fwmark 0x0001 pref 101 table 1
ip route add table 1 to 172.18.0.0/16 dev br-43cb854b8af8

ip rule add fwmark 0x0001 pref 102 table main

ip route flush cache

相关内容