之前介绍过通过 dnsmasq 配合 iptables 实现对 ip 地址的流量过滤,dnsmasq 获取到流量后标记 ipset 然后通过 iptables 识别 ipset 然后将流量送往指定地址。

通过 dnsmasq ipset 和 iptables 对域名流量的控制
iptables 使用教程

这里面存在一个问题就是流量回环问题,如果处理不好回导致 iptables 规则无限循环,尤其是在配置透明代理时候。

iptables -t mangle -A PREROUTING -p tcp -m set --match-set gfwlist dst -j TPROXY --on-port 1081 --tproxy-mark 1
iptables -t mangle -A PREROUTING -p udp -m set --match-set gfwlist dst -j TPROXY --on-port 1081 --tproxy-mark 1
iptables -t mangle -A OUTPUT -p tcp -m set --match-set gfwlist dst -j MARK --set-mark 1
iptables -t mangle -A OUTPUT -p udp -m set --match-set gfwlist dst -j MARK --set-mark 1

以上规则会将 指定 list 的流量发送到指定端口并打上 mark 标记,但是从目标地址返回数据后,数据流会再次匹配到以上规则导致再次将流量送往指定端口,导致无限循环。

处理方法就是在目标地址获取到流量后,给流量打上 mark 标记,然后在 iptables 的最前面加上一条规则识别从目标地址返回的流量,直接 return 流量即可。

例如目标地址处理后的流量标记为 mark 2,iptables 规则最前面增加一条规则:

iptables -t mangle -I OUTPUT -j RETURN -m mark --mark 0x02

-I 参数就是将规则放在在路由链的最前面。

如果是通过脚本的方式配置 iptables,将开始的脚本内容修改如下即可:

iptables -t mangle -A OUTPUT -j RETURN -m mark --mark 0x02

iptables -t mangle -A PREROUTING -p tcp -m set --match-set gfwlist dst -j TPROXY --on-port 1081 --tproxy-mark 1
iptables -t mangle -A PREROUTING -p udp -m set --match-set gfwlist dst -j TPROXY --on-port 1081 --tproxy-mark 1
iptables -t mangle -A OUTPUT -p tcp -m set --match-set gfwlist dst -j MARK --set-mark 1
iptables -t mangle -A OUTPUT -p udp -m set --match-set gfwlist dst -j MARK --set-mark 1

这样就可以避免流量回环问题。

标签:无

你的评论