You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ubuntu 22.04下KVM虚拟机端口转发问题:虚拟机无法通过宿主机公网IP访问自身映射端口

Ubuntu 22.04下KVM虚拟机端口转发问题:虚拟机无法通过宿主机公网IP访问自身映射端口

你遇到的这个问题其实很典型,属于**Hairpin NAT(发夹NAT)**配置缺失导致的。简单来说,当虚拟机通过宿主机公网IP访问自己的映射端口时,数据包虽然能通过DNAT转到虚拟机,但虚拟机的响应数据包会直接走自己的默认网关(也就是宿主机的虚拟网桥)往外发,不会回到宿主机做反向NAT,导致整个连接的闭环断了,所以才会出现超时。

下面给你一步步解决的方案:

1. 确认宿主机IP转发已开启

首先确保宿主机的IPv4转发功能是打开的,这是所有NAT转发的前提:

  • 临时开启:
echo 1 > /proc/sys/net/ipv4/ip_forward
  • 永久生效(重启后不失效):
    编辑/etc/sysctl.conf文件,找到net.ipv4.ip_forward=1这一行,去掉前面的注释符号#,然后执行:
sysctl -p

2. 添加Hairpin NAT的SNAT规则

你已经配置了PREROUTING和OUTPUT链的DNAT规则,现在需要添加一条POSTROUTING链的SNAT规则,修正虚拟机回包的路径:

iptables -t nat -A POSTROUTING -s 192.168.122.0/24 -d 192.168.122.201 -p tcp --dport 22 -j SNAT --to-source 192.168.122.1

这条规则的作用是:当来自KVM虚拟机网段(192.168.122.0/24)的数据包,目标是你的虚拟机IP(192.168.122.201)的22端口时,把数据包的源地址改成宿主机虚拟网桥的IP(192.168.122.1,这是KVM默认虚拟网桥的地址,如果你的网桥IP不一样,记得替换)。这样虚拟机收到数据包后,会把回应发给宿主机,再由宿主机转发回虚拟机,形成完整的连接闭环。

3. 测试连接

现在回到虚拟机里,再次执行:

ssh -p 1023 222.222.222.222

应该就能正常连接了。

补充说明

为什么宿主机自己能访问?因为宿主机访问自身公网IP时,数据包走的是OUTPUT链的DNAT,回包直接在本地内核处理,不需要经过外部网络,所以没问题。而虚拟机的情况是数据包需要经过宿主机的NAT转换,但回包路径没有被正确修正,所以必须添加这条Hairpin NAT规则。

备注:内容来源于stack exchange,提问作者hwang

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.16 09:19:36