Aller au contenu
Virtualisation medium

Réseau KVM/libvirt : NAT vs Bridge, comprendre et configurer

16 min de lecture

Logo KVM

Vos VMs n’ont pas de réseau ? Vous ne savez pas si vous devez utiliser NAT ou Bridge ? Ce guide vous explique le modèle réseau libvirt et vous aide à configurer le bon mode.

SituationModeCe que ça fait
Lab / développementNAT (défaut)VMs isolées, accès Internet via l’hôte
Services exposés / productionBridgeVMs directement sur le LAN
  • La différence entre L2 (bridge) et L3 (NAT/routage)
  • Le fonctionnement du réseau NAT libvirt (virbr0 + dnsmasq)
  • Comment créer un bridge pour exposer vos VMs
  • Les commandes virsh essentielles pour le réseau

Avant de configurer, comprenez comment les paquets circulent.

CoucheCe qu’elle gèreIdentifiantÉquipement
L2 (liaison)Trames sur le même réseauAdresse MACSwitch
L3 (réseau)Paquets entre réseauxAdresse IPRouteur

Le point clé :

  • Un bridge = switch logiciel = travaille en L2 (il regarde les MAC)
  • Le NAT = travaille en L3 (il réécrit les IP)

Confusion fréquente : virbr0 est un bridge (L2). Le NAT vient de :

  1. <forward mode='nat'/> dans la définition XML
  2. Des règles firewall ajoutées automatiquement par libvirt

Le bridge virbr0 est juste le switch interne qui connecte vos VMs entre elles et à l’hôte.

Après installation de libvirt, un réseau “default” est créé automatiquement :

VM (eth0) → vnet0 → virbr0 → règles firewall (NAT) → interface physique → Internet

Ce que libvirt crée pour vous :

ComposantRôle
virbr0Bridge virtuel (switch L2 interne)
dnsmasqServeur DHCP + DNS pour les VMs
Règles firewallNAT (MASQUERADE) pour l’accès Internet

Les VMs obtiennent une IP en 192.168.122.x, avec l’hôte comme passerelle (192.168.122.1).

ObjetCe que c’estExemple
Virtual NetworkRéseau géré par libvirtdefault (NAT)
BridgeSwitch virtuelvirbr0
vNICCarte réseau d’une VMDéfinie dans le XML
tapInterface hôte connectée à une vNICvnet0, vnet1
CritèreNAT (default)Bridge
ConfigurationAutomatiqueManuelle
IP des VMsPrivées (192.168.122.x)LAN (même réseau que l’hôte)
Accès depuis le LANNon (sauf port forward)Oui
IsolationVMs isoléesVMs exposées
Cas d’usageLab, développementProduction, services

En mode bridge, chaque VM apparaît comme une machine physique sur le LAN. Elle obtient donc une IP du réseau (via DHCP ou statique). Si vous avez un plan d’adressage limité, c’est un point à considérer.

Fenêtre de terminal
virsh net-list --all

Sortie réelle :

Name State Autostart Persistent
--------------------------------------------
default active yes yes

Décryptage :

ColonneSignification
State: activeLe réseau est démarré, les VMs peuvent l’utiliser
Autostart: yesDémarre automatiquement au boot de l’hôte
Persistent: yesDéfini de façon permanente (pas juste en mémoire)

Si le réseau n’est pas actif :

Fenêtre de terminal
virsh net-start default
virsh net-autostart default
Fenêtre de terminal
virsh net-info default

Sortie réelle :

Name: default
UUID: 3f61d934-34f7-4f6d-b394-b186699c16f2
Active: yes
Persistent: yes
Autostart: yes
Bridge: virbr0

Le point clé : Bridge: virbr0 — c’est l’interface sur laquelle vos VMs seront connectées.

Fenêtre de terminal
virsh net-dumpxml default

Sortie réelle :

<network>
<name>default</name>
<uuid>3f61d934-34f7-4f6d-b394-b186699c16f2</uuid>
<forward mode='nat'>
<nat>
<port start='1024' end='65535'/>
</nat>
</forward>
<bridge name='virbr0' stp='on' delay='0'/>
<mac address='52:54:00:a5:f2:39'/>
<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>

Décryptage ligne par ligne :

Élément XMLCe que ça fait
<forward mode='nat'>Active le NAT (MASQUERADE via iptables)
<port start='1024' end='65535'/>Ports sources utilisés pour le NAT
<bridge name='virbr0'/>Nom du bridge virtuel
<ip address='192.168.122.1'>IP de l’hôte sur ce réseau (passerelle)
<dhcp><range.../>Plage DHCP : .2 à .254 (253 IPs disponibles)

Avec virt-install :

Fenêtre de terminal
virt-install --network network=default ...

Ou dans le XML de la VM :

<interface type='network'>
<source network='default'/>
<model type='virtio'/>
</interface>

Le bridge virbr0 existe ?

Fenêtre de terminal
ip addr show virbr0

Sortie réelle :

178: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN
link/ether 52:54:00:a5:f2:39 brd ff:ff:ff:ff:ff:ff
inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0
valid_lft forever preferred_lft forever

Décryptage :

  • state DOWN + NO-CARRIER = normal si aucune VM n’est connectée
  • inet 192.168.122.1/24 = l’hôte est la passerelle pour les VMs

Le serveur DHCP (dnsmasq) tourne ?

Fenêtre de terminal
ps aux | grep dnsmasq | grep libvirt

Sortie réelle :

libvirt+ 3754413 /usr/sbin/dnsmasq --conf-file=/var/lib/libvirt/dnsmasq/default.conf ...

libvirt lance automatiquement dnsmasq pour fournir DHCP et DNS aux VMs.

Les règles NAT sont en place ?

Fenêtre de terminal
sudo iptables -t nat -L LIBVIRT_PRT -n -v

Sortie réelle :

Chain LIBVIRT_PRT (1 references)
pkts bytes target prot opt in out source destination
0 0 RETURN 0 -- * * 192.168.122.0/24 224.0.0.0/24
0 0 MASQUERADE 6 -- * * 192.168.122.0/24 !192.168.122.0/24 masq ports: 1024-65535
0 0 MASQUERADE 17 -- * * 192.168.122.0/24 !192.168.122.0/24 masq ports: 1024-65535
0 0 MASQUERADE 0 -- * * 192.168.122.0/24 !192.168.122.0/24

Décryptage : le trafic venant de 192.168.122.0/24 (vos VMs) vers l’extérieur est “masqué” (MASQUERADE = NAT dynamique).

Une fois votre VM démarrée et connectée au réseau default :

Fenêtre de terminal
# Dans la VM
ip addr # IP en 192.168.122.x ?
ping -c 2 192.168.122.1 # Passerelle (l'hôte)
ping -c 2 1.1.1.1 # Internet
host google.com # DNS (fourni par dnsmasq)

En mode bridge, vos VMs sont directement connectées au réseau physique.

Fenêtre de terminal
ip link show | grep -E '^[0-9]+:' | grep -v -E 'lo|virbr|docker|veth|br-'

Sortie exemple :

2: enp2s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 ... state UP ...
3: enp3s0: <BROADCAST,MULTICAST> mtu 1500 ... state DOWN ...

L’interface UP (ici enp2s0) est celle connectée au réseau.

C’est la méthode standard sur Ubuntu Server. Vérifiez votre config actuelle :

Fenêtre de terminal
cat /etc/netplan/*.yaml

Exemple de config actuelle :

network:
ethernets:
enp2s0:
dhcp4: true
version: 2

Créer un bridge — Modifiez le fichier (ou créez /etc/netplan/01-bridge.yaml) :

network:
version: 2
ethernets:
enp2s0:
dhcp4: false # Plus de DHCP sur l'interface physique
bridges:
br0:
interfaces: [enp2s0] # L'interface physique rejoint le bridge
dhcp4: true # Le bridge obtient l'IP
# OU pour IP statique :
# addresses: [192.168.1.100/24]
# routes:
# - to: default
# via: 192.168.1.1
# nameservers:
# addresses: [192.168.1.1, 8.8.8.8]

Appliquer (avec rollback automatique si échec) :

Fenêtre de terminal
sudo netplan try # Applique pendant 120s, rollback si pas confirmé
# Si OK, tapez ENTER pour confirmer
sudo netplan apply # Application définitive

Méthode 2 : NetworkManager (Fedora, RHEL, Ubuntu Desktop)

Section intitulée « Méthode 2 : NetworkManager (Fedora, RHEL, Ubuntu Desktop) »
  1. Identifier votre interface physique

    Fenêtre de terminal
    nmcli device status
  2. Créer le bridge

    Fenêtre de terminal
    sudo nmcli connection add type bridge ifname br0 con-name br0
    sudo nmcli connection modify br0 ipv4.method auto # ou manual pour IP statique
  3. Connecter l’interface physique au bridge

    Fenêtre de terminal
    sudo nmcli connection add type bridge-slave ifname enp2s0 master br0
  4. Activer le bridge

    Fenêtre de terminal
    sudo nmcli connection down "Wired connection 1" # Connexion actuelle
    sudo nmcli connection up br0
  5. Vérifier

    Fenêtre de terminal
    ip addr show br0 # Le bridge a l'IP
    bridge link show # enp2s0 est connecté au bridge
Fenêtre de terminal
ip addr show br0

Sortie attendue :

XX: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 ... state UP ...
inet 192.168.1.100/24 ... # L'IP est sur le bridge, pas sur enp2s0
Fenêtre de terminal
bridge link show

Sortie attendue :

2: enp2s0: <BROADCAST,MULTICAST,UP,LOWER_UP> ... master br0 state forwarding

L’interface physique (enp2s0) est maintenant esclave du bridge (master br0).

Si vous voulez utiliser --network network=... plutôt que --network bridge=... :

Fenêtre de terminal
cat > /tmp/host-bridge.xml << 'EOF'
<network>
<name>host-bridge</name>
<forward mode="bridge"/>
<bridge name="br0"/>
</network>
EOF
virsh net-define /tmp/host-bridge.xml
virsh net-start host-bridge
virsh net-autostart host-bridge

Option directe (recommandée) :

Fenêtre de terminal
virt-install --network bridge=br0 ...

Ou dans le XML :

<interface type='bridge'>
<source bridge='br0'/>
<model type='virtio'/>
</interface>
Fenêtre de terminal
# Sur l'hôte : la VM est connectée au bridge
bridge link show br0
# Doit montrer : eno1 + vnetX
# Depuis la VM
ip addr # IP du LAN (ex: 192.168.1.x)
ping 192.168.1.1 # Passerelle du LAN
# Depuis une autre machine du LAN
ping <ip-de-la-vm> # Doit répondre
CommandeDescriptionExemple de sortie
virsh net-list --allLister les réseauxdefault active yes yes
virsh net-info <nom>Détails d’un réseauBridge, UUID, état
virsh net-dumpxml <nom>Configuration XML complèteVoir plus haut
virsh net-start <nom>Démarrer un réseau
virsh net-autostart <nom>Activer au boot
virsh domiflist <vm>Interfaces d’une VMvnet0 bridge virbr0
virsh domifaddr <vm>IP d’une VMNécessite guest agent
SymptômeDiagnosticSolution
virsh net-list videvirsh uriqemu:///sessionConfigurer LIBVIRT_DEFAULT_URI
Réseau default inactifvirsh net-list → State inactivevirsh net-start default
VM n’obtient pas d’IPps aux | grep dnsmasqVérifier que dnsmasq tourne
VM pas de sortie Internetsudo iptables -t nat -LVérifier règles MASQUERADE
Bridge br0 sans IPip addr show br0L’interface physique n’est pas esclave
  1. NAT = réseau privé (192.168.122.x), VMs isolées, accès Internet via l’hôte. C’est le défaut libvirt.

  2. Bridge = VMs sur le LAN, chaque VM consomme une IP, nécessite configuration manuelle.

  3. virbr0 est un bridge L2. Le NAT vient de <forward mode='nat'/> + règles iptables (MASQUERADE).

  4. dnsmasq fournit DHCP + DNS aux VMs en mode NAT.

  5. Netplan (Ubuntu) ou NetworkManager (Fedora/RHEL) pour créer un bridge.

  6. Toujours avoir un accès console avant de modifier le réseau.

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracing. Aujourd'hui, ce site ne couvre même pas mes frais d'hébergement, d'électricité, de matériel, de logiciels, mais surtout de cafés.

Un soutien régulier, même symbolique, m'aide à garder ces ressources gratuites et à continuer de produire des guides de qualité. Merci pour votre appui.