This is the multi-page printable view of this section. Click here to print.

Return to the regular view of this page.

Client Usage

After server installation and server configuration, you can use the Web UI or run Nebula on devices:

  • ncclient – Preferred method: device client for installation and usage (Docker, CLI, Windows Tray). Enroll once, then ncclient polls for config and certs and can run Nebula.
  • nebula – Manual alternative: create networks and nodes in the UI, then deploy config and certs yourself and run Nebula manually (e.g. when ncclient is not available, such as on mobile).

All of these assume the backend is running and reachable at the URL you configure.

1 - ncclient

ncclient is the preferred way to run Nebula Commander on devices: enroll once with a code from the UI, then ncclient polls for config and certificates and can run or restart Nebula when config changes. When you run the first lighthouse using the Docker client, you can use Magic DNS (split-horizon DNS) for the network.

  • Installation – Docker (preferred for first lighthouse), binaries (Web UI or GitHub Releases), Windows Tray (MSI), or Pip (PyPI) as fallback.
  • Usage – Command line (enrollment, daemon, service) and Windows Tray.

Both the CLI and the Windows tray assume the Nebula Commander backend is running and reachable at the URL you configure.

1.1 - ncclient Installation

You can install ncclient in several ways: Docker (preferred for the first lighthouse to use Magic DNS), binaries (Web UI or GitHub Releases), Windows MSI (CLI and tray app), or Pip (PyPI) as a fallback when Docker or binaries are not suitable.

Docker

The Docker client is the preferred method for the first lighthouse in a network so the container can run dnsmasq and you can use Magic DNS (split-horizon DNS) for the network. Other devices (CLI, tray, or additional Docker clients) can then resolve Nebula hostnames via the lighthouse.

Image: ghcr.io/nixrtr/nebula-commander-ncclient:latest, or build from the repo client/docker (Dockerfile in that directory).

Required environment:

  • NEBULA_COMMANDER_SERVER – Base URL of your Nebula Commander backend (e.g. https://nc.example.com), no trailing slash.

Optional environment:

  • ENROLL_CODE – One-time enrollment code from the Nebula Commander UI (Nodes → Enroll for the node). Only used when the token file does not exist; after enrollment the token is stored and this is ignored.
  • SERVE_DNS – Set to "true" to run dnsmasq on this node when it is a lighthouse, so the network can use Magic DNS. Omit or set to false if this node is not a lighthouse or you do not need DNS.
  • NEBULA_DNS_POLL_INTERVAL – Seconds between dnsmasq config polls when this node is a lighthouse (default: 60).
  • NEBULA_OUTPUT_DIR – Directory where ncclient writes Nebula config and certs inside the container (default: /data/nebula).
  • NEBULA_DEVICE_TOKEN_FILE – Path to the device token file (default: /data/nebula-commander/token).

Use a persistent volume for /data so the token and Nebula config/certs survive restarts. The compose file uses network_mode: host so Nebula and dnsmasq can bind to the host.

Example (docker-compose):

services:
  ncclient:
    image: ghcr.io/nixrtr/nebula-commander-ncclient:latest
    network_mode: host
    restart: unless-stopped
    environment:
      NEBULA_COMMANDER_SERVER: "https://nc.example.com"
      ENROLL_CODE: "XXXXXXXX"   # one-time, from UI
      SERVE_DNS: "true"         # for first lighthouse + Magic DNS
    volumes:
      - ncclient-data:/data

volumes:
  ncclient-data:
    driver: local

Steps:

  1. In Nebula Commander, create a network and add a node for this device. Mark it as a lighthouse if this will be the first lighthouse and you want Magic DNS.
  2. Create or sign a certificate for the node, then click Enroll and copy the one-time code.
  3. Set NEBULA_COMMANDER_SERVER and ENROLL_CODE (and SERVE_DNS: "true" for the first lighthouse), then start the container.
  4. After enrollment, the container fetches config and certs and runs Nebula (and dnsmasq if SERVE_DNS is set and the node is a lighthouse).

Binaries

If Docker is not an option, use binaries from the Web UI or GitHub Releases.

From Web UI

When your Nebula Commander instance is deployed with client binaries included (for example the frontend image built with DOWNLOAD_BINARIES=1), the Web UI can serve them.

  1. Open your Nebula Commander URL in a browser and log in.
  2. Go to the downloads or client section (or open https://YOUR_SERVER/downloads/ if your instance serves that path).
  3. Download the binary for your platform:
    • Linux x86_64: ncclient-linux-amd64
    • Linux ARM64: ncclient-linux-arm64
    • Windows x86_64: ncclient-windows-amd64.exe
    • macOS Intel: ncclient-macos-amd64
    • macOS Apple Silicon: ncclient-macos-arm64
  4. Place the file in a directory on your PATH (or add that directory to PATH). On Linux and macOS, make it executable: chmod +x ncclient-linux-amd64 (or the file you downloaded).

If your instance does not serve binaries, use From releases or Pip (PyPI) instead.

From releases

Pre-built binaries are attached to GitHub Releases for each version.

  1. Open the releases page and choose a version (e.g. the latest).
  2. Download the file for your platform (same names as in From Web UI).
  3. Optionally verify with SHA256SUMS.txt in the same release.
  4. Place the binary in a directory on your PATH (or add that directory to PATH). On Linux and macOS, make it executable: chmod +x ncclient-linux-amd64 (or the file you downloaded).

Windows Installer

On Windows the MSI installer sets up the ncclient CLI, an unelevated tray control UI, and a background Windows Service that does the actual work as LocalSystem - no UAC prompts for enrolling, starting/stopping, or applying split-horizon DNS.

What the installer includes:

  • ncclient – CLI for enrollment and daemon (poll for config/certs, run or restart Nebula).
  • ncclient-tray – Unelevated system tray control UI: enroll, settings, and start/stop/restart the background service.
  • ncclient-service – The NebulaCommanderService Windows Service that polls for config/certs and runs Nebula as LocalSystem. Starts automatically at boot; the tray talks to it over a local named pipe.

All three are installed to %ProgramFiles%\Nebula Commander\. The installer can add that directory to PATH, creates Start Menu shortcuts, and registers/starts the service.

Getting the installer:

  • Download NebulaCommander-windows-amd64.msi from the GitHub Releases page for the version you want.
  • Use SHA256SUMS.txt in the same release to verify the file.

After install:

  1. Open the tray app from the Start Menu and use Enroll: paste the server URL and the one-time code from Nebula Commander (Nodes → open the node → Enroll). This is the recommended way to enroll after an MSI install - it writes the token where the service reads it (%ProgramData%\nebula-commander\) and immediately notifies the service to fetch config. (The CLI’s ncclient enroll writes to a separate per-user location the service does not read from, so avoid it for MSI installs unless you’ve explicitly redirected NEBULA_COMMANDER_CONFIG_DIR.)
  2. The service starts polling automatically once enrolled - nothing else to run. Use the tray’s Start/Stop/Restart Service menu to control it, and Settings to change server URL, poll interval, or enable split-horizon DNS. See Windows Tray in Usage for details.

For building the MSI yourself, see Development: Manual builds.

Pip (PyPI)

Fallback method when Docker or binaries are not suitable (e.g. no Docker, or you need to run from source).

From PyPI:

pip install nebula-commander

Requires Python 3.10+. This installs the ncclient command.

From source (repo clone):

cd nebula-commander
pip install -r client/requirements.txt

Then run as python -m client --server URL enroll --code XXX, or install the client in development mode to get the ncclient command:

cd client
pip install -e .

1.2 - ncclient Usage

After installing ncclient, enroll the device once, then run the daemon (or install the service on Linux).

Command Line

Enrollment

Enrollment is one-time per device. It stores a device token that ncclient uses to fetch config and certificates.

  1. In Nebula Commander, open Nodes, select the node for this device, and click Enroll.
  2. Copy the enrollment code.
  3. On the device, run:
ncclient enroll --server https://YOUR_NEBULA_COMMANDER_URL --code XXXXXXXX

The device token is saved to ~/.config/nebula-commander/token (or /etc/nebula-commander/token when run as root). On Windows, the token is stored under %USERPROFILE%\.config\nebula-commander\token.

Run (daemon)

After enrollment, run ncclient so it periodically pulls config and certificates and optionally runs or restarts Nebula:

ncclient run --server https://YOUR_NEBULA_COMMANDER_URL

Defaults: poll every 60 seconds, write files to /etc/nebula (or ~/.nebula on Windows), and start or restart Nebula from PATH when config changes.

Options

OptionDescription
--output-dir DIRWhere to write config.yaml, ca.crt, host.crt (default: /etc/nebula on Linux/macOS, ~/.nebula on Windows)
--interval NPoll interval in seconds (default: 60)
--token-file PATHPath to device token file
--nebula PATHPath to the nebula binary if it is not on PATH
--restart-service NAMEInstead of running nebula directly, restart this systemd service (e.g. nebula). Use only one of --nebula or --restart-service.
--accept-dnsEnable split-horizon DNS: fetch DNS config from the server and apply it so the Nebula domain is resolved via the network’s DNS (lighthouses). On Linux use systemd-resolved, dnsmasq, or similar (run as root); on Windows uses NRPT (run as Administrator). See Split-horizon DNS below.

Example with nebula in a non-standard location:

ncclient run --server https://nc.example.com --nebula /usr/local/bin/nebula

Example using systemd to run Nebula (ncclient only restarts the service):

ncclient run --server https://nc.example.com --restart-service nebula

Linux: Creating the Nebula TUN device requires root. Run ncclient as root, e.g. sudo ncclient run --server https://....

Split-horizon DNS

When the server has DNS enabled for the network, you can pass --accept-dns so ncclient fetches the DNS config (domain and lighthouse IPs) and configures the host to resolve the Nebula domain via the network’s DNS. On Linux the client tries, in order: systemd-resolved, dnsmasq, NetworkManager, systemd-networkd, then /etc/resolv.conf (best-effort). On Windows it uses NRPT. Run as root (Linux) or Administrator (Windows) to apply. To remove the DNS override on exit, stop ncclient normally (e.g. Ctrl+C); the client clears the rules on exit.

Certificates: If the cert was created via the server (Create certificate in the UI), the bundle includes host.key. If it was signed (Sign flow), the server does not have the key; put your host.key in the same directory as the generated certs (the output dir).

Install service

Linux (quick install)

On Linux you can install a systemd service with one command:

sudo ncclient install

This checks for an existing token at /etc/nebula-commander/token. If missing, it prints the exact ncclient enroll ... command to run first. It then prompts for server URL and options (output dir, interval, nebula path, restart-service), writes /etc/default/ncclient and /etc/systemd/system/ncclient.service, and enables (and optionally starts) the service.

  • Use --no-start to enable without starting.
  • Use --non-interactive with NEBULA_COMMANDER_SERVER (and optional env vars) set for scripting.

Other platforms

Run ncclient run under your init system (launchd on macOS, Task Scheduler or NSSM on Windows). Example configs are in the repo under examples/; see examples/README-startup.md for step-by-step setup on macOS and Windows.

Troubleshooting

  • No TUN device / cannot ping Nebula IP – On Linux, run with sudo. For Sign flow, ensure host.key is in the output directory. Check Nebula’s error output (e.g. “failed to get tun device”, “no such file”).
  • Nebula starts then exits – Often missing host.key (Sign flow), wrong config path, or on Linux needing root. Check the Nebula lines ncclient prints.

macOS notes

Token: ~/.config/nebula-commander/token (or /etc/nebula-commander/token as root). Default output dir: /etc/nebula; for non-root use --output-dir ~/.nebula. Nebula: use PATH or --nebula /opt/homebrew/bin/nebula (Apple Silicon) or /usr/local/bin/nebula (Intel). Do not use --restart-service; use launchd for background runs.

Windows notes (CLI)

Token: %USERPROFILE%\.config\nebula-commander\token. Default output dir: %USERPROFILE%\.nebula. Use --nebula if nebula.exe is not on PATH. Do not use --restart-service. This plain-CLI token/output location is separate from the shared, service-managed location the tray/service use below - for a GUI and no manual daemon management, use the Windows Tray section below instead.

Windows Tray

On Windows, the tray app is an unelevated control UI for a background Windows Service (NebulaCommanderService). The service does the actual work - polling for config/certs and running Nebula - as LocalSystem, so there is no UAC prompt at any point: not to launch the tray, not to enroll, not to start/stop/restart the daemon, and not to apply split-horizon DNS.

The tray and service are installed together by the MSI installer. The tray is not designed to run standalone without it - the service is only ever registered by the MSI (there is no CLI install/remove subcommand for it), so a standalone tray with no service installed has nothing to control and shows as unreachable.

Usage

  • Enroll – Open the tray menu and use Enroll. Enter the server URL and the one-time code from Nebula Commander (Nodes → Enroll for the node). This writes the device token (DPAPI-encrypted, machine-scope) and settings to the shared %ProgramData%\nebula-commander\ folder the service reads from, then tells the service (over a local named pipe) to poll immediately instead of waiting for the next interval.
  • Settings – Configure server URL, poll interval, optional path to the Nebula binary, and Accept split-horizon DNS. There is no output-directory field - Nebula’s config, certs, and logs always live under %ProgramData%\nebula-commander\. When the app is built with bundled Nebula, the default Nebula path points to the bundled nebula.exe.
  • Start / Stop / Restart Service – Controls the real Windows Service via the Service Control Manager (not an in-process loop). The installer grants Authenticated Users the rights to do this, so it works with no admin prompt.
  • Run On Startup – Optional: registers the tray itself (the UI) in the Windows Registry (HKCU\...\Run) so the icon appears when you sign in. This only affects the tray UI - the service already starts automatically at boot (Start="auto", LocalSystem) regardless of whether anyone is logged in.

Settings are stored in %ProgramData%\nebula-commander\settings.json - shared between the tray and the service, not the per-user %APPDATA% location older versions used.

Run from source

From the nebula-commander repo root:

pip install -r client/windows/requirements.txt
pip install -e client/
python -m client.windows.tray

Or with pythonw to avoid a console window:

pythonw -m client.windows.tray

Running this way still expects a real installed-and-running NebulaCommanderService to control - it won’t do anything useful on a machine without one.

Build (PyInstaller)

To build the standalone tray and service executables (and optionally bundle the Nebula Windows binary):

cd client/windows
pip install -r requirements.txt pyinstaller
python build.py

By default build.py builds both ncclient-tray.exe and ncclient-service.exe (--target both); pass --target tray or --target service to build just one. Output is in client/windows/dist/. See client/windows/README.md and build.py for details.

The Windows MSI installer installs and registers all three: ncclient.exe, ncclient-tray.exe, and ncclient-service.exe.

2 - Running Nebula manually

This is the manual method: you use Nebula Commander to create networks, nodes, and certificates, then run Nebula on devices yourself without ncclient. Config and certs are copied or downloaded from the UI (or API) and you start Nebula manually. Use this when you prefer to deploy config and certs yourself or when ncclient is not available (e.g. on mobile).

When to use this

  • You prefer to deploy config and certs yourself (copy to the device, run nebula -config ...).
  • You do not want to enroll devices or run the ncclient daemon.
  • You are fine updating config and certs manually when the network or node changes (re-download from the UI or API and replace files, then restart Nebula).

With ncclient, the device enrolls once and ncclient polls for config and certs and can run or restart Nebula automatically. With manual setup, you handle file deployment and restarts yourself.

Steps

1. Create network and node in Nebula Commander

In the Web UI: create a network, add a node for this device, and create or sign a certificate for the node.

  • Create certificate – The server generates the key and cert; you can download a bundle that includes host.key, host.crt, ca.crt, and config.
  • Sign certificate – You generate the key on the device; the server signs the cert. You will need to place your own host.key next to the downloaded certs.

2. Get config and certs onto the device

Download or copy from the UI (or use the API) the node’s config and certificate files. You typically need:

  • config.yaml (Nebula config for this node)
  • ca.crt (CA certificate)
  • host.crt (host certificate for this node)
  • host.key (only if you used Create certificate; with Sign, you already have this on the device)

Where to get them depends on your Nebula Commander version: use the node’s detail or download actions in the UI, or the device/config API. Place the files in a directory on the device (e.g. /etc/nebula or ~/.nebula).

3. Install and run Nebula on the device

Install Nebula from slackhq/nebula (packages, binary release, or build from source). Then run:

nebula -config /path/to/config.yaml

Use the path to the config.yaml you deployed. Nebula will read ca.crt, host.crt, and host.key from the paths specified in the config (often the same directory as the config).

4. Run Nebula at startup (optional)

Use your platform’s init system so Nebula keeps running: systemd on Linux, launchd on macOS, or a Windows service/task. When you change config or certs (after re-downloading from Nebula Commander), replace the files and restart Nebula.

Mobile devices

The official Nebula client from defined.net (Nebula app) is the only way to run Nebula on a mobile device for now. ncclient is not available on mobile. Use the defined.net app and deploy config and certs manually: create the node and certificate in Nebula Commander, download or copy the config and cert files (e.g. from the Web UI or API), then import or place them in the app as the defined.net client expects.

Summary

ncclientManual (nebula)
EnrollmentOne-time; device gets a tokenNone
Config/certsFetched automatically by ncclientYou copy or download and place them
Nebula processncclient can run or restart itYou run and restart Nebula yourself
Updatesncclient polls and updates filesYou re-download and replace files, then restart Nebula