Nebula recreates the nebula1 TUN adapter on every start, wiping DNS settings. This caused domain authentication to fail at the Windows login screen because Netlogon could not reach the DC. Changes: - install-nebula.ps1 now takes -DnsServer and -Domain parameters - Changed service start type from delayed-auto to auto - Creates set-dns-on-start.ps1 startup script and NebulaDNS scheduled task - Sets ExpectedDialupDelay=60 in Netlogon registry - Idempotency check verifies scheduled task and startup script exist
174 lines
8.1 KiB
Markdown
174 lines
8.1 KiB
Markdown
# 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](DC-SETUP.md).
|
|
|
|
## Prerequisites
|
|
|
|
Before running, you need the following **per-host files** prepared by the domain administrator:
|
|
|
|
- `config.yml` — Nebula configuration (use forward slashes in all paths)
|
|
- `host.crt` — Nebula certificate signed by the CA
|
|
- `host.key` — Nebula private key
|
|
|
|
These files 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 |
|
|
|
|
## Usage
|
|
|
|
All scripts require an **Administrator PowerShell session**. If script execution is blocked, run this first:
|
|
|
|
```powershell
|
|
Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope Process
|
|
```
|
|
|
|
### One-shot bootstrap
|
|
|
|
From the directory containing your per-host files (`config.yml`, `host.crt`, `host.key`):
|
|
|
|
```powershell
|
|
& "C:\path\to\nebula\bootstrap.ps1" -DnsServer 10.10.10.13 -Domain "arvandor.internal"
|
|
```
|
|
|
|
Optionally pass `-ComputerName` to validate the machine name matches a pre-staged AD object:
|
|
|
|
```powershell
|
|
& "C:\path\to\nebula\bootstrap.ps1" -DnsServer 10.10.10.13 -Domain "arvandor.internal" -ComputerName "WS-NAME"
|
|
```
|
|
|
|
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:
|
|
|
|
```powershell
|
|
# 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
|
|
|
|
**install-nebula.ps1**
|
|
- `-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**
|
|
- `-DnsServer` (required) — IP address of the domain controller
|
|
- `-InterfaceAlias` (optional) — Target a specific adapter. Defaults to `nebula1`
|
|
|
|
**join-domain.ps1**
|
|
- `-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
|
|
|
|
1. Create a computer object in Active Directory in the appropriate OU
|
|
2. Sign a Nebula certificate for the machine with the correct group (e.g., `workstations`)
|
|
3. Install Windows on the target machine
|
|
4. **If using a pre-staged AD object:** rename the machine to match and reboot before proceeding
|
|
```powershell
|
|
Rename-Computer -NewName "WS-NAME" -Restart
|
|
```
|
|
5. As a local Administrator, run the bootstrap with the per-host files
|
|
6. 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 the `NebulaDNS` scheduled 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 `LocalSystem` service with `auto` start, depending on `Tcpip` and `NlaSvc` (Network Location Awareness). This ensures the physical network is connected before Nebula attempts handshakes.
|
|
- **DNS** is configured only on the `nebula1` adapter. 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 `nebula1` TUN adapter on every start, which wipes DNS settings. A `NebulaDNS` scheduled 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 via `nltest`. This ensures domain authentication works at the Windows login screen before any user logs in.
|
|
- **Netlogon tuning** — `ExpectedDialupDelay` (60 seconds) is set in the registry to give Netlogon additional time to locate the DC over the Nebula tunnel, which may involve relay handshakes.
|
|
- **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:
|
|
```powershell
|
|
Get-WinEvent -FilterHashtable @{LogName='Application'; ProviderName='nebula'} -MaxEvents 10 | Format-List TimeCreated, Message
|
|
```
|
|
|
|
Common causes:
|
|
- **"found unknown escape character"** — Backslashes in `config.yml` paths. YAML interprets `\` as escape characters inside double quotes. Use forward slashes (`C:/Program Files/Nebula/ca.crt`).
|
|
- **"no config files found"** — The service was installed without `-config`. Reinstall using `install-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:
|
|
```powershell
|
|
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:
|
|
```powershell
|
|
Get-DnsClientServerAddress -InterfaceAlias "nebula1" -AddressFamily IPv4
|
|
```
|
|
If DNS was accidentally set on Wi-Fi/Ethernet, reset it:
|
|
```powershell
|
|
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:
|
|
```powershell
|
|
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:
|
|
1. Nebula service is running: `sc query nebula`
|
|
2. Tunnel is active: `ping 10.10.10.13`
|
|
3. DNS resolves: `nslookup arvandor.internal`
|
|
4. NebulaDNS scheduled task exists: `Get-ScheduledTask -TaskName "NebulaDNS"`
|
|
5. 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:
|
|
```powershell
|
|
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](LICENSE) for details.
|
|
|
|
### Third-party
|
|
|
|
- **[Nebula](https://github.com/slackhq/nebula)** — MIT License, Copyright (c) 2018-2019 Slack Technologies, Inc. Downloaded from GitHub at install time.
|
|
- **[WinTun](https://www.wintun.net/)** — Prebuilt Binaries License, Copyright WireGuard LLC. Included in the Nebula release archive.
|