NAT gateway lab: masquerade and port forwarding with nftables in your browser

A networking lab on network address translation: three machines built inside the student’s one Ubuntu VM, a private host on 10.0.0.0/24, a gateway, and an outside server on 203.0.113.0/24. The host cannot reach the server, because the outside has no route back to a private address, and the student has to find out why and fix it on the gateway with nftables.

Nothing to install and no router to buy: each machine is a network namespace, the real commands work, and the outside server answers every request with the address it saw it come from, so a student sees what translation does.

What students learn

Why a private address cannot be used on the internet, and how a gateway speaks for the machines behind it: masquerade, which rewrites the source address of what leaves, and a port forward, which rewrites the destination of what arrives so the outside can reach one service on a private host. They read the gateway’s connection table with conntrack, watch a link with tcpdump, allow the forwarded flow through a firewall that drops everything else without opening it wider, and save the ruleset so it survives a restart.

The topology and the task

A LAN host with a web page on port 80 and a private page on port 8081, a gateway with one cable to each side, and an outside server on port 8000. Today the gateway only lets the LAN start connections and drops the rest. The student makes the LAN host reach the outside server as the gateway’s outside address, then makes the LAN web page reachable from the outside on port 8080, and nothing else. The addresses are in the README the lab leaves in the home folder, which says what to do and gives none of the answers.

Run it in your browser

VM labs are set as a lab task in a module, and the sample is on the lab’s page.

  1. Add the lab. In a module you teach, add a task and choose the Ubuntu VM lab card. The page shows a short description of the machine instead of a compose file.
  2. Start from the sample. The page offers samples to start from. Choose NAT gateway: masquerade and port forwarding. Using a sample replaces the text, and Undo brings yours back.
  3. Publish and start your own copy. Publish, then Start. The lab’s own setup script installs nftables and a few network tools from Ubuntu’s archive and builds the three machines the first time the VM starts, in about ten seconds.
  4. Open the terminal. Open its terminal and read README.md in the home folder: it says what to do and gives none of the answers. netlab status lists the machines and netlab shell gw opens a shell inside the gateway.

A basic lesson on this lab

NAT Basics is a small lesson worked in this lab, which is an Ubuntu VM: each step is explained and has a Run button that types its command into the machine’s terminal and shows what it printed. A student meets the machines, asks the outside server for its page and watches the request time out, reads the outside server’s routes to see it has none for a private address, and reads the gateway’s rules to see there is nothing in them that translates an address.

They look around and leave the lab’s own task, making it work, to the student, so the lesson hands out no answers. A free personal account is given it on the Basics module, which is on Home, every college can copy it from the Library’s Basics folder, and a new college opens with it in a module called Networking Basics (Sample). It is deliberately small: it shows a teacher what a lesson worked in a lab is, and the lab does the rest. Copy it into a module of your own to change it.

How it is marked

The lab has a check. It runs on a copy of the saved machine after a fresh start, so it sees only what the student saved in /etc/nftables.conf, and it marks what the network does and not how the rules are spelt. A request from the LAN host must reach the outside server, which must have seen the gateway’s outside address. A request from the outside to port 8080 must reach the LAN page, which must have seen the client’s own address, so a proxy on the gateway does not pass. The private page and every other port must stay shut, and the gateway must still drop what it was not told to allow. Rules typed into the running gateway and never saved do not pass, and the first line of what the check printed says why.

  1. Hand it out. Assign the lab like any task, with a due date if you want one. Each student gets a VM of their own, kept between sessions.
  2. Run the check. On a student’s row in the class list, press Run the check. It starts a copy of their saved machine that is not saved back, runs the lab’s check script as root and shows whether it passed, what it printed and when. The student is not told the result.
  3. Mark it. Read what the check printed. When a student stops their VM the class list also shows what they changed, the packages they installed and the files they wrote, so you can mark without starting it. Send the work back with a reason if it needs more.

The definition on GitHub

The file is the whole lab definition, the same text the platform runs: size, setup script, topology, README and check. It asks for one CPU and 1 GB. Copy it and change it to make your own.

Questions people ask

Is the outside the real internet?
No. The outside is a network namespace inside the student’s VM, using 203.0.113.0/24, a range set aside for documentation. The VM itself reaches only Ubuntu’s package archive, PyPI, npm and GitHub, so a lab cannot be pointed at a host on the internet.
Can a student use the real Linux commands?
Yes, which is the point. sudo ip netns exec gw nft list ruleset and sudo ip netns exec gw conntrack -L work as written, and netlab shell gw is a shortcut.
What is the difference between masquerade and a port forward?
Masquerade rewrites the source address of what leaves the private network, so the LAN host can reach the outside server. A port forward rewrites the destination of what arrives, so the outside can reach one service on a private host. The lab asks for both, with the forward on port 8080.