2-2: LAB | A Lighthouse Network
Lab Overview
Lab Mechanics
Under the hood, this lab is a bit trickier than the last one. I wanted to make clear what’s going on for transparency and to avoid confusion.
The files discussed here are all in the labs/2-2 directory in the course repo.
First, you’ll notice a up.sh shell script. This is a helper script used by just to coordinate the building of Podman images necessary for the lab. The script also kicks off a second script, setup.sh, inside of each container that it runs with podman compose up.
That script, located in labs/2-2/peer/ automates the Wireguard key generation we performed manually last time. So when the containers pop up, you’ll find pre-filled keypairs in the Wireguard config files.
You’ll also notice a lighthouse directory in labs/2-2. The lighthouse container is slightly different from a regular Peer, and this folder contains the modified config we need. It will build a container image called wg-lighthouse:2-2 to go along with wg-peer:2-2.
Network Design
Take a moment to review the podman-compose.yml file in labs/2-2. Even if you’re not familiar with compose files (wanna be?), you should be able to suss out what’s going on broadly. We have 3 “services” we’re standing up: a “home” Peer, a “roaming” Peer, and the Lighthouse. Note that each has a networks section, with both a named network and a specific IP address.
Note
For simplicity’s sake, we’re reducing the non-home networks to a single “roaming” subnet. In reality, the local IP of the roaming device would be a private address, much like the home one. But the separation from the home device is the real purpose of this lab, so we’ll accept one fewer network.
You might also notice that in the Lighthouse service, there is a unique sysctls entry. This is how we enable IP forwarding for the Lighthouse, enabling the routing of all Wireguard traffic through the Lighthouse.
Running The Lab
Bring the lab up same as last time with:
just up 2-2
Once again we’re looking at a Zellij session, but this time there are two separate tabs:

The tabs are clickable, but you can also use Ctrl+t to navigate between them. Note the bottom of the Zellij window for instructions.
In the lab_2-2 tab you’ll see three panes, each with a separate container. The large one on the left is the Lighthouse Peer. Top right is the “home” Peer, and bottom right is the “roaming” Peer.
Lighthouse Configuration
We’ll start with the Lighthouse. Using the text editor of your choice, open the config file at /etc/wireguard/lab_2-2.conf. You’ll notice that the [Interface] section has already been populated with a keypair. It has not yet been populated with a Wireguard address. If you’re following the same pattern we used in the last lab, make this 172.16.100.1/24.
Note
Why not pre-fill this in? Mostly to get you the muscle memory of making this setting manually. In later labs, this is automated for efficiency.
There is a single [Peer] placeholder that’s waiting for a public key and an address. We’ll need two such entries for our home and roaming devices. Let’s head over to home and roaming and fill out those configs—but before we leave the Lighthouse, make sure to copy the public key. We’ll need it for both other Peers.
Peer Configuration
Just as with the Lighthouse, the keypairs for the home and roaming Peers are pre-populated. The addresses are not. Following our pattern, assign these:
- Home:
172.16.100.2/24 - Roaming:
172.16.100.3/24
Now for the [Peer] entries. Both home and roaming need only a single entry, pointing to the Lighthouse’s IP. That would be 10.1.99.10:51820, as the compose file shows.
Note
In reality, the Lighthouse is going to probably have a domain name attached to it. And in fact, the roaming Peer can use
lab_2-2_lighthouseinstead of the IP address because they technically share a network. But DNS in containers is a pain, so we’ll stick to IPs for this lab.
AllowedIPs is going to change a little. Remember that for “clients,” AllowedIPs determines what IPs are routed over the Wireguard tunnel. In our last network, this was a Peer-to-Peer connection with direct addressing for each other Peer. In this case, every Peer is routing Wireguard traffic through the Lighthouse, regardless of specific IP in the network. That means that AllowedIPs is not a /32, but the entire /24 subnet we’re using for Wireguard. More succinctly:
AllowedIPs = 172.16.100.0/24
Because both home and roaming are connecting to the same endpoint, entire Peer entry for the Lighthouse will look identical between them. All together, it will be something like:
[Peer]
PublicKey = ybFybA88hvso4fxo8dWCYXRnKmPw6+sy+YwtqisOgBc=
AllowedIPs = 172.16.100.0/24
# For Peer->Server
Endpoint = lab_2-2_lighthouse:51820
PersistentKeepalive = 25
With your own Lighthouse’s public key, of course.
Adding Peers to the Lighthouse
Almost done! Back on the Lighthouse, we need a [Peer] entry for both home and roaming. Take the respective public keys and fill them in, along with the /32 version of their address.
Here’s what that looks like:
# Home
[Peer]
PublicKey = k7uDnn9nV+NlSzJsVRr4sFf98uyvlpvbFHla5foS4iA=
AllowedIPs = 172.16.100.2/32
# Roaming
[Peer]
PublicKey = 9iC0kFu2y2O7A5kn8XNVXso1zjphNf8pu5hvXnZ7Y38=
AllowedIPs = 172.16.100.3/32
Testing the Connection
Can the roaming host make contact with with the home machine? Let’s try an experiment. We’ll set up a tiny “server” on the home Peer for roaming to reach. On home, run:
echo "Hi" | nc -nvlp 8000
This sets up a netcat connection on port 8000 which will send Hi as the buffer to any incoming connection. Then, on roaming:
nc 172.16.100.2:8000
You should get a greeting on the roaming Peer! Use Ctrl+c to kill the connection. Keep experimenting! When you’re done, click over to the os-shell Zellij tab and run just down 2-2 to shut down the lab.