KVM Virtualization (Networking)
Advanced KVM networking configurations
Section titled “Advanced KVM networking configurations”0. Specs
Section titled “0. Specs”0.0. Definition
Section titled “0.0. Definition”KVM Virtualization Tutorial 2 for Debian and Ubuntu Server.
Please refer to the KVM Virtualization Beginner tutorial before reading this one.
This tutorial focuses on KVM networking configurations.
0.1. Infrastructure
Section titled “0.1. Infrastructure”- Server (Host): Debian (13/12) or Ubuntu (24.04/22.04) Server
- IP: 192.168.1.121
- Name: elma
- NIC1: enp3s0f0
- NIC2: enx00e04c534458 (USB network adapter)
- Network1: 192.168.1.0/24 (internet modem/router, first interface)
- Network2: 10.1.1.0/24 (external switch, second interface)
- Workstation: Debian 13 or Ubuntu 24.04 LTS Desktop
0.2. Resources
Section titled “0.2. Resources”- ISBN: 978-1-78829-467-6 KVM Virtualization Cookbook by Konstantin Ivanov
- ISBN: 978-1-83882-871-4 Mastering KVM Virtualization 2nd Ed. by Vedran Dakic, Humble Devassy Chirammal, Prasad Mukhedkar, Anil Vettathu
1. KVM Networks - Configuration Commands
Section titled “1. KVM Networks - Configuration Commands”While numerous variations exist, KVM supports three basic network types:
- Bridged: VMs appear as physical devices on the network
- NAT: VMs share host’s IP with network address translation
- Isolated: VMs communicate only with each other and host
1.1. Active Networks
Section titled “1.1. Active Networks”List KVM Networks:
virsh net-listExample output (after Tutorial 1 bridge configuration):
Name State Autostart Persistent------------------------------------------------- host-bridge active yes yesDisplay detailed network information:
virsh net-info NETWORKNAMEvirsh net-info host-bridgeExample output:
Name: host-bridgeUUID: a67dfcef-86e9-4e4c-832f-bc14443da475Active: yesPersistent: yesAutostart: yesBridge: br0Display network configuration as XML:
virsh net-dumpxml NETWORKNAMEvirsh net-dumpxml host-bridgeExample output:
<network> <name>host-bridge</name> <uuid>a67dfcef-86e9-4e4c-832f-bc14443da475</uuid> <forward mode='bridge'/> <bridge name='br0'/></network>1.2. Adding a Network
Section titled “1.2. Adding a Network”To add a network, create an XML configuration file and define it:
virsh net-define XMLFILEExample: Create a second bridge on the second interface.
First, create the bridge on the host system.
Ubuntu Bridge Configuration
Section titled “Ubuntu Bridge Configuration”Edit Netplan configuration:
sudo nano /etc/netplan/01-netcfg.yamlReplace content with (adjust interface names and IPs):
network: ethernets: enp3s0f0: dhcp4: false dhcp6: false enx00e04c534458: dhcp4: false dhcp6: false bridges: br0: interfaces: [ enp3s0f0 ] addresses: [192.168.1.121/24] routes: - to: default via: 192.168.1.1 mtu: 1500 nameservers: addresses: - 8.8.8.8 - 8.8.4.4 parameters: stp: true forward-delay: 4 dhcp4: false dhcp6: false br1: interfaces: [ enx00e04c534458 ] addresses: [10.1.1.1/24] routes: - to: 10.1.1.0/24 via: 10.1.1.1 mtu: 1500 nameservers: addresses: [8.8.8.8,8.8.4.4] dhcp4: false dhcp6: false version: 2Apply configuration:
sudo netplan applyDebian Bridge Configuration
Section titled “Debian Bridge Configuration”Edit network interfaces file:
sudo nano /etc/network/interfacesReplace content with (adjust interface names and IPs):
# This file describes the network interfaces available on your system# and how to activate them. For more information, see interfaces(5).
source /etc/network/interfaces.d/*auto loiface lo inet loopback# The primary network interfaceauto enp3s0f0#make sure we don't get addresses on our raw deviceiface enp3s0f0 inet manual#set up bridge and give it a static ipauto br0iface br0 inet static address 192.168.1.121 netmask 255.255.255.0 network 192.168.1.0 broadcast 192.168.1.255 gateway 192.168.1.1 bridge_ports enp3s0f0 bridge_stp off bridge_fd 0 bridge_maxwait 0 dns-nameservers 8.8.8.8auto br1iface br1 inet static address 10.1.1.1 netmask 255.255.255.0 network 10.1.1.0 broadcast 10.1.1.255 bridge_ports enx00e04c534458 bridge_stp off bridge_fd 0 bridge_maxwait 0Apply configuration (SSH may disconnect):
sudo systemctl restart networking.serviceAdd Bridge to KVM
Section titled “Add Bridge to KVM”Create XML configuration for the second bridge:
sudo nano host-bridge2.xmlFill as below:
<network> <name>host-bridge2</name> <uuid>c723a80b-d496-460e-9235-9eced7b218cf</uuid> <forward mode='bridge'/> <bridge name='br1'/></network>Note: Generate a unique UUID with uuidgen if needed.
Define, start, and enable autostart:
virsh net-define host-bridge2.xmlvirsh net-start host-bridge2virsh net-autostart host-bridge2Now you have two bridges:
br0for 192.168.1.0/24 networkbr1for 10.1.1.0/24 network
1.3. Stopping and Removing KVM Networks
Section titled “1.3. Stopping and Removing KVM Networks”Stop a KVM Network:
virsh net-destroy NETWORKNAMEvirsh net-destroy host-bridge2Disable autostart:
virsh net-autostart NETWORKNAME --disablevirsh net-autostart host-bridge2 --disableRemove network definition:
virsh net-undefine NETWORKNAMEvirsh net-undefine host-bridge22. KVM Networks - Network Types
Section titled “2. KVM Networks - Network Types”When creating KVM network XML files, use unique UUID and MAC values for each network.
Generate a random UUID:
uuidgenGenerate a random MAC address (or use online tools like Browserling Random MAC Generator).
2.1. Bridged Networks
Section titled “2.1. Bridged Networks”Bridged networks connect VMs directly to the host’s physical network. VMs appear as separate devices on the same network segment as the host.
Use cases:
- Public-facing servers
- Services requiring direct network access
- Environments with existing DHCP infrastructure
Requirements:
- Create a bridge in the host’s network configuration
- Define the bridge in KVM via XML
Example XML configuration:
<network> <name>host-bridge2</name> <uuid>c723a80b-d496-460e-9235-9eced7b218cf</uuid> <forward mode='bridge'/> <bridge name='br1'/></network>Customization:
- Replace
host-bridge2with your network name - Replace UUID with a generated value
- Replace
br1with your actual bridge interface name
Network integration:
- VMs receive IPs from the same DHCP server as the host
- VMs are directly accessible from the network
- No NAT translation occurs
2.2. NAT Network
Section titled “2.2. NAT Network”NAT (Network Address Translation) networks allow VMs to access external networks while remaining hidden behind the host’s IP address.
Use cases:
- Development and testing environments
- VMs requiring internet access but not public exposure
- Security-focused deployments
Example XML configuration:
<network> <name>nat</name> <uuid>d589efd6-7d61-4f92-976b-bde62956cca7</uuid> <forward mode='nat'> <nat> <port start='1024' end='65535'/> </nat> </forward> <bridge name='brnat' stp='on' delay='0'/> <mac address='4a:c3:6a:72:c2:30'/> <ip address='192.168.122.1' netmask='255.255.255.0'> <dhcp> <range start='192.168.122.101' end='192.168.122.254'/> </dhcp> </ip></network>Customization:
- Replace
natwith your network name - Replace UUID with a generated value
- Replace
brnatwith your preferred bridge name - Replace MAC address with a generated value
- Adjust IP subnet and DHCP range as needed
Network behavior:
- VMs can initiate connections to external networks
- External hosts cannot initiate connections to VMs
- Port forwarding can be configured for specific services
- Built-in DHCP server provides IP addresses
2.3. Isolated Network
Section titled “2.3. Isolated Network”Isolated networks create completely private segments where VMs can communicate only with each other and the host.
Use cases:
- Database backends
- Internal service communication
- Security-sensitive applications
- Testing environments requiring network isolation
Example XML configuration:
<network> <name>isolated</name> <uuid>a67bbbaf-81e9-4e4c-832f-bc14443da475</uuid> <bridge name='brisolated' stp='on' delay='0'/> <mac address='4a:c3:6a:72:c2:26'/> <domain name='myisolateddomain'/> <ip address='192.168.20.1' netmask='255.255.255.0'> <dhcp> <range start='192.168.20.101' end='192.168.20.200'/> </dhcp> </ip></network>Customization:
- Replace
isolatedwith your network name - Replace UUID with a generated value
- Replace
brisolatedwith your preferred bridge name - Replace MAC address with a generated value
- Adjust IP subnet and DHCP range as needed
- Set domain name for internal DNS
Security architecture example:
Internet ── [Web Server (dual NIC)] ── [Database Server] bridged:192.168.1.x/24 isolated:192.168.20.x/24Implementation:
- Web server: One interface in bridged network, one in isolated network
- Database server: Only isolated network interface
- Result: Database accessible only via web server
Network characteristics:
- No external network access
- Built-in DHCP server
- Internal DNS resolution via domain name
- Complete isolation from external traffic
3. Case Study A: Bridged and Isolated Networks Together
Section titled “3. Case Study A: Bridged and Isolated Networks Together”3.1. Specifications
Section titled “3.1. Specifications”- Network1: Bridged network on 192.168.1.0/24 (existing)
- Network2: Isolated network on 192.168.20.0/24 (to create)
- VM1: Two network interfaces
- Interface 1: Network1 (bridged)
- Interface 2: Network2 (isolated)
- VM2: One network interface
- Interface: Network2 (isolated)
Architecture:
- VM1: Accessible from all network devices (via Network1)
- VM2: Accessible only from VM1 (via Network2)
- VM1 acts as a gateway between the two networks
3.2. Create the Isolated Network
Section titled “3.2. Create the Isolated Network”Create XML configuration file:
nano isolated.xmlFill as below:
<network> <name>isolated</name> <uuid>a67bbbaf-81e9-4e4c-832f-bc14443da475</uuid> <bridge name='brisolated' stp='on' delay='0'/> <mac address='4a:c3:6a:72:c2:26'/> <domain name='myisolateddomain'/> <ip address='192.168.20.1' netmask='255.255.255.0'> <dhcp> <range start='192.168.20.101' end='192.168.20.200'/> </dhcp> </ip></network>Define and activate the network:
virsh net-define isolated.xmlvirsh net-start isolatedvirsh net-autostart isolatedVerify network creation:
virsh net-list --all3.3. Create VMs with Dual Network Configuration
Section titled “3.3. Create VMs with Dual Network Configuration”Create VM1 (dual-homed):
sudo virt-install --name vm1 \ --connect qemu:///system --virt-type kvm \ --memory 1024 --vcpus 1 \ --disk /srv/kvm/vm1.qcow2,format=qcow2,size=10 \ --cdrom /srv/isos/ubuntu-24.04.2-live-server-amd64.iso \ --network bridge=br0 \ --network bridge=brisolated \ --graphics vnc,port=5901,listen=0.0.0.0 \ --os-variant ubuntu22.04 \ --noautoconsoleCreate VM2 (isolated):
sudo virt-install --name vm2 \ --connect qemu:///system --virt-type kvm \ --memory 1024 --vcpus 1 \ --disk /srv/kvm/vm2.qcow2,format=qcow2,size=10 \ --cdrom /srv/isos/ubuntu-24.04.2-live-server-amd64.iso \ --network bridge=brisolated \ --graphics vnc,port=5902,listen=0.0.0.0 \ --os-variant ubuntu22.04 \ --noautoconsoleNote for Debian 12 hosts: Replace --os-variant ubuntu24.04 with --os-variant ubuntu22.04.
Connect to VMs from your workstation to complete installation:
3.4. Network Configuration Considerations
Section titled “3.4. Network Configuration Considerations”Isolated Network Limitations:
- VM2 cannot access external networks (including internet)
- VM2 cannot receive updates or install packages directly
- VM1 can access both networks and act as a gateway
You can install Squid proxy on the host to provide internet access for isolated VMs.
4. Case Study B: Separating Host and VM Access with 2 NICs
Section titled “4. Case Study B: Separating Host and VM Access with 2 NICs”Separating host and VM network traffic is a recommended practice for improved security, performance, and management. We’ll dedicate one interface for host access and another for VM traffic.
4.1. Specifications
Section titled “4.1. Specifications”- Network: 192.168.1.0/24 (single subnet)
- Host Interfaces:
- NIC1 (enp3s0f0): VM traffic via bridge (192.168.1.121)
- NIC2 (enx00e04c534458): Host management (192.168.1.122)
- VM Configuration: Single interface on bridged network
Benefits:
- Isolate host management traffic from VM traffic
- Prevent VM network issues from affecting host access
- Simplified firewall rules and monitoring
- Better performance isolation
4.2. Host Network Configuration
Section titled “4.2. Host Network Configuration”Configure the server’s network interfaces before KVM setup.
Ubuntu Network Configuration
Section titled “Ubuntu Network Configuration”Edit Netplan configuration:
sudo nano /etc/netplan/01-netcfg.yamlChange as below:
network: ethernets: enp3s0f0: dhcp4: false dhcp6: false enx00e04c534458: addresses: [192.168.1.122/24] routes: - to: 192.168.1.0/24 via: 192.168.1.1 nameservers: addresses: - 8.8.8.8 - 8.8.4.4 bridges: br0: interfaces: [ enp3s0f0 ] addresses: [192.168.1.121/24] routes: - to: default via: 192.168.1.1 mtu: 1500 nameservers: addresses: - 8.8.8.8 - 8.8.4.4 dhcp4: false dhcp6: false version: 2Apply configuration and reboot:
sudo netplan applysudo rebootDebian Network Configuration
Section titled “Debian Network Configuration”Edit network interfaces file:
sudo nano /etc/network/interfaces# This file describes the network interfaces available on your system# and how to activate them. For more information, see interfaces(5).
source /etc/network/interfaces.d/*auto loiface lo inet loopback
# VM traffic interface (bridged)auto enp3s0f0iface enp3s0f0 inet manual
# Bridge for VMsauto br0iface br0 inet static address 192.168.1.121 netmask 255.255.255.0 network 192.168.1.0 broadcast 192.168.1.255 gateway 192.168.1.1 bridge_ports enp3s0f0 bridge_stp off bridge_fd 0 bridge_maxwait 0 dns-nameservers 8.8.8.8
# Host management interfaceauto enx00e04c534458iface enx00e04c534458 inet static address 192.168.1.122 netmask 255.255.255.0 network 192.168.1.0 broadcast 192.168.1.255 gateway 192.168.1.1 dns-nameservers 8.8.8.8Apply configuration (SSH may disconnect):
sudo systemctl restart networking.serviceNote: You may need to reboot because of the previous network configurations may cause instability.
Network Verification:
ip addr show br0ip addr show enx00e04c534458ping -c 3 192.168.1.14.3. KVM Network Configuration
Section titled “4.3. KVM Network Configuration”Skip this step if host-bridge already exists. Define the bridged network in KVM:
Create XML configuration:
nano host-bridge.xmlFill as below:
<network> <name>host-bridge</name> <forward mode="bridge"/> <bridge name="br0"/></network>Define and activate network:
virsh net-define host-bridge.xmlvirsh net-start host-bridgevirsh net-autostart host-bridgeVerify network creation:
virsh net-list --allvirsh net-info host-bridge4.4. Create VM on the Bridged Network
Section titled “4.4. Create VM on the Bridged Network”Create a VM using the bridged interface:
sudo virt-install --name vm3 \ --connect qemu:///system --virt-type kvm \ --memory 1024 --vcpus 1 \ --disk /srv/kvm/vm3.qcow2,format=qcow2,size=10 \ --cdrom /srv/isos/ubuntu-24.04.2-live-server-amd64.iso \ --network bridge=br0 \ --graphics vnc,port=5901,listen=0.0.0.0 \ --os-variant ubuntu22.04 \ --noautoconsoleConnect to VM from your workstation:
virt-viewer --connect qemu+ssh://exforge@elma/system vm3Network Verification:
- Host should be accessible at 192.168.1.122
- VM should obtain an IP from 192.168.1.0/24 range
- Both should have internet access via 192.168.1.1
Firewall Considerations: Consider implementing firewall rules to:
- Restrict host management interface access
- Separate VM traffic rules
- Monitor traffic patterns
5. Case Study C: NAT KVM Network
Section titled “5. Case Study C: NAT KVM Network”We will create a VM, in a NAT network.
5.1. Specifications
Section titled “5.1. Specifications”Create a VM within a NAT (Network Address Translation) network for enhanced security and isolation.
Server Configuration:
- Interface 1 (enp3s0f0): Bridged mode for VMs (as configured in Section 4)
- Interface 2 (enx00e04c534458): Standard mode for host management
- Additional NAT network for isolated VMs
VM Configuration:
- Name:
vmn(VM-NAT) - Single interface connected to NAT network
- Outbound internet access via NAT
- Inbound connections blocked (except port forwarding)
5.2. Host Network Configuration
Section titled “5.2. Host Network Configuration”No changes required if you completed Section 4.2. Verify existing configuration:
ip addr show br0ip addr show enx00e04c5344585.3. KVM NAT Network Configuration
Section titled “5.3. KVM NAT Network Configuration”Create XML configuration file:
nano nat.xmlFill as below:
<network> <name>nat</name> <uuid>d589efd6-7d61-4f92-976b-bde62956cca7</uuid> <forward mode='nat'> <nat> <port start='1024' end='65535'/> </nat> </forward> <bridge name='brnat' stp='on' delay='0'/> <mac address='4a:c3:6a:72:c2:30'/> <ip address='192.168.122.1' netmask='255.255.255.0'> <dhcp> <range start='192.168.122.101' end='192.168.122.254'/> </dhcp> </ip></network>Important: Generate unique values:
- UUID:
uuidgen - MAC address: Use a random generator or
openssl rand -hex 6 | sed 's/\(..\)/\1:/g; s/.$//'
Define and activate the NAT network:
virsh net-define nat.xmlvirsh net-start natvirsh net-autostart natVerify network creation:
virsh net-list --allvirsh net-info natvirsh net-dumpxml nat5.4. Create VM on NAT Network
Section titled “5.4. Create VM on NAT Network”Create the NAT-connected VM:
sudo virt-install --name vmn \ --connect qemu:///system --virt-type kvm \ --memory 1024 --vcpus 1 \ --disk /srv/kvm/vmn.qcow2,format=qcow2,size=10 \ --cdrom /srv/isos/ubuntu-24.04.2-live-server-amd64.iso \ --network bridge=brnat \ --graphics vnc,port=5902,listen=0.0.0.0 \ --os-variant ubuntu22.04 \ --noautoconsoleNote: For Debian 12 hosts, use --os-variant ubuntu22.04.
5.5. NAT Network Behavior
Section titled “5.5. NAT Network Behavior”Outbound Access (VM → External):
- VM can initiate connections to external networks
- Source IP translated to host’s IP (192.168.1.121)
- Source ports mapped to 1024-65535 range
Inbound Access (External → VM):
- External devices cannot initiate connections to VM
- Port forwarding required for specific services
- VM remains hidden behind NAT
Internal Network:
- DHCP range: 192.168.122.101-254
- Gateway: 192.168.122.1 (host)
- DNS: Inherited from host configuration
6. Adding and Removing Networks To/From a VM
Section titled “6. Adding and Removing Networks To/From a VM”Dynamically modify VM network interfaces without recreating the VM.
6.1. Specifications
Section titled “6.1. Specifications”- VM Name:
vmtest - Initial Network:
host-bridge(bridgebr0) - Network to Add:
nat(bridgebrnat) - Network to Remove:
host-bridge(bridgebr0)
Process:
- Create VM with bridged network
- Add NAT network interface
- Configure new interface on VM
- Remove original bridged interface
6.2. Create VM with Bridged Network
Section titled “6.2. Create VM with Bridged Network”Create initial VM:
sudo virt-install --name vmtest \ --connect qemu:///system --virt-type kvm \ --memory 1024 --vcpus 1 \ --disk /srv/kvm/vm.qcow2,format=qcow2,size=10 \ --cdrom /srv/isos/ubuntu-24.04.2-live-server-amd64.iso \ --network bridge=br0 \ --graphics vnc,port=5902,listen=0.0.0.0 \ --os-variant ubuntu22.04 \ --noautoconsole6.3. Add NAT Network Interface
Section titled “6.3. Add NAT Network Interface”Add a second network interface to the running VM:
virsh attach-interface vmtest \ bridge brnat \ --target ens1 \ --configParameters:
bridge brnat: Network type and bridge name--target ens1: Interface name inside VM--config: Persistent after shutdown/start
Restart VM (required for interface activation):
virsh destroy vmtestvirsh start vmtestImportant: virsh reboot may not activate new interfaces; use shutdown/start cycle.
6.4. Configure New Network Interface on VM
Section titled “6.4. Configure New Network Interface on VM”Configure the new interface (ens1) on the Ubuntu VM.
On the VM:
Check available interfaces:
ip link showConfigure Netplan (Ubuntu):
sudo nano /etc/netplan/00-installer-config.yamlnetwork: ethernets: enp1s0: dhcp4: true ens1: dhcp4: true version: 2For Debian VMs, use `/etc/network/interfaces**:
sudo nano /etc/network/interfacesauto loiface lo inet loopback
auto enp1s0iface enp1s0 inet dhcp
auto ens1iface ens1 inet dhcpApply configuration:
Ubuntu:
sudo netplan applyDebian:
sudo systemctl restart networkingVerify network configuration:
ip addr showip route show6.5. Remove Bridged Network Interface
Section titled “6.5. Remove Bridged Network Interface”Remove the original bridged interface (enp1s0).
On the VM:
Identify MAC address of interface to remove:
ip link show enp1s0Example output:
2: enp1s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000 link/ether 52:54:00:83:3c:a0 brd ff:ff:ff:ff:ff:ffMAC Address: 52:54:00:83:3c:a0
On the Host:
Detach interface using MAC address:
virsh detach-interface vmtest \ bridge \ --mac 52:54:00:f7:6d:66 \ --configParameters:
bridge: Network type--mac: MAC address of interface to remove--config: Persistent after shutdown/start
For immediate removal (if VM is running):
virsh detach-interface vmtest \ bridge \ --mac 52:54:00:83:3c:a0 \ --live \ --configShutdown and start VM (not reboot) to complete removal:
virsh destroy vmtestvirsh start vmtest