Chapter 1: Build Your Practice Lab

What you are building

Every exercise in this path needs somewhere safe to run, and somewhere you can break and repair without fear. This chapter builds it on one Ubuntu machine at home: a workstation you work from and two servers, servera and serverb, on lab.example.com. All three are Rocky Linux 9 virtual machines on a private network that nothing outside can connect into.

One lab, two sizes

This site has two learning paths that share one practice lab design. The Ansible path needs more: two extra servers, an automation account on every machine and the Ansible tools. This path needs only the core of it, so this chapter builds a lighter version. Both versions use the same network, names, addresses and passwords, and the same lab commands: lab start, lab grade and lab finish on workstation, and rht-vmctl on the host.

You don't need this setup. The Ansible lab is a complete superset of this one, and every exercise in this path runs on it unchanged.

  1. Add the few everyday tools this path uses, with Repair an existing lab.
  2. Update the lab commands: lab update on workstation, and install the current rht-vmctl.
  3. Run the check in section 1.7, then retake the clean snapshot.

The lighter lab can't be grown into the Ansible lab in place: its machines were built without the account Ansible connects as, and that is set when a machine is first created.

When you get there, tear this lab down and build the Ansible lab in its place. It runs everything in this path too, so you only ever need one lab at a time.

The idea in one picture

Three VMs sit on a private network called rhcebr0. Inside that network they talk to each other freely, and they can reach the internet, so dnf install works. From outside, nobody can open a connection in: not your laptop, not your router, and not even the host itself. You step inside with lxc exec (which does not use the network at all), then SSH between the VMs as you would between real servers.

Pick a traffic flow to see its path and the firewall rule that decides it:

The address plan

The lab uses the network 172.25.250.0/24 and the domain lab.example.com, so every hostname and IP address in this path works unchanged.

NameIPvCPU / RAMExtra diskRole
(rhcebr0 gateway)172.25.250.254——Lives on the host. Routes the lab to the internet; runs DHCP and DNS.
workstation172.25.250.92 / 2 GiB—The machine you work from. The lab command runs here.
servera172.25.250.101 / 1 GiB5 GiBServer you administer
serverb172.25.250.111 / 1 GiB5 GiBServer you administer

The extra disks stay empty until the storage chapters, where you partition them, build logical volumes on them and share them between the two servers.

Accounts on every VM

UserPasswordPurpose
studentstudentYour everyday login. sudo with a password.
rootredhatThe administrator account

The users and groups chapter has you create more accounts of your own. In section 1.6 you also give student on workstation an SSH key that logs in to the servers as student and as root: the lab grade command uses it to check your work.

Where each step happens

Every step in this chapter is labelled with where you run it:

A terminal on the Ubuntu host.

The LXD web interface in your browser.

Inside a lab VM, usually as student on workstation.

Your lab values

A few values differ on every home network. The instructions write them as placeholders, highlighted in amber: <HOST_LAN_IP>, <HOST_USER> and <ROUTER_IP>. Enter yours once here and every command in this path shows (and copies) your real values instead:

PlaceholderMeaningHow to find it
<HOST_LAN_IP>The Ubuntu host's address on your local networkhostname -I on the host
<HOST_USER>Your login name on the Ubuntu hostwhoami on the host
<ROUTER_IP>Your local network's default gatewayip route | grep default

Everything else, including the 172.25.250.0/24 network, the hostnames and the student password, is the same for everyone.

Why the host has two IP addresses

Your Ubuntu host keeps its normal address on your local network, <HOST_LAN_IP>. When you create the lab network, LXD builds a virtual switch called rhcebr0 inside the host and gives the host a second address on it: 172.25.250.254. That second address is the lab's gateway.

Why the host has two IP addresses: The host keeps its normal LAN address (wired or Wi-Fi) and gains a second one, 172.25.250.254, on the lab's virtual switch. The VMs use that second address as their gateway.

The gateway can't be removed: without it the VMs would get no addresses (DHCP), couldn't find each other by name (DNS), and couldn't install packages. What you can do, and what the seal does, is make it one-way: traffic may leave the lab, but nothing, including the host, may start a connection into it.

Host interfaceAddressFaces
Your ethernet / Wi-Fi card<HOST_LAN_IP>Your local network and the internet. Unchanged.
rhcebr0 (virtual, created by LXD)172.25.250.254The lab VMs only. Gateway, DHCP and DNS.

What you need

MinimumRecommendedTested on
Operating systemUbuntu Server LTS, x86_64, with snap supportUbuntu Server 26.04.1 LTS
CPU2 cores / 4 threads with Intel VT-x or AMD-V4 coresIntel Core i5-7500, 4 cores / 4 threads, 3.4 GHz
Memory8 GB16 GB32 GB (30 GiB usable)
Free disk30 GB60 GB or more (SSD)200 GiB ZFS pool on a loop file
NetworkA fixed address on your LAN and internet accessWiredWi-Fi (USB adapter) on a /16 home LAN. The lab is routed with NAT, not bridged, so Wi-Fi works.

Tested versions

Newer patch releases should behave the same. If something differs, compare against this table first.

LayerComponentVersionHow it's pinned
HostUbuntu Server26.04.1 LTS, kernel 7.0.0-34-generic—
LXD (snap)5.21.8 LTS, rev 40958--channel=5.21/stable + snap refresh --hold
nftablesUbuntu 26.04 package—
Guest imageimages:rockylinux/9/cloudbuild 20260929_0805Optional local copy: rocky9-lab
Rocky Linux9.8 (Blue Onyx)—
All VMsSELinuxEnforcing, selinux-policy 38.1.75Added by the profile; the image ships without it
firewalld, chronyRunningAdded by the profile, as on a RHEL server

The build at a glance