Linux虚拟机配网实战:桥接、NAT、仅主机一次讲清
聊到Linux虚拟机绕不开的一件事就是配网。我见过太多人装好系统后卡在这一步选了桥接宿主机掉线选了NAT外面访问不到虚拟机选了仅主机虚拟机又死活上不了网。其实Linux虚拟机最常用的三种配网方式——桥接、NAT、仅主机——各自干什么、什么时候用、怎么配才不会翻车是虚拟化里最值得花半小时搞清楚的基本功。这篇文章我就按自己日常在虚拟机里折腾Linux的经验把三种模式从头到尾拆一遍包括平台侧的设置、Linux系统内的IP配置、端口转发和常见的排障套路。这篇文章适合刚接触Linux虚拟机的人也适合已经上手但老被网络问题折磨的开发者或运维同学。不管你是用桌面级虚拟化软件还是KVM这类Linux原生方案底层逻辑是一样的我会把不同平台的操作点都提到方便你对照着做。1. 三种配网各管什么先把桥接、NAT、仅主机一次说清1.1 网络流量从虚拟机出来以后去哪儿Linux虚拟机里的每一块网卡本质上是软件模拟出来的真正的数据包还得经过宿主机转发。所以配网前你只需要搞清楚一个问题虚拟机发出去的包到了宿主机这个“关口”之后是被直接扔给物理路由器还是先被宿主机改头换面送出去还是干脆关在这台机器内部不许出门。对应这三种处理方式就是三大主要网络模式桥接模式虚拟机的虚拟网卡接到一个虚拟交换机上这个虚拟交换机又直接“桥接”到宿主机的物理网卡。从链路层角度看虚拟机就和局域网里的其他物理机器一样能直接拿到同网段的IP。NAT模式虚拟机发出的包先到达宿主机内部的虚拟NAT设备NAT模块会把数据包的源地址改成宿主机物理网卡的地址再发到外网。外面的人看到的永远只是宿主机的IP看不到虚拟机。仅主机模式虚拟网卡接到一个虚拟交换机上但交换机的上联口不存在物理网卡根本不参与。虚拟机和宿主机之间的通信靠宿主机里创建的一块虚拟网卡完成默认情况下没有任何路由能通到外网。用一句话记桥接是让虚拟机直接混进物理网络NAT是让宿主机给虚拟机当“二传手”仅主机是让虚拟机在宿主机内部自成一个“封闭小区”。1.2 一张对照表看穿三种模式的差异我把三种模式的关键差异整理成一张表配网的时候直接对照这个选就行能力项桥接模式NAT模式仅主机模式虚拟机到宿主机可通可通可通虚拟机到外网可以依赖物理网络可以经宿主机转发默认不通外网到虚拟机可直接访问不能直接访问需端口转发不能访问虚拟机之间互访同网段的可以直接互访同一NAT网络内可互访同一Host-only网络内可互访典型用途Web服务、数据库、模拟物理服务器日常下载、联网开发、隔离测试安全实验、集群调试、内网环境搭建这张表里的“外网到虚拟机”是最容易搞混的点。很多人配了NAT之后发现别人访问不了虚拟机这不奇怪NAT模式从设计上就是单向的外部只能看到宿主机的外网IP。想从外面连进来就得加端口转发这个后面章节会专门讲。1.3 选型前先问自己三个问题我不建议一上来就照着教程改配置那样容易一会儿通一会儿不通。你只需要按顺序回答下面三个问题这台虚拟机需要被局域网里的其他物理设备直接访问吗比如你在虚拟机上跑了某个Web站点想让手机或同事的电脑直接打开答案是需要那优先选桥接。这台虚拟机只需自己联网比如下载软件包、拉代码、调API不需要别人主动连进来那NAT是最省心的选择配置少还不占局域网IP。这台虚拟机要做的事情跟外网完全无关甚至希望越隔离越好比如做渗透测试、恶意软件分析、离线集群实验那就用仅主机模式。还有一点容易被忽略这三种模式并不是互斥的。一台Linux虚拟机完全可以配两块虚拟网卡一块用NAT去访问外网一块用Host-only加入一个私有实验网段。很多模拟集群的实验环境就是这么搭的后面我会讲具体怎么配。2. 动手配网前必须摸清的底层链路2.1 虚拟网卡与虚拟交换机的实际形态很多人配网失败是因为根本不看网卡叫什么名字直接拿网上抄来的eth0或ens33套上去。但不同平台、不同发行版、不同虚拟化驱动网卡命名天差地别。VMware里常见的虚拟网卡可能是ens33、ens160KVM里默认的virtio网卡可能叫enp1s0而老一点的镜像里又可能是eth0。拿到一个Linux虚拟机后第一件事永远是使用ip link或ip addr查看当前网卡列表确认系统识别到了哪块网卡再去改配置。这一步花不了10秒却能避免后面一连串“网卡不存在”的报错。平台侧的虚拟网络也是同一个道理。VMware有vmnet0、vmnet1、vmnet8分别对应桥接、仅主机、NATVirtualBox有自己的全局NAT网络和Host-only网卡KVM默认有一个叫virbr0的NAT网桥。你至少得知道当前这台虚拟机“接到”了哪个虚拟网络才能在Linux系统内配出不冲突的IP。2.2 确认宿主机网络环境避免地址“打架”给虚拟机配静态IP之前最好先在宿主机上搞清楚自己处在什么网络环境里。常用的几个命令ip addr show # 查看宿主机网卡和IP ip route show # 查看默认路由和网关 cat /etc/resolv.conf # 查看当前DNS配置最常见的翻车现场就是宿主机在192.168.1.0/24这个网段虚拟机里却随手填了一个192.168.1.101结果这个IP已经被家里的智能家居设备占用了。轻则虚拟机网络间歇性中断重则局域网内出现IP冲突把路由器的DHCP表都搞乱了。所以我一般建议先检查网段里还有哪些地址是空闲的。如果你在一个Linux宿主机上可以用arping或nmap扫一下懒得扫的话至少选一个离宿主机IP远一点的地址比如宿主机是.10虚拟机就从.50以后开始挑。2.3 静态IP规划的几个基本原则静态IP规划不需要多复杂记住三条铁律桥接模式下的虚拟机IP、网关、DNS都要跟物理局域网保持一致。虚拟机相当于物理网络里的一台普通机器跨网段就收不到包。NAT模式下的虚拟机IP必须落在平台分配的虚拟子网内。很多平台的默认NAT网段是192.168.122.0/24或192.168.88.0/24虚拟机里就算配静态IP也不要跑到别的网段去。仅主机模式下的虚拟机IP要落在Host-only虚拟网卡所在的网段并且通常不要配默认网关。因为没有路由器可以出去配了默认路由反而会导致部分流量卡顿。规划完之后去平台设置里看一眼虚拟网络的子网到底是多少再回到Linux虚拟机里配置基本不会出大问题。3. 桥接模式实战让虚拟机变成局域网里的“真邻居”3.1 平台侧让虚拟网卡接入物理网络桥接模式的平台侧配置每个软件入口不一样但核心动作是一样的让虚拟机的虚拟网卡桥接到宿主机的某一块物理网卡上。以VMware Workstation为例右键虚拟机进入“设置”在“网络适配器”里选择“桥接模式”。如果你用的是笔记本最好勾上“复制物理网络连接状态”。这里有个非常容易踩的坑虚拟机默认的桥接可能落在“自动”上宿主机同时有有线和无线网卡时系统有可能选错物理网卡导致虚拟机拿到一个奇怪的IP甚至拿不到IP。保险起见打开“编辑 - 虚拟网络编辑器”找到VMnet0手动把“桥接到”改成当前正在上网的那块网卡。VirtualBox的操作类似虚拟机“设置 - 网络”连接方式选“桥接网卡”界面名称选择宿主机那块真实物理网卡。如果你有多个网卡选正在用的那个别选USB外置网卡或虚拟网卡。KVM/libvirt的桥接稍微底层一些你需要先在宿主机上创建一个Linux网桥把物理网卡加进去。简单用NetworkManager操作sudo nmcli connection add type bridge con-name br0 ifname br0 sudo nmcli connection modify br0 ipv4.addresses 192.168.1.10/24 ipv4.gateway 192.168.1.1 ipv4.method manual sudo nmcli connection add type ethernet slave-type bridge con-name eth0-br0 ifname enp3s0 master br0 sudo nmcli connection up br0创建好网桥后KVM虚拟机网络类型改成bridge源设备填br0就行。需要注意宿主机的原IP地址应该迁移到br0上否则宿主机自己会断网。3.2 Ubuntu/Debian系用Netplan配置静态IP平台侧桥接好之后剩下的就是在Linux系统内部把IP配出来。主流系统里Ubuntu 22.04及之后的版本默认用Netplan管理网络。Netplan的配置文件在/etc/netplan/下典型配置可以这样写network: version: 2 ethernets: ens33: dhcp4: false addresses: - 192.168.1.101/24 routes: - to: default via: 192.168.1.1 nameservers: addresses: - 192.168.1.1 - 223.5.5.5这里ens33换成你在虚拟机里实际看到的网卡名192.168.1.101/24是你要用的静态IP192.168.1.1是物理局域网的网关。改完后执行sudo netplan trytry是一个很实用的选项它会先应用配置并等待几秒如果你没有按回车确认它会自动回滚避免你把自己SSH断掉。确认没问题后再执行sudo netplan apply。3.3 RHEL系用nmcli完成网卡配置RHEL、CentOS Stream、Rocky Linux这类发行版现在都推荐用NetworkManager的nmcli命令行工具来改IP。比如把ens160配置成静态IPnmcli connection modify ens160 \ ipv4.method manual \ ipv4.addresses 192.168.1.101/24 \ ipv4.gateway 192.168.1.1 \ ipv4.dns 192.168.1.1 223.5.5.5 nmcli connection up ens160nmcli connection up是关键很多人光改了配置不重启连接导致状态一直是旧的。这条命令会重新激活连接读完新配置并生效。用这种方式改的配置是持久化的不需要担心重启丢失。3.4 桥接模式验证与易犯的错配置完成后在虚拟机里依次验证三个连通性ip addr show # 查看IP是否生效 ping -c 3 192.168.1.1 # 测网关 ping -c 3 223.5.5.5 # 测公网IP ping -c 3 example.com # 测DNS解析如果IP能ping通但域名不行多半是DNS配错了如果网关能ping通但公网IP不通重点看路桥到底对不对。桥接模式最常见的坑有三类。第一虚拟机是从模板克隆出来的网卡MAC地址没重新生成导致局域网内出现两个相同MAC的设备网络忽断忽通复制完虚拟机后一定要让平台重新生成MAC。第二笔记本用无线网卡桥接信号稍差或者AP开了客户端隔离虚拟机就联不上局域网这种情况优先换有线或者退而求其次用NAT。第三物理路由器启用了MAC白名单虚拟机新接入没被放行这个就需要在路由器后台加一下。4. NAT模式实战虚拟机借宿主机这张“路由器”上网4.1 不用配就能上网的背后发生了什么NAT模式对新手最友好装完虚拟机后默认网络就是NAT开机基本就能上网。但“默认能用”不代表不需要理解它。NAT模式下平台会在宿主机内部建立一个虚拟子网虚拟机的虚拟网卡从这个子网里拿一个私有IP比如192.168.88.128/24默认网关指向宿主机内部的虚拟NAT设备。当虚拟机访问外网时NAT引擎会把数据包的源IP改成宿主机的物理网卡IP响应再原路返回。打个比方这就好比小区门卫帮你统一收发快递。你住在小区里面快递员只知道门卫室的地址门卫再按门牌号转交给你。外面的人看不到你具体住哪栋但你们之间的通信确实畅通。NAT网络是“只出不进”的外面无法直接连接虚拟机。如果需要外边访问就得靠端口转发这个后面讲。4.2 自定义NAT网络与DHCP细节有些场景下默认NAT的子网和你的物理网络冲突或者你想让多台虚拟机在同一个NAT网络里互相访问这时候需要自定义子网。VMware里打开“编辑 - 虚拟网络编辑器”选中VMnet8可以修改子网IP和DHCP分配范围。注意改子网IP意味着虚拟机里的默认网关也会跟着变比如你改成192.168.88.0/24那虚拟机网关就是192.168.88.2这类平台分配的地址不是192.168.88.1。VirtualBox不太一样它默认的“NAT”是每台虚拟机独立的NAT两台虚拟机互不相通。如果你希望多台虚拟机在同一个NAT网络里互访需要去“全局设定 - 网络 - NAT网络”里创建一个NAT网络然后把虚拟机的连接方式从NAT改成“NAT网络”并选中你创建的那个网络。KVM的NAT默认由virbr0提供子网通常是192.168.122.0/24。你可以用virsh net-edit default修改子网和DHCP范围改完执行virsh net-destroy default virsh net-start default重启网络。改完平台侧的NAT后虚拟机里确认一下网络状态ip addr show ip route cat /etc/resolv.conf看到IP落在正确的网段、默认路由指向虚拟网关就没问题。4.3 端口转发让外部访问NAT里的虚拟机NAT模式最大的痛点是从外面访问不了虚拟机。解决办法是端口转发把宿主机的某个端口映射到虚拟机里的某个服务端口上。这样外面的人访问宿主机IP加这个端口数据就会被NAT引擎转到虚拟机内部的服务。以VMware为例在“虚拟网络编辑器”里选中VMnet8点击“NAT设置”添加一条端口转发规则宿主机端口填2222虚拟机IP填192.168.88.128虚拟机端口填22。保存后外部设备就能用ssh -p 2222 用户名宿主机IP连进这台NAT虚拟机了。VirtualBox里操作路径是“虚拟机设置 - 网络 - 高级 - 端口转发”添加一条SSH规则就行。如果你用的是KVM并且宿主机是Linux可以直接用iptables做DNAT效果一样sudo iptables -t nat -A PREROUTING -p tcp --dport 2222 \ -j DNAT --to-destination 192.168.122.50:22 sudo iptables -A FORWARD -p tcp -d 192.168.122.50 --dport 22 -j ACCEPT这里的192.168.122.50是KVM里虚拟机的IP2222是宿主机对外端口。使用端口转发时有一个安全细节尽量绑定127.0.0.1不要让宿主机监听在0.0.0.0上否则同网段的其他物理机器也能访问你的SSH端口很容易被扫描工具盯上。4.4 NAT模式下最常见的配置错误NAT模式配错多半出在“聪明反被聪明误”。有人在虚拟机里手动配了一个物理局域网的IP比如192.168.1.101以为这样就能被外面直接访问结果发现上不了网。原因很简单NAT虚拟网络的网关在192.168.88.0/24这段你配一个192.168.1.x的地址默认网关根本不在同一网段数据包出不去。还有一个容易踩的坑是DNS。Ubuntu桌面版用systemd-resolved系统里的/etc/resolv.conf可能指向127.0.0.53看起来有点奇怪但其实是正常的。你只需要确认netplan配置里写了正确的nameservers然后执行netplan apply不要手动去改/etc/resolv.conf因为重启后会被覆盖。5. 仅主机模式实战把VM放进一个与外网隔绝的“实验室”5.1 Host-only的拓扑与默认短板仅主机模式是三种模式里最被低估的很多人以为它就是“不能上网”的残缺模式其实它是一个非常强大的隔离环境。在这个模式下虚拟机虚拟网卡连接到一个只有宿主机参与的虚拟交换机上宿主机通过一块独立的虚拟网卡VMware里是VMnet1VirtualBox里是vboxnet0接入这个交换网络。物理网卡完全不参与所以默认情况下虚拟机没法访问外网外网更不可能访问虚拟机。这个模式最适合干这些事跑一些不想沾物理网络的测试程序、模拟一个局域网内的多台服务器、做封闭环境的攻防实验、或者把几台虚拟机组成一个内部集群慢慢调试。5.2 给虚拟机和宿主机分配私有网段IP仅主机模式默认会有一个私有网段。VMware的VMnet1常见的是192.168.56.0/24宿主机虚拟网卡IP是192.168.56.1VirtualBox的Host-only网卡一般是vboxnet0地址也是类似结构。你在虚拟机里把这些信息确认一下然后给Linux配一个同一网段的静态IP。Ubuntu系用Netplan配置Host-only网卡可以单独写一个网卡的配置network: version: 2 ethernets: ens37: dhcp4: false addresses: - 192.168.56.101/24注意这里没有routes也没有gateway4这种老字段。因为Host-only网络里没有默认网关也不需要默认路由。有些人会随手填一个192.168.56.1作为网关反而会在路由表里留下一条永远不通的默认路由导致访问外网的时候卡半天。保存后执行sudo netplan apply然后在虚拟机里ping宿主机Host-only网卡ping -c 3 192.168.56.1通了就说明Host-only链路是好的。5.3 进阶操作让仅主机虚拟机也能访问外网仅主机模式虽然默认上不了外网但如果你在Linux宿主机上可以手动给它“加装”一个NAT让这台虚拟机既能保持Host-only的隔离身份又能偶尔访问外网下载东西。第一步在宿主机上开启IP转发sudo sysctl -w net.ipv4.ip_forward1如果想让这个设置重启后依然生效写入/etc/sysctl.d/99-forward.confnet.ipv4.ip_forward1第二步给Host-only网段加一条MASQUERADE规则。假设主机上网的物理网卡是eth0Host-only网段是192.168.56.0/24sudo iptables -t nat -A POSTROUTING -s 192.168.56.0/24 -o eth0 -j MASQUERADE第三步回到虚拟机里添加上网关和DNSsudo ip route add default via 192.168.56.1 sudo sh -c echo nameserver 223.5.5.5 /etc/resolv.conf这样虚拟机就可以通过宿主机转发出外网了。这个操作相当于你在宿主机上亲手搭了一个更纯粹的NAT理解了这个过程前面NAT模式的工作原理也就真正吃透了。5.4 仅主机模式下的多机互访与防火墙Host-only模式的另一个高频用途是搭建内部多机环境。几台虚拟机都接到同一个Host-only虚拟网络上IP按顺序分配比如192.168.56.101、192.168.56.102、192.168.56.103它们之间直接就可以互ping。不过如果发现ping不通优先检查虚拟机里的防火墙。Ubuntu默认可能装了ufw但规则没放行可以临时允许Host-only网段访问sudo ufw allow from 192.168.56.0/24RHEL系则要注意firewalld的默认zone如果用的是public内部互访很可能被拦临时测试可以sudo firewall-cmd --add-interfaceens37 --zonetrusted。调试完再收紧规则。多机互访还有一个特别容易踩的坑虚拟机是从模板克隆出来的MAC地址都一样或者网卡名都相同这样不管你怎么配IP网络都会乱。克隆虚拟机后记得重新生成MAC地址网卡名变了也要用ip link确认。6. 配网故障排查实录照着这张表排错6.1 桥接后宿主机掉线的典型原因桥接模式配完后如果宿主机自己掉线了八成不是虚拟机的问题而是网桥创建或者物理网卡分配出了问题。尤其是手动在Linux宿主机上建网桥的时候物理网卡原来的IP必须迁移到网桥上否则物理网卡被网桥接管后宿主机就失去了原来的IP配置自然就断网了。解决思路很直接把原来的IP、网关这些配置全部挪到br0上然后重新激活网桥。还有一种情况是无线网卡桥接。笔记本用Wi-Fi桥接虚拟机很多AP不允许多个MAC从同一个客户端接入或者设置了客户端隔离宿主机可能没事但虚拟机怎么都上不了网。这时候别死磕桥接换NAT模式更现实。6.2 NAT虚拟机ping不通外网NAT模式出问题按顺序排查能在两分钟内定位虚拟机内ip addr show确认网卡处于UP状态且拿到了IP。ip route确认默认路由指向NAT虚拟网关。虚拟机里ping网关不通说明虚拟交换机或NAT设备有问题。网关通了但外网不通去宿主机查net.ipv4.ip_forward是否为1以及防火墙FORWARD链是否挡了转发。KVM环境下执行virsh net-list --all确认默认网络是active状态如果不是执行virsh net-start default。如果ping公网IP是通的但ping域名不通那就是DNS问题去检查/etc/resolv.conf以及netplan或NetworkManager里的DNS配置。6.3 静态IP重启后被打回原形这是被人问得最多的问题明明sudo ip addr add加好了IP重启虚拟机又没了。原因很简单你用命令行直接改的IP只是临时配置没有写入任何网络管理工具的持久化配置里。真正的解决方式就两个方向Ubuntu/Debian系改/etc/netplan/*.yaml然后sudo netplan apply。RHEL系用nmcli connection modify修改对应的NetworkManager连接配置。另外一个隐藏杀手是cloud-init。如果你用的是云镜像创建的虚拟机cloud-init可能在你开机时按模板重置网络配置。解决办法是在/etc/netplan/50-cloud-init.yaml里确认DHCP相关配置或者直接停用cloud-init的网络管理模块。改完netplan后先执行netplan try确认不会断连再netplan apply持久化。6.4 多台虚拟机之间互相“失联”多台虚拟机互访的问题几乎都源于“模式选错导致网段隔离”。桥接模式的虚拟机在物理局域网里NAT模式的虚拟机在宿主虚拟子网里两者默认根本不在同一个网络域互相ping不通才是正常现象不用慌。要让它们互通有以下几种做法都改成同一个Host-only网络同网段直接互访。如果都在VMwareNAT模式且都连在同一个VMnet8上可以互访。如果都在VirtualBox请改用“NAT网络”而不是各自的默认“NAT”然后再互访。不同模式混合的用桥接做中转或者加一块网卡让一台虚拟机同时接入两个网络。互访还需要注意防火墙。很多情况是IP通、端口不通就是因为虚拟机里的防火墙默认只允许出站不允许入站。测试时先临时放行同网段或对应端口再逐步收紧。6.5 快速验证网络连通性的三个命令组合最后分享一下我每次配完网必做的三板斧。这三条命令能覆盖九成以上的网络验证需求ip addr show # 看IP有没有到位 ip route show # 看默认路由指向哪 ping -c 3 目标地址 # 实测连通性网关、公网IP、域名各测一遍如果虚拟机需要同时和宿主机、外网、其他虚拟机通信那就做一个“三角验证”虚拟机ping宿主机虚拟机ping网关宿主机ping虚拟机。两步都通配置基本稳了哪一步不通回到前面对应的故障点查。我个人折腾网络这么多年最大的体会是给Linux虚拟机配网真正的问题往往不是Linux命令不熟而是没想清楚数据包从虚拟机出来之后到底要往哪条路走。桥接是直连NAT是代理式转发仅主机是封闭内网这三者对应完全不同的信任边界。以后再遇到“配完就断网”的情况先别急着翻命令把网卡接哪个交换机、交换机上联到哪个出口画出来问题往往自己就现形了。还有一个小建议条件允许的话尽量在虚拟机里把NetworkManager和systemd-networkd的职责分清同一个网卡不要让两个管理工具一起管。不然你netplan写得再漂亮下次重启也可能被打回原形。这篇就当是把配网的路先替你走了一遍照着做能少踩不少坑。