Setting up a lab network on Linux
- DE
- EN
During my work, I regularly connect to various computers and embedded devices that are accessible via an Ethernet connection. These could now be connected directly - like the development computer - to the company network…
… or you can create your own “lab network” for your devices, which is only accessible from your own laptop and over which you have full control. Advantages can be:
- Overview of the connected devices and their IP addresses.
- No exposure of the connected devices to the company network (improvement of security)
- If only Wifi is available at the development computer, the embedded devices can still be reached easily and wired.
In larger companies, access to the internal company network may also be heavily regulated, so that only unlocked devices can be used at all. With an own small laboratory network on a second network interface, this problem can be elegantly circumvented.
The plan
The laboratory network at the network interface ens37
gets the IPv4 network 10.0.0.1/24
. IP addresses are assigned between 10.0.0.10 and 10.0.0.254. The own development computer is to act in it as router and DNS resolver and has the IP address 10.0.0.1
.
The network parameters on the lab interface are set statically in the network settings:
- IP address: 10.0.0.1
- Netmask: /24 (255.255.255.0)
- Gateway: 10.0.0.1
All occurrences of ens37 are to be replaced by the own name of the used network interface! Often for example:
eth1or
enp85s0` or similar!).
Using Dnsmasq as DHCP and DNS server
The dnsmasq
server is used to provide a DHCP and DNS server in the laboratory network. DNS is needed if an internet connection is to be used via NAT (see last section).
sudo apt install dnsmasq
In the new configuration file /etc/dnsmasq.d/labnet.conf
dnsmasq is configured:
# interface to use
interface=ens37
# DHCP settings
dhcp-authoritative
dhcp-range=10.0.0.100,10.0.0.250,255.255.255.0,12h
dhcp-option=option:router,10.0.0.1
dhcp-option=option:dns-server,10.0.0.1
# Always assign the same IP addresses to these hosts
dhcp-host=10:00:00:00:00:01,10.0.0.100
dhcp-host=10:00:00:00:00:01,10.0.0.101
# Upstream DNS resolver
server=127.0.0.53
# Local TLD
domain=lab
local=/lab/
expand-hosts
# Static DNS hostnames in labnet
address=/mydevice-altname.com/10.0.0.101
interface=ens37
makes the DNS resolver listen only on the network interface ens37
. If you omit the setting, dnsmasq
tries to start a DNS service on the localhost interface as well, which fails on modern Linux distributions, because systemd-resolved
is already running here.
Subsequently, the DHCP range is defined from which IP addresses are to be distributed to devices in the laboratory network (10.0.0.100 - 10.0.0.250
). This guarantees that an IP address remains valid for at least 12 hours.
The dhcp-option
settings are used to tell the terminated devices under which IP addresses the default gateway and DNS resolver are located. In both cases, this is the host that runs dnsmasq.
With dhcp-host
IP addresses for individual network interfaces or devices can be “fixed”. Thus the device with the MAC address 10:00:00:00:0
is always assigned the IP address 10.0.0.101
.
If the devices connected to the laboratory network are to have Internet access (see section “Providing a (temporary) Internet connection”), an upstream DNS server must be specified for the dnsmasq instance. Dnsmasq cannot resolve global domain names such as google.com itself and instead falls back on the DNS server stored here. Here it is set to the IP address of the systemd-resolved service that comes with most modern Linux distributions.
The three following parameters (domain=
etc.) define which top-level domain should be used within the lab network. This is important to be able to tell systemd-resolved later which DNS resolver (namely dnsmasq!) should be used for the lab network.
If you want to manipulate public DNS records or simulate your own virtual ones, you can set one or more address=
parameters. The domain name mentioned in it will then be statically converted to the IP address set behind it (and the upstream DNS server will be bypassed).
The new config file is still activated at the bottom of the /etc/dnsmasq.conf
file by commenting the following line:
conf-dir=/etc/dnsmasq.d/,*.conf
Last but not least, systemd-resolved is told to automatically resolve domain names ending with .lab
using the dnsmasq server instead of another possibly public DNS server (which of course would not know the names in the lab network). For this purpose, a new systemd service file /etc/system/system/resolved-set-dns-ens37.service
is created:
[Unit]
Description=Pper-link DNS configuration for ens37
BindsTo=sys-subsystem-net-devices-ens37.device
After=sys-subsystem-net-devices-ens37.device
[Service]
Type=oneshot
ExecStart=/usr/bin/resolvectl dns ens37 10.0.0.1
ExecStart=/usr/bin/resolvectl domain ens37 ~lab
ExecStopPost=/usr/bin/resolvectl revert ens37
RemainAfterExit=yes
[Install]
WantedBy=sys-subsystem-net-devices-ens37.device
(the tilde character ~ in front of the “lab” is important here, so that the DNS server is only used for the named “lab” top-level domain!).
The new Service is activated by:
sudo systemctl daemon-reload
sudo systemctl enable --now resolved-set-dns-ens37
A
sudo resolvectl status
should show that “DNS Servers” and “DNS Domain” are set:
Link 3 (ens37)
Aktuelle Bereiche: DNS
DefaultRoute-Einstellung: nein
LLMNR-Einstellung: ja
MulticastDNS-Einstellung: nein
DNSOverTLS-Einstellung: nein
DNSSEC-Einstellung: nein
DNSSEC unterstützt: nein
DNS-Server: 10.0.0.1
DNS-Domäne: ~Labor
After restarting dnsmasq
, devices that are only plugged into the lab interface will pull an IP address via DHCP and should be reachable from the development computer. Which IP address a device got can be traced in the dnsmasq
log:
sudo journalctl -u dnsmasq -f
If a device with the hostname mydevice
reports to the DHCP server, it can be pinged using the hostname mydevice.lab
for example, or an SSH session can be opened as follows:
ssh user@mydevice.lab
Providing a (temporary) Internet connection
To allow connected devices to find a way to the Internet for software installations and updates, a source NAT can be set up on the development machine. I use a small script for this:
#!/bin/bash
EXT_IFACE=ens33 # ens33 = interface to public network
INT_IFACE=ens37 # ens37 = interface to lab network
if [[ "$1" == "start" ]]; then
echo "Starting NAT ..."
sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward"
sudo iptables --table nat --append POSTROUTING --out-interface $EXT_IFACE -j MASQUERADE
sudo iptables --append FORWARD --in-interface $INT_IFACE -j ACCEPT
else
echo "Stopping NAT ..."
sudo iptables --table nat --delete POSTROUTING --out-interface $EXT_IFACE -j MASQUERADE
sudo iptables --delete FORWARD --in-interface $INT_IFACE -j ACCEPT
fi
(Important: Adjust interface names ens33
or ens37
via variables EXT_IFACE and INT_IFACE!)
The script is stored under ~/.local/bin/natctl
and made known in the PATH:
~/.bashrc
:
export PATH=$PATH:~/.local/bin
The executable bit on the script is set:
chmod u+x ~/.local/bin/natctl
After a source ~/.bashrc
the natctl
script should be available. With two simple commands the internet connection can then be enabled or disabled:
natctl start
natctl stop
Note: After a reboot, the dnsmasq
server may have to be restarted, since the lab interface may not have had the right IP address for the first startup attempt and this may have failed. If newly connected devices do not get an IP address, it is worthwhile to try a restart via sudo systemctl restart dnsmasq
.
Note 2: The NAT function also does not survive a reboot (on purpose). After booting, the NAT must be re-enabled via natctl start
.