LFCE 144 ๐ง KVM Networking โ Bridges and NAT
KVM virtual machines need a network path to communicate with each other, with the host, and with the outside world. The two primary mechanisms are NAT, which hides the VMs behind the host’s IP address, and bridging, which places the VMs directly on the physical LAN with their own routable IPs. The choice between them is a decision about reachability: a VM that only needs outbound internet access can use NAT, but a VM that needs to accept incoming connections from the LAN must use a bridge.
This chapter covers both modes: the default NAT network (virbr0) that libvirt creates automatically, the host bridge (br0) that connects a VM’s tap interface to the physical NIC, and the virsh commands that define, start, and inspect the networks. It also covers the macvtap alternative for direct attachment without a bridge, and the firewall considerations that often prevent a correctly configured bridge from passing traffic.
Key point: The default NAT network works out of the box but makes VMs unreachable from the LAN. A bridged network makes VMs first-class citizens on the physical network, but requires creating a host bridge and attaching the physical NIC to it. The virsh net-define command registers a libvirt network; the ip link command creates the underlying Linux bridge.
Why the two modes exist
The reachability problem. NAT is the default because it requires no configuration. libvirt creates a virtual bridge (virbr0), runs a DHCP server on it, and adds firewall rules that masquerade the VMs’ outbound traffic through the host’s IP . The VM can reach the internet, but the internet cannot reach the VM. For a development VM, this is sufficient. For a production web server, it is not.
The bridge problem. A bridge places the VM’s virtual NIC on the same layer-2 network as the host’s physical NIC. The VM gets an IP from the LAN’s DHCP server (or a static assignment), and it is reachable by that IP from any other machine on the LAN . The host’s physical interface becomes a member of the bridge, and the VM’s vnetX interface is attached to the same bridge. The host and the VM are peers on the network.
The macvtap problem. macvtap is a middle ground. It attaches the VM directly to the physical interface without creating a Linux bridge, giving the VM a private MAC-VLAN endpoint on the wire. It avoids the bridge configuration overhead, but the host cannot communicate with the VM over the macvtap interface in the default mode . Red Hat recommends a Linux bridge over macvtap unless the use case explicitly requires macvtap .
a. The default NAT network
libvirt creates the default NAT network on installation. It is defined in /etc/libvirt/qemu/networks/default.xml and is active by default on most distributions.
# Check the default network
virsh net-list --all
# Name State Autostart Persistent
# default active yes yes
The network’s XML definition uses virbr0 as the bridge, 192.168.122.0/24 as the subnet, and a forward element with mode='nat' .
<network>
<name>default</name>
<forward mode='nat'>
<nat>
<port start='1024' end='65535'/>
</nat>
</forward>
<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>
A VM attached to the default network receives an address in the 192.168.122.0/24 range from the dnsmasq instance that libvirt runs. Outbound traffic is masqueraded through the host’s default route. Inbound traffic is blocked unless a port-forwarding rule is added to the host’s firewall .
To attach a VM to the default NAT network:
virt-install --name test-vm --network network=default,model=virtio ...
The model=virtio selects the paravirtualized network driver, which is faster than the emulated e1000 or rtl8139 drivers.
b. The bridged network
A bridged network requires a Linux bridge on the host with the physical NIC attached. The VM’s vnetX interface is then attached to the same bridge, placing it on the physical LAN.
The bridge can be created with nmcli, ip link, or the distribution’s network configuration. The virsh iface-bridge command is a libvirt shortcut that creates the bridge and attaches the physical interface in one step .
# Create a bridge and attach eth0 to it (libvirt shortcut)
virsh iface-bridge eth0 br0
This moves the host’s IP address from eth0 to br0. The host remains reachable on the same address, but the address is now on the bridge instead of the physical interface. The physical interface becomes a member of the bridge with no IP of its own.
For a more controlled configuration, the bridge can be created with ip link:
# Create the bridge
ip link add name br0 type bridge
# Attach the physical interface
ip link set eth0 master br0
# Bring up the bridge
ip link set br0 up
Once the bridge exists, a libvirt network can be defined to reference it. The network’s XML uses forward mode='bridge' and specifies the bridge name.
<network>
<name>host-bridge</name>
<forward mode='bridge'/>
<bridge name='br0'/>
</network>
# Define, start, and autostart the network
virsh net-define br0-network.xml
virsh net-start host-bridge
virsh net-autostart host-bridge
A VM can then be attached to the bridge either through the libvirt network (--network network=host-bridge) or directly by specifying the bridge name in the VM’s interface definition .
<interface type='bridge'>
<source bridge='br0'/>
<model type='virtio'/>
</interface>
The VM receives an IP address from the LAN’s DHCP server (or a static assignment) and is reachable by that address from any machine on the LAN. The host and the VM are peers on the same network .
c. Firewall and bridge netfilter
A correctly configured bridge can still fail to pass traffic if the host’s firewall is blocking it. The firewalld service may treat the bridge as a separate zone with different rules. The kernel’s bridge netfilter may also be enabled, which causes iptables rules to apply to bridged traffic in ways that surprise administrators .
# Check if bridge netfilter is enabled
sysctl net.bridge.bridge-nf-call-iptables
# If it is 1 and traffic is failing, try setting it to 0
sysctl -w net.bridge.bridge-nf-call-iptables=0
On systems with firewalld, the bridge interface may need to be added to a trusted zone or the appropriate zone for the LAN.
# Add the bridge to the trusted zone
firewall-cmd --permanent --zone=trusted --add-interface=br0
firewall-cmd --reload
The clean-traffic network filter is a libvirt feature that prevents MAC and IP spoofing from the guest. It is applied with a <filterref> in the interface definition and is recommended for bridged networks where the guest is on the same layer-2 segment as other machines .
Complete Example Session
# ============================================
# PART 1: THE DEFAULT NAT NETWORK
# ============================================
virsh net-list --all
# The default network is active and autostarted.
# It uses virbr0 and 192.168.122.0/24.
# ============================================
# PART 2: INSPECT THE NAT NETWORK
# ============================================
virsh net-dumpxml default
# Shows the forward mode='nat', the bridge name,
# and the DHCP range.
# ============================================
# PART 3: CREATE A VM ON THE NAT NETWORK
# ============================================
virt-install --name nat-vm \
--vcpus 2 --ram 2048 \
--disk size=10 \
--network network=default,model=virtio \
--cdrom /path/to/iso
# ============================================
# PART 4: CREATE THE HOST BRIDGE
# ============================================
virsh iface-bridge eth0 br0
# The host IP moves from eth0 to br0.
# eth0 becomes a member of the bridge.
# ============================================
# PART 5: VERIFY THE BRIDGE
# ============================================
ip link show type bridge
brctl show br0
# br0 is UP.
# eth0 is a member of br0.
# ============================================
# PART 6: DEFINE THE LIBVIRT BRIDGE NETWORK
# ============================================
cat > br0-network.xml <<'EOF'
<network>
<name>host-bridge</name>
<forward mode='bridge'/>
<bridge name='br0'/>
</network>
EOF
virsh net-define br0-network.xml
virsh net-start host-bridge
virsh net-autostart host-bridge
# ============================================
# PART 7: CREATE A VM ON THE BRIDGE
# ============================================
virt-install --name bridge-vm \
--vcpus 2 --ram 2048 \
--disk size=10 \
--network network=host-bridge,model=virtio \
--cdrom /path/to/iso
# ============================================
# PART 8: VERIFY THE VM'S IP
# ============================================
virsh domifaddr bridge-vm
# The VM has an IP from the LAN's DHCP range.
# It is reachable from other machines on the LAN.
# ============================================
# PART 9: FIREWALL CHECK
# ============================================
sysctl net.bridge.bridge-nf-call-iptables
firewall-cmd --zone=trusted --add-interface=br0
# ============================================
# PART 10: THE MACVTAP ALTERNATIVE
# ============================================
# Direct attachment without a bridge.
# The host cannot reach the VM in default mode.
# Use only when bridge config is not possible.
The ten parts covered the default NAT network, inspecting it, creating a NAT VM, creating the host bridge, verifying the bridge, defining the libvirt network, creating a bridge VM, verifying the VM’s IP, firewall checks, and the macvtap alternative.
Quick Reference
NAT vs Bridge
| Feature | NAT (default) | Bridge |
|---|---|---|
| Default bridge | virbr0 | br0 (host-created) |
| VM IP range | 192.168.122.0/24 | LAN subnet |
| Outbound access | Yes (masqueraded) | Yes (direct) |
| Inbound access | No (without port forward) | Yes (direct) |
| LAN reachability | No | Yes |
| Host-VM communication | Yes | Yes |
| Configuration | None (default) | Host bridge + libvirt network |
virsh network commands
| Command | Purpose |
|---|---|
virsh net-list --all | List all networks |
virsh net-dumpxml <net> | Show network XML |
virsh net-define <file> | Register a network |
virsh net-start <net> | Activate a network |
virsh net-autostart <net> | Start on boot |
virsh net-info <net> | Show network details |
Bridge creation
| Tool | Command |
|---|---|
| libvirt shortcut | virsh iface-bridge eth0 br0 |
| ip link | ip link add name br0 type bridge |
| nmcli | nmcli con add type bridge ifname br0 |
VM interface XML
| Type | Snippet |
|---|---|
| NAT | <interface type='network'><source network='default'/></interface> |
| Bridge | <interface type='bridge'><source bridge='br0'/></interface> |
| macvtap | <interface type='direct'><source dev='eth0' mode='bridge'/></interface> |
Best Practices
โ Do This:
# Use NAT for development VMs that only need outbound access
virt-install --network network=default,model=virtio # โ
# Use a bridge for production VMs that need LAN reachability
virsh iface-bridge eth0 br0 # โ
# Use virtio for the network model
--network network=host-bridge,model=virtio # โ
# Check bridge netfilter if traffic fails
sysctl net.bridge.bridge-nf-call-iptables # โ
โ Don’t Do This:
# Use NAT for a VM that must accept inbound connections
# Port forwarding is required, which is extra configuration # โ
# Assume a bridge works without checking the firewall
# firewalld may block bridged traffic # โ
# Use macvtap when host-VM communication is needed
# The host cannot reach the VM in default mode # โ
Common Pitfalls
| Pitfall | Why It Happens | Fix |
|---|---|---|
| VM unreachable from LAN | NAT network used | Create a bridge and attach the VM |
| Bridge VM has no IP | DHCP not available on the LAN or bridge misconfigured | Check the bridge members and DHCP |
| Bridge traffic blocked | firewalld or bridge netfilter | Add the bridge to a trusted zone; check bridge-nf-call-iptables |
Host loses IP after iface-bridge | The IP moved from eth0 to br0 | Configure the IP on br0 instead |
| macvtap VM cannot reach host | macvtap default mode blocks host-VM traffic | Use a bridge instead |
Real-World Examples
1. Default NAT network
virsh net-list --all
2. NAT VM creation
virt-install --network network=default,model=virtio
3. Create a bridge
virsh iface-bridge eth0 br0
4. Verify bridge members
brctl show br0
5. Define a libvirt bridge network
virsh net-define br0-network.xml
6. Bridge VM creation
virt-install --network network=host-bridge,model=virtio
7. Check VM IP
virsh domifaddr bridge-vm
8. Firewall trust
firewall-cmd --zone=trusted --add-interface=br0
9. Bridge netfilter
sysctl net.bridge.bridge-nf-call-iptables
10. macvtap interface
<interface type='direct'>
<source dev='eth0' mode='bridge'/>
</interface>
Visual
NAT networking
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ HOST โ
โ eth0 (192.168.1.10) โ
โ โ โ
โ โผ โ
โ virbr0 (192.168.122.1) โ
โ โ โ
โ โโโ VM1 (192.168.122.2) โ
โ โโโ VM2 (192.168.122.3) โ
โ โ
โ Outbound: NAT through eth0 โ
โ Inbound: blocked (no port forward) โ
โ LAN cannot reach the VMs directly. โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Bridged networking
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ HOST โ
โ br0 (192.168.1.10) โ
โ โ โ
โ โโโ eth0 (physical, no IP) โ
โ โโโ vnet0 (VM1) โ
โ โโโ vnet1 (VM2) โ
โ โ
โ VM1 and VM2 are on the LAN. โ
โ They get LAN IPs and are reachable from the LAN. โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
The bridge components
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ br0 (bridge) โ
โ โโโ eth0 (physical NIC) โ
โ โโโ vnet0 (VM1 tap) โ
โ โโโ vnet1 (VM2 tap) โ
โ โ
โ All members share the same layer-2 segment. โ
โ The bridge forwards frames between them. โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
The NAT port forward
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ External client โ
โ โ โ
โ โผ โ
โ Host IP:8080 โโโบ DNAT โโโบ VM 192.168.122.50:80 โ
โ โ
โ Without the DNAT rule, inbound is blocked. โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Summary
| Item | Value |
|---|---|
| Default network | NAT, virbr0, 192.168.122.0/24 |
| Bridge network | Host bridge (br0), LAN subnet |
| NAT inbound | Blocked without port forwarding |
| Bridge inbound | Direct |
| Bridge creation | virsh iface-bridge eth0 br0 |
| libvirt network define | virsh net-define <file> |
| VM interface model | virtio (recommended) |
| macvtap limitation | Host cannot reach VM in default mode |
| Firewall | Add bridge to trusted zone if needed |
Key takeaways:
- NAT is the default and requires no configuration. libvirt creates
virbr0, runs DHCP, and masquerades outbound traffic. The VM can reach the internet, but the internet cannot reach the VM without port forwarding . - Bridging makes the VM a peer on the physical LAN. The host’s physical NIC is attached to a Linux bridge, and the VM’s tap interface is attached to the same bridge. The VM gets a LAN IP and is reachable from any machine on the network .
- The bridge must be created on the host before libvirt can use it.
virsh iface-bridgecreates the bridge and moves the host’s IP to it. A libvirt network withforward mode='bridge'references the bridge by name . - Firewall and bridge netfilter can block bridged traffic.
firewalldmay treat the bridge as a separate zone, andnet.bridge.bridge-nf-call-iptablesmay cause iptables rules to filter bridged frames. Check both if the bridge is configured but traffic fails . - macvtap is an alternative but has a host-VM communication limitation. It attaches the VM directly to the physical NIC without a bridge, but the host cannot reach the VM over the macvtap interface in the default mode. Use a bridge when host-VM communication is required .
virtiois the recommended network model. It is paravirtualized and significantly faster than the emulatede1000orrtl8139drivers.
Remember: KVM networking is a choice between reachability and simplicity. NAT is simple and works for development, but the VMs are hidden behind the host. A bridge is more configuration, but it makes the VMs first-class citizens on the LAN. Create the bridge with virsh iface-bridge, define a libvirt network with forward mode='bridge', and attach the VM with model=virtio. Check the firewall and bridge netfilter if the VM has an IP but cannot communicate. And remember that macvtap is not a drop-in replacement for a bridge when the host needs to talk to the VM.
Stop using slow, ad-bloated tool sites! ๐คฎ
๐ Search “KandZ Tools” on Google to use many professional utilities for free.
KandZ.me is the ultimate minimalist hub for:
โ
Finance (Mortgage, Interest, Inflation)
โ
Tech (Base64, JSON, Dev Suite, IP)
โ
Health (BMI, BMR, TDEE)
โ
Productivity (Timer, Workspace, QR)
โก๏ธ Fast & Private
๐ No data leaves your device
๐ 100% Free
๐ Use it now: https://tools.kandz.me
๐ Bookmark itโyouโll need it later!