nebula-domain-join/README.md

173 lines
7.9 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.
- **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.