我正在尝试使用 iptables 实现透明的 http 代理。以下规则将流量从端口 80 重定向到 8080(代理正在监听的端口)
# iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080
这有效。我遇到的问题是它只适用于新连接。因此,我尝试强制现有连接重新连接,一旦连接,就允许流量。为了区分新连接和现有连接,我计划使用标记。
我正在尝试以下一组规则:
1 iptables -A INPUT -j CONNMARK --restore-mark
2 iptables -A INPUT -m state --state NEW -p tcp --dport 80 -j CONNMARK --set-mark 8
3 iptables -A INPUT -m state --state NEW -p tcp --dport 80 -j CONNMARK --save-mark
4 iptables -A INPUT -m state --state NEW -p tcp --dport 80 -j ACCEPT
5 iptables -A INPUT -p tcp -m state --state ESTABLISHED -m mark ! --mark 8 -j REJECT --reject-with tcp-reset
规则的目的如下:
- 恢复现有连接的任何标记
- 标记新连接
- 保存新连接的标记
- 接受新连接
- 如果未标记,则拒绝现有连接
但是,这组规则会导致拒绝所有新的或现有的连接。如果我反转拒绝标记包的规则,那么所有现有和新的连接都会被接受。因此,我猜想这些包并没有像我预期的那样被标记为用于新连接。
5 iptables -A INPUT -p tcp -m state --state ESTABLISHED -m mark --mark 8 -j REJECT --reject-with tcp-reset
注意:即使文档指出
The CONNMARK target is available in all chains and all tables
,对于规则 1-4,我也尝试使用-A PREROUTING -t mangle
(正如我在许多示例中看到的)并得到相同的结果。
答案1
在有状态的 netfilter(iptables)防火墙中,你可以使用以下命令刷新连接跟踪缓存[sudo] conntrack --flush
这将删除有关已建立连接的所有状态和信息。