![为什么应用 SNAT 和 DNAT 规则转发 ip(在 SSH 服务器上)后 SSH 仍然有效?](https://linux22.com/image/777889/%E4%B8%BA%E4%BB%80%E4%B9%88%E5%BA%94%E7%94%A8%20SNAT%20%E5%92%8C%20DNAT%20%E8%A7%84%E5%88%99%E8%BD%AC%E5%8F%91%20ip%EF%BC%88%E5%9C%A8%20SSH%20%E6%9C%8D%E5%8A%A1%E5%99%A8%E4%B8%8A%EF%BC%89%E5%90%8E%20SSH%20%E4%BB%8D%E7%84%B6%E6%9C%89%E6%95%88%EF%BC%9F.png)
我有以下情况:
- 我有一台带有桥接网络适配器的 Ubuntu Server VM(假设其 IP 为 192.168.100.3),它在端口 22 上公开一个 ssh 服务器,
- VM 托管在 Ubuntu 桌面上,
- 当我通过 ssh 连接到我的 VM(从主机)并在 VM 的 NAT 表中附加一些规则时,如下所示:
sudo iptables \
--table nat \
--append PREROUTING \
--protocol ALL \
--destination 192.168.100.3 \
--jump DNAT \
--to-destination 192.168.100.4 # some other machine in my local network
sudo iptables \
--table nat \
--append POSTROUTING \
--protocol ALL \
--destination 192.168.100.4 \
--jump SNAT \
--to-source 192.168.100.3
正在进行的 ssh 连接仍然存在,并且不会断开连接。但是,如果我在主机上打开一个新终端并尝试连接,我实际上会连接到网络中的另一台机器,我使用 iptables (192.168.100.4) 将其转发到该机器。为什么我的第一个连接仍然存在并且不会断开连接?根据我的理解,我指定的规则应该将所有数据包转发到 ip 192.168.100.4,但事实并非如此。ssh [email protected]
答案1
该nat
表仅由连接的第一个数据包遍历。它定义了所有转换,这些转换都记录在连接跟踪表中。后续数据包根本不会遍历该nat
表,相反,连接跟踪器只会从其表中获取记录的转换参数并应用它们。
因此,nat
建立连接后出现的规则永远不会应用于已运行的连接。您案例中的前一个连接知道没有定义转换规则,因此它不进行转换。如果您现在连接到另一台计算机并删除nat
规则,则将保留该连接,但将再次创建新连接而无需进行转换。