From 44dff5151d462f4444e5eaf1aefebd977d1ef561 Mon Sep 17 00:00:00 2001 From: Ashley Mensah Date: Tue, 21 Apr 2026 11:14:38 +0200 Subject: [PATCH] Add NetBird VPN setup guide for PiKVM Document the full setup process for running NetBird on PiKVM's read-only filesystem, including overlayfs configuration, systemd service modifications, device registration (setup key and SSO), state persistence, and common troubleshooting steps. --- docs/netbird.md | 304 ++++++++++++++++++++++++++++++++++++++++++++++++ mkdocs.yml | 1 + 2 files changed, 305 insertions(+) create mode 100644 docs/netbird.md diff --git a/docs/netbird.md b/docs/netbird.md new file mode 100644 index 00000000..249f3c3b --- /dev/null +++ b/docs/netbird.md @@ -0,0 +1,304 @@ +--- +title: NetBird VPN +description: How to configure the access to your PiKVM using NetBird VPN +--- + +[NetBird](https://netbird.io/) can be used to access PiKVM from the Internet +if configuring [port forwarding](port_forwarding.md) is not possible or more +security is desired. NetBird is an open-source, self-hostable WireGuard-based mesh +VPN that connects devices peer-to-peer without a central gateway. NetBird also offers a free (for private use) +hosted management service. + +Because PiKVM's root filesystem is read-only, NetBird requires an overlay +filesystem so it can write runtime state without modifying the underlying disk. + +----- + +## Setting up the overlay + +The NetBird client stores its state in `/var/lib/netbird`. On PiKVM this path must be +writable at runtime, so we mount an overlay backed by tmpfs over a persistent +copy of the state. + +1. Switch to read-write mode and ensure the `overlay` kernel module loads on boot: + + ```console + [root@pikvm ~]# rw + [root@pikvm ~]# echo "overlay" > /etc/modules-load.d/overlay.conf + ``` + +2. Create the persistent state directory: + + ```console + [root@pikvm ~]# mkdir -p /root/netbird-state + ``` + +3. Create the helper script. Save as `/usr/local/bin/setup-netbird-overlay.sh`: + + ```bash + #!/bin/bash + set -e + + # Make tmpfs for netbird overlay + mkdir -p /tmp/netbird-tmpfs + mountpoint -q /tmp/netbird-tmpfs || mount -t tmpfs tmpfs /tmp/netbird-tmpfs + + # Prepare overlay dirs + mkdir -p /tmp/netbird-tmpfs/upper + mkdir -p /tmp/netbird-tmpfs/work + mkdir -p /tmp/netbird-merged + + # Mount overlay (lowerdir = persistent readonly state in /root) + mountpoint -q /tmp/netbird-merged || mount -t overlay overlay \ + -o lowerdir=/root/netbird-state,upperdir=/tmp/netbird-tmpfs/upper,workdir=/tmp/netbird-tmpfs/work \ + /tmp/netbird-merged + + # Bind merged to /var/lib/netbird + mountpoint -q /var/lib/netbird && umount /var/lib/netbird || true + mount --bind /tmp/netbird-merged /var/lib/netbird + ``` + + Make it executable: + + ```console + [root@pikvm ~]# chmod +x /usr/local/bin/setup-netbird-overlay.sh + ``` + +4. Create a systemd unit to run the overlay setup before NetBird starts. + Save as `/etc/systemd/system/netbird-overlay.service`: + + ```ini + [Unit] + Description=Setup overlayfs for NetBird + After=local-fs.target tmp.mount + Before=netbird.service + + [Service] + Type=oneshot + ExecStart=/usr/local/bin/setup-netbird-overlay.sh + RemainAfterExit=yes + + [Install] + WantedBy=multi-user.target + ``` + +5. Enable the overlay service: + + ```console + [root@pikvm ~]# systemctl daemon-reload + [root@pikvm ~]# systemctl enable netbird-overlay.service + ``` + +----- + +## Installing NetBird + +1. Install the NetBird client: + + ```console + [root@pikvm ~]# curl -fsSL https://pkgs.netbird.io/install.sh | sh + ``` + +2. Edit the NetBird service file to work with PiKVM's read-only filesystem: + + ```console + [root@pikvm ~]# systemctl edit --full netbird.service + ``` + + The complete file should look like this: + + ```ini + [Unit] + Description=NetBird mesh network client + ConditionFileIsExecutable=/usr/bin/netbird + After=network.target syslog.target netbird-overlay.service + Requires=netbird-overlay.service + + [Service] + StartLimitInterval=5 + StartLimitBurst=10 + ExecStart= + ExecStart=/usr/bin/netbird "service" "run" "--log-level" "info" "--daemon-addr" "unix:///var/run/netbird.sock" "--log-file" "syslog" + + StandardOutput= + StandardOutput=journal + StandardError= + StandardError=journal + + Restart=always + RestartSec=120 + EnvironmentFile=-/etc/sysconfig/netbird + Environment=NB_DISABLE_SSH_CONFIG=true + Environment=SYSTEMD_UNIT=netbird + + [Install] + WantedBy=multi-user.target + ``` + + The key changes from the default service file are: + + * **`After=` and `Requires=`** include `netbird-overlay.service` so the + overlay is mounted before NetBird starts. + * **`ExecStart=`** is cleared then set with `--log-file syslog` instead of + a file path, since `/var/log` is read-only. + * **`StandardOutput=` and `StandardError=`** are cleared then set to + `journal` instead of file paths. + * **`NB_DISABLE_SSH_CONFIG=true`** prevents NetBird from writing SSH + shortcut configuration to `/etc/ssh/ssh_config.d/99-netbird.conf`, + which would fail on the read-only filesystem. This only disables + the convenience of `ssh ` — SSH over NetBird still works + using the peer's IP address directly. + + !!! note + The empty `ExecStart=`, `StandardOutput=`, and `StandardError=` lines + are **not a typo**. In systemd, these directives are list-type settings. + An empty assignment clears the previous value so the next line replaces + it rather than appending to it. + +3. Enable and start the services: + + ```console + [root@pikvm ~]# systemctl daemon-reload + [root@pikvm ~]# systemctl enable netbird.service + [root@pikvm ~]# systemctl start netbird-overlay.service + [root@pikvm ~]# systemctl start netbird.service + ``` + +----- + +## Registering the device + +There are two ways to register your PiKVM with NetBird. The `--disable-dns` +flag is used in both cases to prevent NetBird from trying to write to +`/etc/resolv.conf` on the read-only filesystem. + +### Option 1: Setup key (recommended) + +Setup keys allow registration without any browser interaction, making them +ideal for headless devices like PiKVM. + +1. Log in to the [NetBird dashboard](https://app.netbird.io/) and navigate to + **Setup Keys**. Create a new key. + +2. Register your PiKVM using the setup key: + + ```console + [root@pikvm ~]# netbird up --setup-key --disable-dns + ``` + +### Option 2: Interactive SSO login + +You can also use the standard SSO login flow. PiKVM does not have a browser, +but the activation URL can be opened on any other device. + +1. Start the login flow: + + ```console + [root@pikvm ~]# netbird up --disable-dns + ``` + +2. NetBird will print an activation URL in the terminal, for example: + + ``` + Please do the SSO login in your browser. + If your browser didn't open automatically, use this URL to log in: + + https://login.netbird.io/activate?user_code=XXXX-XXXX + ``` + +3. Copy this URL and open it in a browser on your computer or phone. + Complete the login there. The PiKVM terminal will proceed automatically + once authentication is confirmed. + +### Verifying and persisting + +1. Verify the connection: + + ```console + [root@pikvm ~]# netbird status + ``` + + You should see `Status: Connected` and a NetBird IP address (e.g. `100.x.x.x`). + +2. Persist the authentication state so it survives reboots: + + ```console + [root@pikvm ~]# rw + [root@pikvm ~]# cp -a /tmp/netbird-tmpfs/upper/* /root/netbird-state/ + [root@pikvm ~]# ro + ``` + +3. Reboot to verify everything starts automatically: + + ```console + [root@pikvm ~]# reboot + ``` + +!!! warning "Persist state after configuration changes" + Because the overlay uses tmpfs, any changes NetBird writes at runtime + (authentication tokens, key rotations, etc.) exist only in RAM. After making + configuration changes or re-authenticating, always persist the state: + + ```console + [root@pikvm ~]# rw + [root@pikvm ~]# cp -a /tmp/netbird-tmpfs/upper/* /root/netbird-state/ + [root@pikvm ~]# ro + ``` + +----- + +## Configuring a client device + +* [Download](https://www.netbird.io/download) and install the NetBird client + on the system you are using (not the system you want to control). +* Check the [NetBird dashboard](https://app.netbird.io/) to see your connected peers. +* Open `https://` in your browser to access the PiKVM web interface. + +----- + +## Troubleshooting + +* **Service fails with `status=209/STDOUT`**: The service is trying to write + logs to a file on the read-only filesystem. Make sure you edited the service + file to use `StandardOutput=journal` and `--log-file syslog` as described above. + +* **`mount: special device overlay does not exist`**: The `overlay` kernel module + is not loaded. Verify that `/etc/modules-load.d/overlay.conf` contains `overlay` + and reboot, or load it manually with `modprobe overlay`. + +* **DNS lookup failures (`DeadlineExceeded`)**: If NetBird cannot reach + `api.netbird.io`, check that your PiKVM has working DNS resolution: + + ```console + [root@pikvm ~]# curl -v --max-time 10 https://api.netbird.io:443 + ``` + + If DNS is broken, verify `/etc/resolv.conf` contains a valid nameserver. + A stale NetBird daemon process can also cause this; restart the service: + + ```console + [root@pikvm ~]# systemctl restart netbird + ``` + +* **Need to re-authenticate after reboot**: You forgot to persist the state. + Run `netbird up --setup-key --disable-dns` again, then persist: + + ```console + [root@pikvm ~]# rw + [root@pikvm ~]# cp -a /tmp/netbird-tmpfs/upper/* /root/netbird-state/ + [root@pikvm ~]# ro + ``` + +* If something does not work, the usual advice is to completely remove NetBird + and perform a clean installation: + + ```console + [root@pikvm ~]# rw + [root@pikvm ~]# netbird down + [root@pikvm ~]# systemctl stop netbird + [root@pikvm ~]# systemctl disable netbird netbird-overlay + [root@pikvm ~]# rm -rf /var/lib/netbird /root/netbird-state + [root@pikvm ~]# reboot + ``` + + Now follow the instructions from the beginning to re-install. diff --git a/mkdocs.yml b/mkdocs.yml index da9dec1d..94a5b4c4 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -125,6 +125,7 @@ nav: - "Reverse proxy": reverse_proxy.md - "Tailscale VPN": tailscale.md - "Cloudflare tunnel": cloudflared.md + - "NetBird VPN": netbird.md - "Setting up Wi-Fi": wifi.md - "Setting up 3G/4G/LTE modem": modem.md - "Let's Encrypt certificates": letsencrypt.md