Last active
January 2, 2026 22:36
-
-
Save aldoborrero/6bec43ed0d9550d1f2524b2291e34dc4 to your computer and use it in GitHub Desktop.
PiKVM Netbird
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| set -e | |
| # PiKVM Netbird Setup Script | |
| # Based on: https://docs.netbird.io/how-to/installation/pikvm | |
| # Directories | |
| NETBIRD_STATE_DIR="/root/netbird-state" | |
| NETBIRD_VAR_DIR="/var/lib/netbird" | |
| NETBIRD_TMPFS_DIR="/tmp/netbird-tmpfs" | |
| NETBIRD_MERGED_DIR="/tmp/netbird-merged" | |
| OVERLAY_SCRIPT="/usr/local/bin/setup-netbird-overlay.sh" | |
| OVERLAY_SERVICE="/etc/systemd/system/netbird-overlay.service" | |
| NETBIRD_SERVICE_OVERRIDE_DIR="/etc/systemd/system/netbird.service.d" | |
| RED='\033[0;31m' | |
| GREEN='\033[0;32m' | |
| YELLOW='\033[1;33m' | |
| NC='\033[0m' | |
| info() { echo -e "${GREEN}[INFO]${NC} $1"; } | |
| warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } | |
| error() { echo -e "${RED}[ERROR]${NC} $1"; exit 1; } | |
| # Check if running as root | |
| [[ $EUID -ne 0 ]] && error "This script must be run as root" | |
| # Check if setup key is provided | |
| if [[ -z "$1" ]]; then | |
| echo "Usage: $0 <SETUP-KEY>" | |
| echo "" | |
| echo "Get a setup key from your Netbird admin console." | |
| echo "Recommended: create a key with no expiration for the device." | |
| exit 1 | |
| fi | |
| SETUP_KEY="$1" | |
| info "Making filesystem writable..." | |
| rw | |
| info "Installing Netbird..." | |
| curl -fsSL https://pkgs.netbird.io/install.sh | sh | |
| info "Initial Netbird connection to create config files..." | |
| netbird up -k "$SETUP_KEY" --allow-server-ssh --enable-lazy-connection --no-browser --log-file syslog | |
| info "Stopping Netbird to prepare overlay setup..." | |
| netbird down | |
| systemctl stop netbird | |
| info "Cleaning up state files..." | |
| rm -f "${NETBIRD_VAR_DIR}/state.json" | |
| rm -f "${NETBIRD_VAR_DIR}"/*.log | |
| rm -f "${NETBIRD_VAR_DIR}/resolv.conf" | |
| # Keep only essential config files | |
| find "${NETBIRD_VAR_DIR}" -type f ! -name 'active_profile.json' ! -name 'default.json' -delete 2>/dev/null || true | |
| info "Copying initial config to persistent location..." | |
| mkdir -p "${NETBIRD_STATE_DIR}" | |
| cp -a "${NETBIRD_VAR_DIR}"/* "${NETBIRD_STATE_DIR}"/ | |
| info "Creating overlay setup script..." | |
| cat > "${OVERLAY_SCRIPT}" << EOF | |
| #!/bin/bash | |
| set -e | |
| # Make tmpfs for netbird overlay | |
| mkdir -p ${NETBIRD_TMPFS_DIR} | |
| mountpoint -q ${NETBIRD_TMPFS_DIR} || mount -t tmpfs tmpfs ${NETBIRD_TMPFS_DIR} | |
| # Prepare overlay dirs | |
| mkdir -p ${NETBIRD_TMPFS_DIR}/upper | |
| mkdir -p ${NETBIRD_TMPFS_DIR}/work | |
| mkdir -p ${NETBIRD_MERGED_DIR} | |
| # Mount overlay (lowerdir = persistent readonly state in /root) | |
| mountpoint -q ${NETBIRD_MERGED_DIR} || mount -t overlay overlay \\ | |
| -o lowerdir=${NETBIRD_STATE_DIR},upperdir=${NETBIRD_TMPFS_DIR}/upper,workdir=${NETBIRD_TMPFS_DIR}/work \\ | |
| ${NETBIRD_MERGED_DIR} | |
| # Bind merged to ${NETBIRD_VAR_DIR} | |
| mountpoint -q ${NETBIRD_VAR_DIR} && umount ${NETBIRD_VAR_DIR} || true | |
| mount --bind ${NETBIRD_MERGED_DIR} ${NETBIRD_VAR_DIR} | |
| EOF | |
| chmod +x "${OVERLAY_SCRIPT}" | |
| info "Creating overlay systemd service..." | |
| cat > "${OVERLAY_SERVICE}" << EOF | |
| [Unit] | |
| Description=Setup overlayfs for netbird | |
| After=local-fs.target tmp.mount | |
| Before=netbird.service | |
| [Service] | |
| Type=oneshot | |
| ExecStart=${OVERLAY_SCRIPT} | |
| RemainAfterExit=yes | |
| [Install] | |
| WantedBy=multi-user.target | |
| EOF | |
| info "Creating netbird service override..." | |
| mkdir -p "${NETBIRD_SERVICE_OVERRIDE_DIR}" | |
| cat > "${NETBIRD_SERVICE_OVERRIDE_DIR}/override.conf" << 'EOF' | |
| [Unit] | |
| After=network.target syslog.target netbird-overlay.service | |
| [Service] | |
| ExecStart= | |
| ExecStart=/usr/bin/netbird service run --log-level info --daemon-addr unix:///var/run/netbird.sock --log-file syslog | |
| StandardOutput=journal | |
| StandardError=journal | |
| EOF | |
| info "Enabling services..." | |
| systemctl daemon-reload | |
| systemctl enable netbird-overlay.service | |
| systemctl enable netbird | |
| info "Enabling systemd-resolved for DNS support..." | |
| systemctl enable --now systemd-resolved || true | |
| # Remove openresolv if present (conflicts with netbird DNS) | |
| if pacman -Qi openresolv &>/dev/null; then | |
| warn "Removing openresolv (conflicts with Netbird DNS)..." | |
| pacman -R --noconfirm openresolv || true | |
| fi | |
| info "Making filesystem read-only..." | |
| ro | |
| echo "" | |
| info "Setup complete!" | |
| echo "" | |
| echo "To verify, run:" | |
| echo " sudo systemctl start netbird-overlay.service" | |
| echo " sudo systemctl start netbird" | |
| echo " netbird status -d" | |
| echo "" | |
| echo "Or simply reboot:" | |
| echo " reboot" | |
| echo "" | |
| warn "Note: Config changes won't persist across reboots." | |
| warn "Edit ${NETBIRD_STATE_DIR}/ directly for persistent changes." |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment