#!/usr/bin/env bash # OPT-IN: create a NetworkManager bridge (br0) that enslaves a physical NIC, so # libvirt/qemu VMs get real LAN IPs (DHCP from your router) instead of NAT. # # Host-specific (NIC name differs per machine) and briefly drops the wired link, # so this is NOT part of run.sh. Run once per machine, locally (not over the # very link you're bridging): # sudo ./kvm-bridge.sh [iface] # iface defaults to the connected ethernet # # For a STATIC bridge IP instead of DHCP, after running this: # nmcli connection modify br0 ipv4.method manual \ # ipv4.addresses 192.168.1.100/24 ipv4.gateway 192.168.1.1 ipv4.dns 8.8.8.8 # nmcli connection up br0 set -euo pipefail [ "$(id -u)" -eq 0 ] || { echo "run as root"; exit 1; } IFACE="${1:-$(nmcli -t -f DEVICE,TYPE,STATE device status \ | awk -F: '$2=="ethernet" && $3=="connected"{print $1; exit}')}" [ -n "$IFACE" ] || { echo "no connected ethernet found — pass the interface name"; exit 1; } echo "Bridging $IFACE into br0 (the wired connection will blip)." # let qemu's bridge helper use br0 install -d /etc/qemu grep -qxF 'allow br0' /etc/qemu/bridge.conf 2>/dev/null || echo 'allow br0' >> /etc/qemu/bridge.conf # bridge + slave (DHCP on the bridge by default); idempotent nmcli connection show br0 >/dev/null 2>&1 \ || nmcli connection add type bridge con-name br0 ifname br0 nmcli connection show "bridge-slave-$IFACE" >/dev/null 2>&1 \ || nmcli connection add type ethernet con-name "bridge-slave-$IFACE" ifname "$IFACE" master br0 nmcli connection up br0 echo "Done. Point VMs at bridge 'br0' (virt-manager: Bridge device → br0)."