nebula's built-in Go service manager (-service install) is unreliable on Windows — it reports "service already exists" when the SCM, registry, and Get-Service all confirm no service is present. Use PowerShell's New-Service cmdlet instead, which talks directly to the Windows SCM.
8.6 KiB
Nebula Domain Bootstrap
Onboards a Windows machine to the Nebula mesh network and joins it to an Active Directory domain. Designed to be run once by a local Administrator on a fresh Windows install.
Nebula version: 1.10.3 (downloaded from GitHub at install time)
For domain controller setup requirements, see DC-SETUP.md.
Prerequisites
The domain administrator prepares a deployment package containing:
ca.crt— Nebula CA certificate (ships with the scripts)bootstrap.json— Deployment config with DNS server and domain name (ships with the scripts)config.yml— Nebula configuration (use forward slashes in all paths)host.crt— Nebula certificate signed by the CAhost.key— Nebula private key
The per-host files (config.yml, host.crt, host.key) are unique to each machine and should be placed in a directory you will run the scripts from.
Package Contents
| File | Purpose |
|---|---|
bootstrap.ps1 |
Runs all three steps in sequence |
install-nebula.ps1 |
Downloads Nebula and installs it as a Windows service |
set-dns.ps1 |
Points the Nebula adapter's DNS at the domain controller |
join-domain.ps1 |
Joins the machine to the domain |
ca.crt |
Nebula CA certificate (provided by admin) |
bootstrap.json |
Deployment config: DNS server IP and domain name (provided by admin) |
Usage
All scripts require an Administrator PowerShell session. If script execution is blocked, run this first:
Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope Process
One-shot bootstrap
From the directory containing your per-host files (config.yml, host.crt, host.key):
& "C:\path\to\nebula\bootstrap.ps1"
Optionally pass -ComputerName to validate the machine name matches a pre-staged AD object:
& "C:\path\to\nebula\bootstrap.ps1" -ComputerName "WS-NAME"
DNS server and domain are read from bootstrap.json in the script directory. This runs all three steps in order, prompts for domain credentials, and offers to restart when finished.
Step-by-step
If you need to run steps individually:
# 1. Install Nebula
& "C:\path\to\nebula\install-nebula.ps1" -DnsServer 10.10.10.13 -Domain "arvandor.internal"
# 2. Point DNS at the domain controller (for the current session)
& "C:\path\to\nebula\set-dns.ps1" -DnsServer 10.10.10.13
# 3. Join domain
& "C:\path\to\nebula\join-domain.ps1" -Domain "arvandor.internal"
Parameters
bootstrap.ps1
-ComputerName(optional) — Expected NetBIOS name (max 15 characters). Warns if the current machine name doesn't match.- Reads
DnsServerandDomainfrombootstrap.json.
bootstrap.json
{
"DnsServer": "10.10.10.13",
"Domain": "arvandor.internal"
}
install-nebula.ps1 (standalone use)
-DnsServer(required) — IP address of the domain controller. Used to configure DNS persistence across reboots.-Domain(required) — FQDN of the Active Directory domain. Used to configure Netlogon DC rediscovery at startup.
set-dns.ps1 (standalone use)
-DnsServer(required) — IP address of the domain controller-InterfaceAlias(optional) — Target a specific adapter. Defaults tonebula1
join-domain.ps1 (standalone use)
-Domain(required) — FQDN of the Active Directory domain-ComputerName(optional) — Expected NetBIOS name (max 15 characters). If provided and the current machine name doesn't match, the script warns but proceeds with the join under the current name.
Deployment Flow
- Create a computer object in Active Directory in the appropriate OU
- Sign a Nebula certificate for the machine with the correct group (e.g.,
workstations) - Install Windows on the target machine
- If using a pre-staged AD object: rename the machine to match and reboot before proceeding
Rename-Computer -NewName "WS-NAME" -Restart - As a local Administrator, run the bootstrap with the per-host files
- Restart — the machine will authenticate against the domain controller over Nebula at the login screen and pull Group Policy
Idempotency
All scripts are safe to re-run:
install-nebula.ps1— Skips reinstall if the service is already running with the correct version, matching files, and theNebulaDNSscheduled task exists. Tears down and rebuilds if the version or files have changed.set-dns.ps1— Overwrites the existing DNS setting on the Nebula adapter.join-domain.ps1— Skips the join if already on the domain.
Architecture
- Nebula provides the encrypted mesh network. It runs as a
LocalSystemservice withautostart, depending onTcpipandNlaSvc(Network Location Awareness). This ensures the physical network is connected before Nebula attempts handshakes. - DNS is configured only on the
nebula1adapter. Physical adapters (Wi-Fi, Ethernet) keep their DHCP-assigned DNS so they can reach the internet and Nebula lighthouses independently. - DNS persistence — Nebula recreates the
nebula1TUN adapter on every start, which wipes DNS settings. ANebulaDNSscheduled task runs at startup to re-apply DNS on the adapter, wait for the domain controller to become reachable, then force Netlogon to rediscover the DC vianltest. This ensures domain authentication works at the Windows login screen before any user logs in. - Domain trust flows through the Nebula tunnel. The domain controller is reachable at its Nebula IP, so machines do not need a VPN or physical proximity to the DC.
Troubleshooting
Scripts won't run
PowerShell execution policy is blocking unsigned scripts. Run Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope Process in the same terminal before retrying. This only affects the current session.
"This script must be run as a machine Administrator"
Right-click PowerShell and select Run as Administrator, or use an elevated terminal.
Nebula service fails to start
Check the Application event log:
Get-WinEvent -FilterHashtable @{LogName='Application'; ProviderName='nebula'} -MaxEvents 10 | Format-List TimeCreated, Message
Common causes:
- "found unknown escape character" — Backslashes in
config.ymlpaths. YAML interprets\as escape characters inside double quotes. Use forward slashes (C:/Program Files/Nebula/ca.crt). - "no config files found" — The service binary path is missing the
-configargument. Reinstall usinginstall-nebula.ps1.
Handshake timeouts after reboot
Nebula started before the physical network was ready. Verify the service is configured with auto start and NLA dependency:
sc qc nebula
Expected: START_TYPE: AUTO_START with DEPENDENCIES: Tcpip, NlaSvc. Re-run install-nebula.ps1 to fix.
DNS resolution fails
Verify DNS is set on the Nebula adapter only:
Get-DnsClientServerAddress -InterfaceAlias "nebula1" -AddressFamily IPv4
If DNS was accidentally set on Wi-Fi/Ethernet, reset it:
Set-DnsClientServerAddress -InterfaceAlias "Wi-Fi" -ResetServerAddresses
Computer name mismatch warning during domain join
The script warns if the machine's current name doesn't match the -ComputerName parameter. If you have a pre-staged AD object, rename the machine and reboot before running bootstrap:
Rename-Computer -NewName "WS-NAME" -Restart
Then re-run bootstrap. The machine will present the correct name to AD and auto-match the pre-staged object.
Cannot reach domain controller at login screen
The Nebula tunnel must be established before Windows attempts domain authentication. Verify:
- Nebula service is running:
sc query nebula - Tunnel is active:
ping 10.10.10.13 - DNS resolves:
nslookup arvandor.internal - NebulaDNS scheduled task exists:
Get-ScheduledTask -TaskName "NebulaDNS" - Startup script exists:
Test-Path "C:\Program Files\Nebula\set-dns-on-start.ps1"
If DNS is not set on nebula1 after a reboot, the scheduled task may have failed. Check its last run result:
Get-ScheduledTaskInfo -TaskName "NebulaDNS" | Select-Object LastRunTime, LastTaskResult
If the service is running but handshakes fail, check that the machine's Nebula certificate group has firewall access to the ad group.
License
This project is licensed under the MIT License. See LICENSE for details.