VMware Host-only模式虚拟机联网全攻略:NAT与路由配置详解
虚拟机连着宿主机把网卡切成“主机模式”本意是搭个隔离的测试环境结果装完系统一ping外网直接无响应。这个问题我在不同版本的VMware上都碰到过前前后后折腾了好几个晚上才彻底理顺。其实原因并不复杂就是Host-only模式天生没有把虚拟机的流量转发到物理网络里的那套“门卫”机制。这篇文章我把自己的踩坑过程、原理拆解、以及Windows和Linux两种宿主机下的完整配法都记录下来希望能帮你少走弯路。1. 先把问题定位清楚Host-only 到底能不能上网1.1 三种网络模式的底层逻辑VMware里最常见的三种虚拟网络模式桥接模式、NAT模式、主机模式很多人只是会“选”但不太清楚它们背后到底做了什么动作。我说个生活化的类比桥接模式相当于你直接住进了小区外面那条主干道邻居能看见你你也能直接出门逛街NAT模式相当于你住在小区里出门必须通过门卫门卫帮你把包裹转交出去外面的人看不见你而主机模式Host-only相当于你在小区里租了个房间但小区物业把大门锁了你只能在小区内部溜达出不去。从VMware的实现上看桥接模式直接把虚拟机的虚拟网卡挂到物理网卡上虚拟机就像一台和宿主机并排的独立设备。NAT模式由VMware的虚拟NAT设备提供地址转换虚拟机和宿主机共享一个出口IP访问外网时由NAT设备代为转交。主机模式则只创建一个虚拟交换机VMnet1宿主机和虚拟机都接在VMnet1上彼此能通信但这个虚拟交换机没有接到任何物理网卡上也没配置NAT和路由所以虚拟机自然没有办法把数据包送出去。用一张简单的关系对照表来看网络模式虚拟网卡能否访问宿主机能否访问外网外部能否访问虚拟机桥接模式VMnet0桥接到物理网卡能能能NAT模式VMnet8能能靠NAT转换不能除非端口映射主机模式VMnet1能默认不能不能所以当你看到虚拟机在主机模式下ping不通8.8.8.8这其实不是故障这是VMware原本的设计预期。问题在于很多人和我一样既想要主机模式的隔离性又想顺手能联网装个依赖包、拉个代码于是就会陷入“为什么我配了IP、配了网关还是不通”的困惑里。1.2 Host-only 的“不能上网”是设计使然不是故障主机模式这个设计初衷很明确给用户提供一个完全隔离的虚拟网络适合做内网渗透测试、分布式集群内部通信测试、或者只允许虚拟机访问宿主机服务的场景。它不会有NAT规则也不会把VMnet1接到物理网络。所以它不是坏了是默认就没通电。搞明白这一点之后解决方向就清晰了要么放弃主机模式改用NAT或者桥接要么保留主机模式自己给它“通电”——也就是手动补上NAT、路由和DNS这几样东西。前者一步到位改动最小后者保留隔离性还能上网适合对网络环境有特殊要求的场景。我在实际项目里两种方案都用过。如果只是临时让虚拟机装个软件我建议直接切NAT如果你是为了模拟一个内部服务器环境又需要偶尔联网同步代码那给Host-only加NAT更值得投入时间。下面我分两条路详细讲。2. 思路解析想让 Host-only 上网底层要补三样东西2.1 方案一把虚拟机网卡直接切成 NAT最简单在VMware里打开虚拟机设置把网络连接类型从“主机模式”改成“NAT模式”点确定然后重启虚拟机里的网络服务通常就能直接联网了。整个过程不超过两分钟适合绝大多数只需要“能上网”的日常场景。切开之后你不需要手动配置虚拟机的IP地址正常用DHCP就能拿到VMnet8网段的地址网关也自动是虚拟NAT设备的地址。唯一要注意的是如果你之前给虚拟机配了静态IP切成NAT后需要把它改成DHCP自动获取或者改成VMnet8网段内的可用地址否则网卡起不来。这个方案的好处是零配置坏处是失去了主机模式的隔离性。虽然NAT模式下外部设备同样访问不到虚拟机但虚拟机和宿主机之间的网络关系不再那么“私密”和主机模式相比NAT模式下VMnet8默认是允许虚拟机访问宿主机的也能访问外网但它的用途毕竟偏向“出门”而不是“内部隔离”。2.2 方案二给 Host-only 加“门卫”在宿主机上补 NAT 和路由如果你需要保留主机模式那就得给VMnet1增加三层能力分别是默认路由、NAT转发、DNS解析。先说默认路由。虚拟机处在VMnet1这个网段它发出的数据包默认要发往某个网关地址。这个网关必须在VMnet1网段内并且由宿主机或者一台虚拟机来扮演。因为VMnet1只连接了宿主机和虚拟机所以这个网关几乎只能是宿主机上VMnet1网卡的IP地址。如果你的VMnet1地址是192.168.117.1那虚拟机里的网关就要填192.168.117.1。再说NAT转发。宿主机收到虚拟机发来的数据包后知道目标是外网但它不能直接把这个包转出去因为虚拟机的IP地址是私有的外面不认识。宿主机需要把数据包的源地址改成自己物理网卡的IP这就是NAT。Windows下可以借助“Internet连接共享”功能Linux下可以手动开启ip_forward再添加iptables MASQUERADE规则。最后是DNS解析。能ping通IP不代表能解析域名虚拟机还需要一个可用的DNS服务器。最省事的办法是直接把宿主机所在局域网的DNS填进去比如运营商的DNS或局域网网关的IP如果你不想记这些可以在虚拟机里填宿主机物理网卡的IP前提是宿主机开启了DNS代理服务否则还是要把真实DNS地址填进去。这三样缺一不可。很多人配置完发现能ping通192.168.117.1但ping不通外网就是NAT转发没生效能ping通外网IP但域名解析不了就是DNS没配置好。接下来我把Windows和Linux两个平台的完整配置过程分别展开。2.3 选型建议什么场景该用哪种方案我自己的判断标准很简单如果你想快速搞定、不追求隔离直接切NAT如果你在模拟一个独立的内网环境例如搭建数据库集群、内网测试平台而且不希望这些服务暴露到局域网那留在Host-only并手动配置NAT更有价值。还有一个折中做法让宿主机开两个虚拟网卡其中一个走NAT另一个走Host-only虚拟机内部把业务流量走Host-only把上网流量走NAT。这种“双网卡”方案在服务器环境里很常见但配置复杂度也高一些新手容易把路由表搞乱不建议刚接触的人尝试。先把单条路走通再考虑组合。3. 实操Windows 宿主机上用“Internet连接共享”给 Host-only 开外网3.1 网络共享的完整配置步骤Windows下最常见的做法是使用系统的“Internet连接共享”也就是ICS功能。它会把物理网卡上的Internet连接共享给VMnet1网卡让连接在VMnet1上的虚拟机能够通过宿主机的物理网卡上网。配置步骤大概是这样的。第一步确认VMnet1存在。打开VMware的“虚拟网络编辑器”在“主机虚拟网络映射”里确认有一个名为VMnet1的“仅主机模式”网络。如果你用的网络模式是默认设置VMnet1通常在列表里。如果没看到先点击右下角的“更改设置”获取管理员权限然后添加网络类型选“仅主机模式”。第二步记录VMnet1的IP。在Windows的“网络连接”里找到VMnet1对应网卡通常名字里带VMware Virtual Ethernet Adapter for VMnet1查看它的IPv4地址。因为我习惯用“虚拟网络编辑器”里的“子网IP”作为参考所以这里会先看一眼子网范围。注意ICS启用之后系统会把VMnet1网卡的IP强制改成192.168.137.1这是Windows的固定行为。也就是说你的虚拟机网关必须改成192.168.137.1而不是你原来的192.168.117.1之类。第三步启用共享。在“网络连接”里右键你当前上网用的那张物理网卡有线或无线取决于宿主机怎么联网进入“属性”切到“共享”选项卡勾选“允许其他网络用户通过此计算机的Internet连接来连接”。然后在下拉框里选择VMnet1对应的专用网络连接。记得取消勾选“允许其他网络用户控制或禁用该共享Internet连接”防止有人误操作把共享关掉。注意启用ICS的一瞬间VMnet1的IP会被改成192.168.137.1子网掩码通常是255.255.255.0。如果你之前给VMnet1手动配置过IP也会被覆盖。所以不要反过来手动改192.168.137.1否则共享服务可能不起作用。第四步确认服务状态。ICS依赖Windows的“Internet Connection Sharing (ICS)”服务和“Application Layer Gateway Service”服务。打开服务管理器确认这两个服务都在运行状态。如果之前手动禁用过把它们设为自动并启动。这一步是很多人忽略的尤其是一些“精简版”系统把共享服务裁剪掉了ICS怎么开都不生效。3.2 虚拟机内部的网络配置细节宿主机共享开好之后虚拟机内部就要按“网关192.168.137.1”来配置。如果你用的是Linux虚拟机可以手动执行命令配置也可以修改网卡配置文件。以常见的Ubuntu服务器版为例先确认网卡名再用netplan配置。假设网卡名叫ens33在/etc/netplan/99-custom.yaml里写network: version: 2 ethernets: ens33: dhcp4: false addresses: - 192.168.137.100/24 routes: - to: default via: 192.168.137.1 nameservers: addresses: - 223.5.5.5 - 192.168.137.1然后执行sudo netplan apply让它生效。如果你是CentOS/RHEL则改/etc/sysconfig/network-scripts/ifcfg-ens33设置BOOTPROTOstatic、IPADDR192.168.137.100、GATEWAY192.168.137.1、DNS1223.5.5.5然后重启网络服务。这里DNS我填了公共DNS如果你希望走宿主机的解析能力可以填192.168.137.1但前提是Windows的共享服务会自动承担DNS中继实测下来大多数情况是能用的个别情况下会有延迟不如直接填公共DNS稳。Windows虚拟机就更简单了打开网络适配器设置把IP填成192.168.137.2之类的地址子网掩码255.255.255.0网关192.168.137.1DNS填公共DNS或192.168.137.1都行。这里有个小细节Windows的ICS会自动把VMnet1网卡的防火墙例外打开但你宿主机上其他网卡的防火墙不一定会放行来自VMnet1的流量。如果虚拟机ping不通192.168.137.1优先检查Windows防火墙里是否允许了VMnet1网卡入站。3.3 分阶段验证从网关到外网到域名配置完不要急着直接ping百度按这个顺序排查会让你更快定位问题。第一步ping网关。在虚拟机上执行ping 192.168.137.1通则说明虚拟机和宿主机链路正常不通则先看VMnet1网卡是否启用、虚拟机网卡IP是否在192.168.137.0/24内。第二步ping外网IP。比如ping 223.5.5.5通则说明NAT转发和路由基本没问题虚拟机可以通过宿主机访问外网IP不通则问题多半在ICS服务或Windows防火墙。此时在Windows宿主机上执行ipconfig确认VMnet1仍然保留192.168.137.1再检查ICS服务是否存在。第三步解析域名。比如ping www.baidu.com能通就说明DNS配置正常不通则检查虚拟机里的DNS设置修改/etc/resolv.conf或网卡配置里的域名服务器。我在这一步经常遇到的情况是ping 223.5.5.5能通但解析域名时非常慢甚至超时。后来定位到是我在虚拟机里填的DNS是192.168.137.1而Windows的ICS中继解析在部分网络环境下不稳定尤其宿主机开了多个虚拟网卡时更容易出问题。后来我直接把DNS改成公共DNS问题就没再出现过。所以如果你只是想快速联网就把DNS写成公共的少折腾。4. 实操Linux 宿主机上用内核转发和 NAT 给 Host-only 开外网4.1 开启内核 IP 转发让宿主机愿意当路由器Windows下有ICS一键搞定NATLinux下就没这么省事了但原理一样而且配置好之后比Windows更透明、更可控。整个思路是让宿主机把来自VMnet1网段的流量转发到物理出口再用NAT伪装源地址。第一步先检查内核是否开启了IPv4转发。执行cat /proc/sys/net/ipv4/ip_forward看到1就说明已经是开启状态看到0就手动打开echo net.ipv4.ip_forward1 | sudo tee -a /etc/sysctl.conf sudo sysctl -p注意sysctl.conf里的配置在重启后会保留前面用echo 1 /proc/sys/net/ipv4/ip_forward只是临时生效一旦重启又会变回去。所以无论当前值是几都建议把配置写进sysctl.conf。提示某些云服务器或安全加固过的Linux发行版默认会关闭IP转发改完sysctl.conf之后一定要执行sysctl -p确认没有报错。如果执行后没有输出说明配置已读入。4.2 编写 iptables 规则完成 MASQUERADE 源地址转换开启转发之后宿主机在“路由”层面愿意接收和传递数据包了但这些数据包发出去之后回来的应答包要能正确路由回虚拟机。由于虚拟机的192.168.x.x是私有地址物理网络上的其他设备不知道这个地址在哪所以必须在宿主机上做NAT把这些私有源地址“伪装”成宿主机的物理IP。下面这组iptables规则是Linux下给Host-only开NAT的标准写法# 假设你的VMnet1网卡名为vmnet1物理出口网卡名为eth0 sudo iptables -t nat -A POSTROUTING -s 192.168.117.0/24 -o eth0 -j MASQUERADE sudo iptables -A FORWARD -i vmnet1 -o eth0 -j ACCEPT sudo iptables -A FORWARD -i eth0 -o vmnet1 -m state --state RELATED,ESTABLISHED -j ACCEPT这几条规则的含义可以逐句拆解。第一条在NAT表的POSTROUTING链里把来自192.168.117.0/24网段、从eth0出去的包的源地址改写成宿主机的IP。第二条允许从VMnet1进入、从物理网卡出去的流量通过第三条允许从物理网卡进入、回给VMnet1的返回流量通过前提是该连接已经被跟踪。如果你用的是nftables而不是iptables写法略有不同但思路一致。需要确认系统默认防火墙是iptables还是nftablesRedHat系现在很多默认走nftablesUbuntu也可以用iptables-nft兼容层。我习惯先执行sudo iptables -L -n看有没有报错有报错说明内核里没有iptables相关模块那就老老实实用nftables。如果你系统上还有firewalld或ufw这类前端防火墙务必确认它们的默认规则允许了FORWARD链对vmnet1到外网的放行。有的发行版默认FORWARD策略是DROP你手工加iptables规则虽然写进去了但顺序和防火墙策略冲突结果还是不生效。最简单的验证方法是临时把FORWARD策略改成ACCEPTsudo iptables -P FORWARD ACCEPT如果这时虚拟机突然能上网了说明问题出在防火墙默认策略而不是NAT规则本身。之后再把所需的最小放行规则写进防火墙配置里。4.3 给虚拟机配置网络网关和 DNS 缺一不可Linux宿主机环境下VMnet1的网段和地址可以从VMware虚拟网络编辑器里看到。比如子网IP是192.168.117.0子网掩码255.255.255.0那么宿主机的VMnet1地址通常是192.168.117.1。你在虚拟机里配置IP时网关就要指向192.168.117.1DNS可以用公共DNS也可以用宿主机的物理网卡DNS。我常用的配置方式是直接在虚拟机里改netplan或者ifcfg文件静态地址设为192.168.117.100/24网关192.168.117.1DNS填223.5.5.5和8.8.8.8。这里要注意虚拟机IP不能和宿主机的VMnet1 IP冲突也不能和Virtual Network Editor里启用的DHCP服务分配地址撞车。如果你不确定可以把VMware自带的DHCP服务关掉然后完全手动管理地址池。还有一种更灵活的方式是让宿主机自己跑一个DHCP服务比如用dnsmasq。dnsmasq的配置很简单在/etc/dnsmasq.conf里指定interfacevmnet1dhcp-range192.168.117.100,192.168.117.200,12h然后再把dnsmasq配置成监听vmnet1并转发DNS查询。不过这种方式对新手来说有点重其实只为几台虚拟机联网的话静态配置完全不麻烦还能省去排查DHCP服务的精力。如果你的Linux宿主机上安装了firewalld还需要让firewalld放行vmnet1的流量。执行sudo firewall-cmd --permanent --zoneinternal --add-interfacevmnet1然后reload。这倒不是必须的但如果不做有时你会发现iptables规则已经加上了虚拟机的流量还是出不去检查firewalld是第一步。4.4 持久化配置别让规则在重启后丢失临时规则有一个问题iptables规则不会自动保存机器一重启就没了。我建议在配置完成后把规则保存下来。Debian/Ubuntu系可以使用iptables-persistent安装时选择保存当前IPv4规则之后系统重启会自动加载。或者你也可以手动把规则写到文件里sudo iptables-save /etc/iptables/rules.v4 sudo sh -c iptables-save /etc/network/if-pre-up.d/iptables-rulesRedHat/CentOS系可以用service iptables save它会将规则保存到/etc/sysconfig/iptables开机时加载。如果系统没有iptables服务就用firewalld的规则持久化方式把前面那些允许和NAT规则通过firewall-cmd来配置。注意sysctl.conf里已经持久化了IP转发但Netplan、ifcfg这些虚拟机内的网络配置也要保证在虚拟机重启后依然存在。虚拟机里的网络配置和宿主机里的NAT规则是两套独立体系别只配一半。4.5 验证命令集从数据包流向确认问题Linux下排查手段比Windows丰富一些我整理了一套验证命令按顺序执行基本能定位绝大多数问题。# 在宿主机上查看IP转发状态 cat /proc/sys/net/ipv4/ip_forward # 查看NAT表规则 sudo iptables -t nat -L -n -v # 查看FORWARD链规则 sudo iptables -L FORWARD -n -v # 查询物理网卡的IP和路由 ip addr show eth0 ip route show # 抓包确认流量是否到达物理网卡出口 sudo tcpdump -i eth0 icmp我在配置Linux宿主机时遇到过一种隐蔽情况虚拟机ping外网时通畅但网页打开奇慢后来用tcpdump抓包发现大量DNS查询发到了不存在的地址上。原因是虚拟机里没配DNS却继承了VMware虚拟网卡的“自动获取DNS服务器地址”而那个地址对应的DHCP服务早已被我把VMnet1的DHCP关掉。所以配置静态IP时一定要主动填好DNS别依赖自动获取。5. 那些年踩过的坑问题排查与经验小结5.1 常见症状速查表我把实际运维中遇到过的各种现象整理成一张表排查时直接对着看症状优先级常见原因解决方法虚拟机ping不通宿主机VMnet1地址高VMnet1网卡被禁用、虚拟机IP不在同一网段恢复VMnet1网卡检查虚拟机和宿主机IP是否在同一子网能ping通VMnet1但ping不通外网IP高NAT转发没生效、ICS服务未启动/iptables规则缺失在宿主机上重新启用ICS或检查iptables NAT规则能ping通外网IP但无法解析域名中虚拟机DNS配置错误改为公共DNS如223.5.5.5能上网但速度极慢中DNS中继不稳、MTU问题换公共DNS尝试降低MTU到1400开机后又不能上网中持久化没做或网络服务启动顺序问题保存iptables规则、确认sysctl.conf已生效共享后宿主机自己的网络无法访问外网低ICS把物理网卡IP改成192.168.137.1和局域网冲突避免对多网卡同时启用ICS检查物理网卡IP是否被改虚拟机可以上网但外部访问不了虚拟机的服务低Host-only没有端口映射能力如需外部访问改用桥接模式或在宿主机上配置端口转发这七种情况对应了大部分“主机模式上不了网”的报障。我的经验是百分之七十的问题都出在网关没配、NAT没开、DNS不对这三件事上先把这三样逐个排查清楚再查防火墙和路由表不要一上来就重装系统。5.2 两个容易被忽略的细节虚拟网络服务和防火墙放行第一个细节是VMware自带的虚拟网络服务。VMware Workstation和VMware Player的后台服务包括VMware Authorization Service、VMware DHCP Service和VMware NAT Service。如果你在用主机模式配合ICSDHCP服务可以开着但如果你自己静态分配IP建议把VMware DHCP Service停掉避免它给你的虚拟机分配一个和静态配置不同网的地址导致虚拟机网络一会儿通一会儿不通。第二个细节是Windows防火墙的“网络发现”和“文件和打印机共享”例外。有时候你的ICS配置没有问题iptables规则也加了但虚拟机就是ping不同宿主机网关原因是Windows防火墙把VMnet1网卡上的入站ICMP包拦了。这种情况下不需要关闭整个防火墙只需在Windows防火墙的高级设置里针对“文件和打印机共享(Echo Request - ICMPv4-In)”规则启用或者单独为VMnet1网卡创建一条允许规则。我早期在某个Windows服务器版本上就遇到过共享开了虚拟机IP配了网卡也正常但虚拟机始终无法ping通192.168.137.1。后来发现是Windows Server版本的防火墙里默认把“核心网络-ICMPv4-In”规则全关了开启后立刻恢复。5.3 关于“主机模式”网络规划的个人建议最后分享一点长期使用中的网络规划心得。第一VMnet1的网段尽量避开宿主机所在局域网的网段。如果你的局域网就是192.168.1.0/24那VMnet1最好不要也配192.168.1.0/24否则路由表会打架虚拟机访问宿主机局域网里的设备时容易混乱。VMware默认给的网段一般不会冲突但有些人在配置共享时把VMnet1拖到了和物理网卡同网段结果宿主机本身的网络就变得不稳定。第二如果你的虚拟机需要长期稳定联网尽量用静态IP而不是DHCP。DHCP虽方便但在某些场景下租约更新会出问题尤其是在虚拟机长时间挂起、恢复后网络断掉的情况。静态IP配合写好的DNS恢复速度明显更快。第三不要把“主机模式HOST-ONLY”当作生产环境的网络方案。它更适合测试、实验、封闭开发和离线程控场景。生产环境里需要虚拟机对外提供服务的老老实实走桥接或者用正规的虚拟网络设备和安全组来控制访问策略。主机模式加固的隔离性确实好但它的可管理性、可观测性都比较弱出了网络问题排查起来也费劲。结尾想再叮嘱你的几件事配置这个问题的过程中我最大的体会是网络问题的排查一定要沿着数据包的路径走一层一层往下查。虚拟机先看自己IP、网关、DNS再看宿主机VMnet1网卡、NAT规则、物理出口最后再检查防火墙拦截、服务状态。绝大多数卡住的地方都是因为某一层的配置没和上一层衔接上。如果你用的是Windows宿主机ICS是上限也是最方便的办法但别让它把你原来的物理网卡共享配置给弄乱了多网卡机器尤其要留意。如果你用的是Linux宿主机iptables那条MASQUERADE规则记得持久化别等到重启后再后悔。如果按你说的情况把这些步骤都走了一遍还是不通不妨把VMware虚拟网络编辑器里VMnet1的“子网IP”和“DHCP设置”截图下来对照网卡配置再看一遍总有一步会露出破绽。