在Linux虚拟机NAT模式下,想让主机访问虚拟机,核心配置是设置端口转发(Port Forwarding),同时配合正确的网卡模式、静态IP和防火墙规则。
NAT模式下主机访问虚拟机的基本原理
NAT(网络地址转换)模式是VirtualBox、VMware等主流虚拟化软件默认的网络模式之一,它的工作逻辑是:虚拟机通过宿主机(你的电脑)的物理网卡访问外部网络,对外表现为宿主机的一个进程,外部设备无法直接找到虚拟机,因为虚拟机没有独立的局域网IP。
这个机制决定了主机访问虚拟机不能靠“直接发现”,而是要靠“端口映射”,你可以把NAT模式理解成小区门卫:虚拟机的数据都通过门卫中转,外部访客想进小区找某户人家,必须先告诉门卫门牌号,门卫再帮你接通。
为什么NAT模式下主机默认无法访问虚拟机
很多新手配置NAT模式后发现ping不通虚拟机,这是正常现象,原因有两条:
- IP地址隔离:虚拟机在NAT网络中拥有独立子网IP(例如192.168.56.101),而主机自身的物理网卡IP是另一个网段(例如192.168.1.5),两者不在同一广播域。
- 没有路由表项:主机的路由表不知道“去往192.168.56.x”应该走哪条链路,数据包会被发往默认网关,而不是VirtualBox或VMware创建的虚拟网卡。
行业共识认为,NAT模式的设计初衷是让虚拟机“单向出网”,而非提供“双向互访”。如果你想在NAT模式下让主机主动访问虚拟机,必须手动建立一条“隧道”,也就是端口转发规则。
主机访问NAT模式虚拟机的三种配置方案
配置端口转发(最常用)
这是VirtualBox和VMware都支持的标准做法,以VirtualBox为例,操作步骤如下:
- 打开VirtualBox管理器,选中目标虚拟机,点击“设置”。
- 进入“网络”选项卡,确认连接方式为NAT。
- 点击“高级”展开,再点击“端口转发”按钮。
- 在规则列表中添加一条新规则:
- 名称随意,比如web-ssh
-
协议选择TCP
- 主机IP留空(表示监听所有地址)
- 主机端口填一个未被占用的端口,例如2222
- 子系统IP填虚拟机的IP(如192.168.56.101)
- 子系统端口填虚拟机内服务的实际端口,例如SSH的22
配置完成后,主机访问虚拟机的方式变成:ssh 主机用户名@127.0.0.1 -p 2222,也就是说,主机把数据发到自己的2222端口,VirtualBox自动转交给虚拟机的22端口。
VMware Workstation的操作类似:菜单栏“编辑”->“虚拟网络编辑器”,选择NAT模式对应的VMnet8,点击“NAT设置”,添加端口转发条目。注意VMware的端口转发只支持TCP和UDP协议,不支持ICMP,所以ping不通计算机是正常情况。
给虚拟机添加第二块网卡(桥接模式混用)
如果你需要主机直接访问虚拟机的多个端口,或者懒得配置多条转发规则,可以给虚拟机添加第二块网卡。
- 第一块网卡保持NAT模式,用于虚拟机访问外网。
- 第二块网卡设置为桥接模式(Bridged),桥接到主机物理网卡。
这样虚拟机会同时拥有NAT网段的IP和主机所在局域网的真实IP,主机和虚拟机之间通过局域网IP通信,速度更快,ping也能通,缺点是:虚拟机会暴露在局域网中,其他设备也能访问它,安全性稍有下降。
修改NAT网络属性为“允许主机访问”(VMware专用)
VMware的NAT模式里有一个默认选项叫“连接主机虚拟适配器到网络”(Connect a host virtual adapter to this network),这个选项默认是勾选的,它会在主机上创建VMnet8虚拟网卡,主机理论上能通过VMnet8的IP(通常是192.168.x.1)访问虚拟机。
但实际测试中,很多用户反馈即使勾选了,主机也无法直接ping通虚拟机,原因是Windows防火墙拦住了来自VMnet8的入站请求,解决办法是:
- 在虚拟机内关闭防火墙(测试环境)或放行对应端口。
- 在主机防火墙中允许VMnet8入站规则。
如果你的VMware版本较新,编辑虚拟网络设置时,把NAT模式下的“端口转发”和“主机虚拟适配器”都配置好,基本就能满足需求。
业内专家指出,VMware的NAT模式在默认情况下比VirtualBox更“通情达理”,但依然需要手工确认虚拟网络编辑器的参数。
配置完成后主机访问虚拟机失败的排查清单
就算按照上述步骤配置了端口转发,访问时仍然可能失败,按以下顺序排查,能解决绝大多数问题:
- 检查虚拟机内服务监听地址,务必确认服务监听的是0.0.0.0而不是127.0.0.1,例如Linux的SSH服务,如果只监听127.0.0.1,端口转发无效,使用
ss -tlnp | grep 22查看。 - 检查防火墙状态,虚拟机里执行
sudo systemctl stop firewalld临时关闭,若还是不通再检查iptables,注意Ubuntu默认没有firewalld,但可能有ufw。 - 检查主机端口冲突。
netstat -ano查看2222端口是否被其他程序占用。 - 确认虚拟机IP地址没变,如果虚拟机开了DHCP,重启后IP可能改变,端口转发规则里的旧IP就失效了,建议给虚拟机设置静态IP。
- 确认NAT网络自身没被破坏,VirtualBox的NAT服务如果异常,可以尝试“管理”->“全局设定”->“网络”中重置NAT网络。
不同虚拟化软件的主机访问虚拟机性能对比
表格数据整理自各软件官方文档和常见实践反馈,供你在方案选择时参考:
| 虚拟化软件 | 端口转发 | 主机直通访问 | 配置复杂度 | 适用场景 |
|---|---|---|---|---|
| VirtualBox | 支持,规则简单 | 需配合桥接 | 较低 | 个人开发、临时测试 |
| VMware Workstation | 支持,NAT设置里可配 | 默认有VMnet8适配器 | 中等 | 需要复杂网络模拟 |
| KVM/QEMU(libvirt) | 支持,virsh命令或virt-manager配置 | 支持用户模式NAT | 较高 | 服务器环境、批量管理 |
对于大多数做Linux运维练习或容器测试的同学,VirtualBox的端口转发已经足够用,如果需要跑K8s集群,建议直接用VMware的NAT模式并保持VMnet8存在,因为多个虚拟机之间互相访问更方便。
常见问题解答
主机访问虚拟机时,ping不通但SSH能通,正常吗?
正常,NAT模式下的端口转发只针对TCP/UDP协议,不处理ICMP协议,ping使用的是ICMP,虚拟化软件不会为你转发ICMP包,所以ping不通不代表网络不通,能SSH就说明TCP链路没问题,如果你用方案二(桥接第二网卡),则可以ping通虚拟机的桥接IP。
虚拟机设置静态IP后,网关地址应该填什么?
在NAT模式下,虚拟机的网关通常指向虚拟化软件提供的虚拟路由器,VirtualBox的NAT默认网关是0.2.2(或根据你NAT网络设置的网段),VMware的VMnet8默认网关一般是168.x.1,不同版本的软件可能存在差异,建议用ip route show default命令查看当前路由,把网关抄下来用于静态配置。
主机通过端口转发访问虚拟机时,项目里的网站URL应该写什么?
写虚拟机的内部IP,不要写127.0.0.1或主机IP,例如你在虚拟机里部署了一个网站,监听端口8080,从主机访问时使用http://127.0.0.1:8080,但在网站配置文件中,回调URL、API地址等业务逻辑涉及主机访问场景时,一律填虚拟机内部IP(如192.168.56.101),否则虚拟机内部的服务会尝试去连接一个不存在的地址,这个细节是很多开发者部署Web应用时踩过坑的地方。
Linux虚拟机NAT模式下实现主机访问虚拟机,不需要改变NAT的核心机制,只需要在虚拟化软件里添加端口转发规则,或者增加一块桥接网卡绕过NAT,对于SSH、MySQL、Web服务等常见场景,端口转发是安全且零学习成本的方案;如果需要双向、多端口高频通信,第二块网卡走桥接更省心,配置完成后,用telnet或ssh -v验证链路,比ping更有参考价值,因为NAT模式本身就不承诺支持ICMP。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/739343.html





