Linux如何配置虚拟机NAT网络(虚拟机.配置.网络.Linux.NAT...)

wufei123 发布于 2025-09-24 阅读(13)
答案:配置Linux虚拟机NAT网络需通过libvirt创建或启用default网络,确保虚拟机连接至virbr0网桥并获取私有IP,宿主机开启IP转发和防火墙规则,实现虚拟机经NAT访问外网。

linux如何配置虚拟机nat网络

在Linux上配置虚拟机NAT网络,核心在于让虚拟机通过宿主机访问外部网络,同时保持虚拟机与宿主机内部网络相对隔离。这通常涉及到宿主机的网络管理工具(如

libvirt
或VirtualBox的网络设置)和虚拟机自身的网络配置。简单来说,就是宿主机扮演一个路由器角色,为虚拟机提供一个私有网络,并通过宿主机自身的网络接口进行地址转换(NAT)来访问互联网。 解决方案

在Linux环境下,配置虚拟机NAT网络,我们主要以KVM/QEMU为例,因为它在Linux上是原生且功能强大的虚拟化解决方案。如果你使用VirtualBox,其配置会更直观,在虚拟机设置中选择“网络”->“连接方式”为“NAT”即可。

对于KVM/QEMU,通常通过

libvirt
管理。默认情况下,
libvirt
会创建一个名为
default
的NAT网络。
  1. 检查或启用默认NAT网络: 打开终端,首先检查

    libvirt
    的默认网络是否已存在并运行:
    virsh net-list --all

    你可能会看到一个名为

    default
    的网络,状态为
    active
    。如果不是,或者你想自定义,可以继续下一步。
  2. 查看或编辑NAT网络定义: 如果

    default
    网络不存在或你想修改它,可以查看其XML定义:
    virsh net-edit default

    这会打开一个文本编辑器显示网络的XML配置。一个典型的NAT网络配置看起来会是这样:

    <network>
      <name>default</name>
      <uuid>...</uuid>
      <forward mode='nat'/>
      <bridge name='virbr0' stp='on' delay='0'/>
      <ip address='192.168.122.1' netmask='255.255.255.0'>
        <dhcp>
          <range start='192.168.122.2' end='192.168.122.254'/>
        </dhcp>
      </ip>
    </network>
    • <forward mode='nat'/>
      :明确指出这是NAT模式。
    • <bridge name='virbr0' .../>
      virbr0
      是宿主机上虚拟网桥的名称,虚拟机将连接到这个网桥。
    • <ip address='192.168.122.1' netmask='255.255.255.0'>
      :这是虚拟网桥的IP地址,也是虚拟机默认的网关。
    • <dhcp>
      libvirt
      内置的DHCP服务器会为连接到此网络的虚拟机分配IP地址。

    你可以根据需要调整IP地址范围,但通常默认设置已经足够。保存并退出编辑器。

  3. 启动或激活网络: 如果网络状态不是

    active
    ,需要启动它:
    virsh net-start default
    virsh net-autostart default # 设置开机自启动
  4. 将虚拟机连接到NAT网络:

    • 使用
      virt-manager
      图形界面: 打开
      virt-manager
      ,选择你的虚拟机,点击“打开”,进入虚拟机详情页面。点击左侧的“添加硬件”或直接编辑现有网卡。在“网络源”中选择“网络名称”,然后从下拉菜单中选择
      default
      (或你自定义的NAT网络)。确保“设备型号”选择一个常见的虚拟网卡,如
      virtio
    • 使用
      virsh
      命令行: 如果你已经创建了虚拟机但未指定网络,或者想修改现有虚拟机的网络,可以使用
      virsh edit <vm_name>
      命令。在虚拟机的XML配置中找到
      <interface type='network'>
      部分,确保其配置如下:
      <interface type='network'>
        <mac address='52:54:00:xx:xx:xx'/>
        <source network='default'/>
        <model type='virtio'/>
        <address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
      </interface>

      <source network='default'/>
      是关键,它将虚拟机连接到名为
      default
      libvirt
      网络。
  5. 启动虚拟机并验证网络: 启动你的虚拟机。进入虚拟机内部,检查其网络配置。如果虚拟机配置为DHCP客户端(大多数Linux发行版默认如此),它应该会自动从

    libvirt
    的DHCP服务获取到一个IP地址(例如
    192.168.122.x
    ),网关是
    192.168.122.1
    。 尝试
    ping 8.8.8.8
    或访问一个网站,验证虚拟机是否能正常访问外部网络。

这个过程听起来可能有些繁琐,但一旦

default
网络配置好,后续的虚拟机直接选择连接它就行,非常方便。我个人更倾向于KVM/QEMU,因为它更底层、更灵活,也更符合Linux的生态。 为什么选择NAT网络而不是桥接网络?它们各自有什么优缺点?

在选择虚拟机网络模式时,NAT(网络地址转换)和桥接(Bridge)是最常见的两种。它们各自有其适用场景和优缺点,我通常会根据具体需求来权衡。

NAT网络(Network Address Translation)

  • 优点:

    • 简单易用: 通常是默认设置,配置最简单。宿主机充当路由器,虚拟机在独立的私有网络中,通过宿主机的IP访问外部网络。
    • 安全性高: 虚拟机与宿主机所在局域网是隔离的。外部网络无法直接访问虚拟机,增加了安全屏障。
    • 对宿主网络无侵入: 虚拟机不会在宿主机的局域网中占用IP地址,避免了潜在的IP冲突问题,特别适合在公共Wi-Fi或不确定网络环境下使用。
    • 宿主机IP变化不影响虚拟机: 即使宿主机的IP地址变化(例如从一个Wi-Fi切换到另一个),虚拟机通常也能保持稳定的互联网连接,因为NAT机制会处理地址转换。
  • 缺点:

    • 外部无法直接访问虚拟机: 这是最大的限制。如果想让局域网内的其他设备或外部网络访问虚拟机提供的服务(如Web服务器),需要进行复杂的端口转发配置。
    • 性能略低: 理论上,NAT模式下数据包需要经过宿主机的地址转换,相比桥接模式可能会有轻微的性能开销,但在大多数日常使用中感知不明显。
    • 网络隔离: 虚拟机之间、虚拟机与宿主机局域网其他设备之间的通信需要通过宿主机转发,这在某些需要局域网内互通的场景下可能不便。

桥接网络(Bridged Network)

  • 优点:

    • 虚拟机作为独立设备: 虚拟机就像局域网中的一台物理机器,拥有独立的IP地址,可以直接与局域网内的其他设备通信,也可以直接被外部访问(如果防火墙允许)。
    • 高性能: 数据包直接通过虚拟网桥转发到物理网卡,性能接近物理机。
    • 方便服务暴露: 如果虚拟机需要提供服务(如Web服务器、数据库),桥接模式最方便,无需额外的端口转发。
  • **缺点:

    • 配置相对复杂: 特别是宿主机使用无线网络时,配置虚拟网桥可能会遇到一些挑战。
    • 可能引起IP冲突: 虚拟机需要从宿主机的局域网中获取一个IP地址,如果管理不善,可能会与局域网内其他设备冲突。
    • 安全性较低: 虚拟机直接暴露在局域网中,需要更强的防火墙保护。
    • 依赖宿主网络: 宿主机的网络环境变化(如IP地址变更),可能会直接影响虚拟机的网络连接。

我的选择偏好:

Teleporthq Teleporthq

一体化AI网站生成器,能够快速设计和部署静态网站

Teleporthq182 查看详情 Teleporthq

我个人在日常开发和测试中,如果只是想让虚拟机能够上网,并且不需要外部访问,NAT网络是我的首选。它简单、安全、可靠。但如果我需要搭建一个内部服务,让团队成员能够访问,或者进行网络攻防实验,那么桥接网络的优势就凸显出来了,虽然配置上可能需要多花点心思。

配置NAT网络后,虚拟机无法访问外部网络怎么办?常见排查思路和解决办法。

虚拟机配置了NAT网络后,却无法访问外部网络,这确实是让人头疼的问题。我遇到过不少次,通常都是一些细节没到位。这里整理一些常见的排查思路和解决办法,希望能帮你快速定位问题。

  1. 检查宿主机

    libvirt
    网络状态: 这是第一步,也是最容易被忽视的。
    • 网络是否启动?
      virsh net-list --all

      确保你的NAT网络(通常是

      default
      )状态是
      active
      。如果不是,执行
      virsh net-start default
      启动它。
    • 网络是否设置为自启动? 如果每次重启宿主机后都要手动启动网络,那它可能没有设置为自启动。
      virsh net-autostart default
      可以解决这个问题。
    • 网络定义是否正确?
      virsh net-edit default
      ,检查XML配置,特别是
      <forward mode='nat'/>
      <bridge name='virbr0'/>
      以及
      <ip ...>
      部分,确保没有语法错误或不合理的IP范围。
  2. 检查虚拟机网卡配置:

    • 虚拟机是否连接到正确的网络? 在
      virt-manager
      中查看虚拟机硬件详情,或者使用
      virsh edit <vm_name>
      ,确认
      <interface type='network'>
      中的
      <source network='default'/>
      (或你自定义的NAT网络名称)是正确的。
    • 网卡是否启用? 进入虚拟机内部,使用
      ip a
      ifconfig
      检查网卡是否已启用并获取到IP地址。
    • IP地址、网关和DNS是否正确? 虚拟机应该通过DHCP获取到IP地址(例如
      192.168.122.x
      ),网关是
      libvirt
      网络的IP地址(例如
      192.168.122.1
      ),DNS服务器通常也会由DHCP分配。
      • 检查IP地址和网关:
        ip route
      • 检查DNS服务器:
        cat /etc/resolv.conf
        如果IP地址不对或者没有获取到,尝试重启虚拟机内部的网络服务(如
        sudo systemctl restart NetworkManager
        sudo service networking restart
        ),或者检查DHCP客户端是否运行。
  3. 宿主机防火墙问题: 这是另一个常见的“坑”。宿主机上的防火墙可能会阻止NAT转发。

    • firewalld
      : 如果你使用的是
      firewalld
      libvirt
      通常会添加必要的规则。但有时可能会被其他规则干扰。你可以尝试临时关闭
      firewalld
      进行测试(
      sudo systemctl stop firewalld
      ,注意:生产环境慎用!)。如果关闭后网络正常,说明是防火墙问题。你需要确保
      libvirt
      服务对应的区域(通常是
      libvirt
      区域)是正确的,并且允许了转发。
    • ufw
      ufw
      也可能需要特殊配置。确保相关端口或转发规则没有被阻断。
    • iptables
      libvirt
      在启动NAT网络时会自动添加
      iptables
      规则。你可以查看
      iptables -t nat -L
      iptables -L -v
      ,检查是否有正确的
      POSTROUTING
      FORWARD
      规则。如果宿主机上部署了其他
      iptables
      规则,可能会覆盖或干扰
      libvirt
      的规则。
  4. 宿主机IP转发是否开启: NAT功能依赖于宿主机内核的IP转发功能。

    • 检查:
      cat /proc/sys/net/ipv4/ip_forward
      ,如果输出是
      0
      ,表示未开启。
    • 开启:
      echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward
    • 永久开启:编辑
      /etc/sysctl.conf
      ,添加或修改
      net.ipv4.ip_forward = 1
      ,然后执行
      sudo sysctl -p
      使之生效。
  5. DNS解析问题: 如果能

    ping 8.8.8.8
    但不能
    ping google.com
    ,那就是DNS解析问题。
    • 检查虚拟机内部的
      /etc/resolv.conf
      文件,确保DNS服务器地址是可达且正确的。可以尝试手动将其修改为公共DNS(如
      8.8.8.8
      114.114.114.114
      )进行测试。

排查时,我通常会从虚拟机内部开始,先确认它自身网络配置是否正确,然后逐步向外,检查宿主机的网络服务、防火墙和转发设置。这个过程需要耐心和细致。

如何在NAT模式下让外部网络访问虚拟机提供的服务?(端口转发/Port Forwarding)

在NAT模式下,虚拟机隐藏在宿主机之后,外部网络无法直接访问到它。但如果虚拟机内部运行着Web服务器、SSH服务或其他应用,我们确实需要让外部(包括宿主机所在的局域网)能够访问。这时,就需要用到端口转发(Port Forwarding),它本质上是在宿主机上设置一个规则,将宿主机某个端口收到的连接请求,转发到虚拟机内部的特定IP和端口。

对于KVM/QEMU,实现端口转发主要有两种方式:通过

libvirt
网络定义或直接使用
iptables
规则。我个人倾向于使用
iptables
,因为它更灵活,且在许多场景下是直接可用的。

方法一:通过

libvirt
网络定义(适用于KVM/QEMU)

这种方法是将端口转发规则集成到

libvirt
的网络配置中,由
libvirt
自动管理
iptables
规则。
  1. 编辑NAT网络定义:

    virsh net-edit default

    找到

    <network>
    标签,在
    <forward mode='nat'/>
    之后(或者在
    <ip ...>
    之前),添加
    <portforward>
    规则。
  2. 添加端口转发规则示例: 假设你的虚拟机IP是

    192.168.122.100
    ,内部运行着一个Web服务在
    80
    端口,你想让宿主机
    8080
    端口的请求转发到虚拟机
    80
    端口。
    <network>
      <name>default</name>
      <!-- ... 其他配置 ... -->
      <forward mode='nat'/>
      <portforward name='web-server' proto='tcp'>
        <port start='8080' end='8080'/>
        <target type='ipv4' address='192.168.122.100' port='80'/>
      </portforward>
      <!-- ... 其他配置 ... -->
    </network>
    • name='web-server'
      :给这个转发规则起一个描述性名称。
    • proto='tcp'
      :指定协议,可以是
      tcp
      udp
      all
    • <port start='8080' end='8080'/>
      :宿主机上监听的端口范围。这里是
      8080
    • <target type='ipv4' address='192.168.122.100' port='80'/>
      :虚拟机内部的IP地址和目标端口。
  3. 保存并重启网络: 保存XML文件。然后需要停止并重新启动

    default
    网络,以使更改生效:
    virsh net-destroy default
    virsh net-start default

    注意: 停止网络会导致所有连接到该网络的虚拟机暂时断网。

方法二:直接使用

iptables
命令(更灵活,适用于所有Linux NAT场景)

这种方法直接在宿主机上添加

iptables
的DNAT(Destination NAT)规则。它的好处是不依赖
libvirt
的网络定义,可以更精细地控制。
  1. 确认IP转发已开启: 如果未开启,请参照上一节的方法开启:

    net.ipv4.ip_forward = 1
  2. 添加

    iptables
    DNAT规则: 假设你的宿主机IP是
    192.168.1.10
    (或者宿主机面向外部的网卡IP),虚拟机IP是
    192.168.122.100
    。你想将宿主机
    8080
    端口的TCP请求转发到虚拟机
    80
    端口。
    sudo iptables -t nat -A PREROUTING -p tcp --dport 8080 -j DNAT --to-destination 192.168.122.100:80
    sudo iptables -A FORWARD -p tcp -d 192.168.122.100 --dport 80 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
    • 第一条规则:在
      nat
      表的
      PREROUTING
      链中添加一条规则。当收到目标端口为
      8080
      的TCP请求时,将其目的地址改为
      192.168.122.100:80
    • 第二条规则:在
      filter
      表的
      FORWARD
      链中添加一条规则,允许转发到虚拟机
      192.168.122.100
      80
      端口的TCP流量通过。这通常是必要的,因为默认的
      FORWARD
      策略可能是
      DROP
  3. 使

    iptables
    规则持久化:
    iptables
    规则在系统重启后会丢失,除非你保存它们。
    • 使用
      netfilter-persistent
      (Debian/Ubuntu):
      sudo apt-get

以上就是Linux如何配置虚拟机NAT网络的详细内容,更多请关注知识资源分享宝库其它相关文章!

相关标签: linux go 防火墙 虚拟机 路由器 端口 ubuntu 工具 mac ai 路由 wi-fi dns google echo xml Filter 接口 Interface default 数据库 udp linux ubuntu ssh debian 虚拟化 大家都在看: 如何在Linux命令行中进行文件操作? 如何在Linux中监控网络接口流量? Linux命令行中top与htop命令的对比与使用 如何在Linux命令行中使用alias命令提高效率 如何在Linux中排查网络拥塞?

标签:  虚拟机 配置 网络 

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。