189 lines
8.6 KiB
Markdown
189 lines
8.6 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
|
|
|
|
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 CA
|
|
- `host.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:
|
|
|
|
```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"
|
|
```
|
|
|
|
Optionally pass `-ComputerName` to validate the machine name matches a pre-staged AD object:
|
|
|
|
```powershell
|
|
& "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:
|
|
|
|
```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
|
|
|
|
**bootstrap.ps1**
|
|
- `-ComputerName` (optional) — Expected NetBIOS name (max 15 characters). Warns if the current machine name doesn't match.
|
|
- Reads `DnsServer` and `Domain` from `bootstrap.json`.
|
|
|
|
**bootstrap.json**
|
|
```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 to `nebula1`
|
|
|
|
**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
|
|
|
|
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.
|