Give a guest the right network for its job

applied · 40 min · Objective 1.7

Task

Configure each of the libvirt network types, and prove by experiment which one a guest needs to be a server, which suits a lab, and which isolates a tier that must not reach the outside. The NAT-versus-bridged distinction is the one most often chosen wrongly.

Steps

  1. Put the guest on the default NAT network. From inside, confirm it reaches the internet. From the second LAN machine, confirm you CANNOT reach a service the guest is running. Explain why in one sentence.
  2. Reconfigure the guest onto a bridged network with nmcli on the host to create the bridge, and attach the guest with virsh attach-interface --model virtio. Confirm the guest now gets a LAN address and the second machine can reach its service.
  3. Create an isolated network and move a second guest onto it. Confirm the two guests can reach each other and neither can reach the internet -- correct for a database tier.
  4. Note the --model virtio on the attach: confirm with ethtool -i inside the guest that it is using the paravirtualised driver, not an emulated one.
  5. Break the guest's networking deliberately (bring its interface down from inside) and recover it through virsh console, proving the console works when the network does not.
  6. Summarise the decision in your own words: bridged for servers, NAT for desktops and labs, isolated for tiers that must not reach out.

Verify

# on the second LAN machine, against the guest's service:
# NAT stage -- must fail:
timeout 5 curl -sf http://GUEST_LAN_IP/ >/dev/null 2>&1 && echo "reachable (unexpected on NAT)" || echo "unreachable on NAT, as expected"
# bridged stage -- must succeed:
curl -sf -o /dev/null -w '%{http_code}\n' http://GUEST_LAN_IP/
# inside the isolated guest:
timeout 5 ping -c1 8.8.8.8 >/dev/null 2>&1 && echo "has internet (wrong for isolated)" || echo "isolated, as expected"

The NAT stage failing and the bridged stage succeeding is the whole lesson: a guest on NAT can browse out but nothing can reach in, which is exactly the "the server works locally but nobody can connect" symptom.

Notes

virsh console in step 5 is the one to remember. When a guest has lost its network you cannot SSH to it; the console is a serial link through the hypervisor and works regardless. Put console=ttyS0 in your template so it is there before you need it.