问题:
我有一个位于主机(我们称之为host1
)上的应用程序,它将 TLS 加密的 TCP 数据包发送到另一台主机的端口 5015(我们称之为host2
)。由于网络限制,host1
所有入站和出站流量必须通过 80 或 443 进出。我无法访问host2
.
方法:
我的想法是,我可以创建一个 iptables 规则,host1
将路由/重定向/转发 443 中的 5015 流量,并且必须让它到达host2:5015
.我遇到的问题是创建正确的规则。这是我到目前为止所拥有的:
TCP_TRAFFIC_PORT=5015
PROXY_PORT=443
_apply_outbound_rules() {
# Forward outgoing packets through the proxy port
sudo iptables -t nat \
-I OUTPUT 1 \
-p tcp --destination-port $TCP_TRAFFIC_PORT \
-j DNAT --to-destination :$PROXY_PORT
# Send packets to host2:5015 port (this is likely the rule to fix)
sudo iptables -t nat \
-I POSTROUTING 1 \
-p tcp --destination-port $PROXY_PORT \
-j SNAT --to-source :$TCP_TRAFFIC_PORT
}
apply_outbound_rules
有谁知道如何做到这一点?这似乎是很常见的事情,但我却遇到了麻烦。
答案1
首先,Linux 中的 NAT 是有状态的。这意味着您不需要出站和入站规则。当流量返回经过 NAT 的出站时,Linux 将自动取消返回流量的 NAT。
尽管您将遇到的主要问题是 TCP 会话是由以下各项的组合定义的:
- 源IP
- 源端口
- 目的IP
- 目的端口
源 IP 已限制为单个值(host1 的 IP)。目标 IP 已经是单个值(主机 2 的 IP)。源端口只有 2 个可能的值(80 和 443)。并且目标端口仅限于单个值 (5015)。
这意味着您最多只能建立 2 个同时连接(如果您跨 2 个端口平衡 SNAT 负载)。即使使用顺序连接,您也可能会遇到端口重用问题,例如端口处于 TIME_WAIT 状态。
尽管如此,如果你真的想尝试这个,应该遵循的规则是:
iptables -t nat -I POSTROUTING \
-d $HOST2_IP -p tcp --dport $TCP_TRAFFIC_PORT \
-j SNAT --to-source :$PROXY_PORT
答案2
您是否知道应用程序在您的主机上运行的端口,如果不知道,则需要将所有源端口映射到 80 或 443
尝试下面替换 host2ip。
iptables -t nat -A POSTROUTING -p tcp -d host2ip -j SNAT -m multiport --sports 1:65535 --to-source :443