claude generated first pass

This commit is contained in:
nick committed 2026-07-15 17:58:23 -07:00
1 parent 81553590df
commit 911b1f8c5d
24 files changed
+899 -1

No files matched your search

+78
View File
@@ -0,0 +1,78 @@
# Site-side configuration (manual steps at Trochalakis and Oswald)
Everything the RackNerd box needs from the two sites, the DCs, and the Duo
admin panel. Nothing here runs on the VPS.
## 1. WireGuard peers (both sites)
Add the RackNerd peer to each site's existing WG config. The sites
**initiate** (RackNerd has the static IP) and keep the tunnel alive:
```ini
# Trochalakis WG box — add:
[Peer] # RackNerd hub
PublicKey = <RACKNERD_WG_PUBLIC_KEY> # printed by host/setup.sh
Endpoint = vpn.atlashorizon.net:51820
AllowedIPs = 172.31.255.1/32, 172.31.8.0/24
PersistentKeepalive = 25
```
Oswald: identical block. Site WG interface addresses on the new mesh links:
Trochalakis `172.31.255.2/32`, Oswald `172.31.255.3/32` (add to the site
[Interface] Address list if the WG box doesn't already carry an address in
this transfer net).
**Do NOT** add the other site's LAN to the RackNerd peer's AllowedIPs —
inter-site traffic stays on your existing direct tunnel. The mesh only adds
`172.31.8.0/24` (roaming clients) and `172.31.255.1` (the hub) via RackNerd.
## 2. Return-path routing (both sites)
Hosts at each site must route the client subnet back via the site WG box.
If the WG box is **not** the LAN default gateway, add static routes on the
LAN router (or directly on the DCs):
| Destination | Via |
|------------------|------------------------|
| `172.31.8.0/24` | site WireGuard box |
| `172.31.255.1/32`| site WireGuard box |
Verify no asymmetry: `tracert 172.31.8.10` from a DC must leave via the
local WG box → RackNerd, never via the other site.
## 3. Windows Firewall / segmentation on the DCs
Allow from **`172.31.8.0/24`** (roaming clients, real source IPs): standard
AD client ports — DNS 53, Kerberos 88/464, LDAP 389/636, SMB 445, RPC 135 +
49152-65535, NTP 123, GC 3268/3269.
Allow from **`172.31.255.1/32`** (the RackNerd host itself):
- TCP/UDP 53 → AHDC01, AHDC03, AH-OSWLDC (Unbound forwarder queries)
- TCP 636 → AHDC01, AHDC03 (Duo Auth Proxy LDAPS)
## 4. Active Directory
- **Sites and Services**: create subnet `172.31.8.0/24` and assign it to the
Trochalakis site (clients will then prefer AHDC01/AHDC03 for DC discovery).
- **Duo service account**: plain domain user, read-only, no interactive
logon rights; goes in `.env` as `DUO_SVC_USER` / `DUO_SVC_PASSWORD`.
- Optional: a `VPN Users` security group if you want `security_group_dn`
gating in the auth proxy.
## 5. LDAPS certificates
AHDC01 and AHDC03 need valid LDAPS certs (AD CS auto-enrollment or
manually issued). Export the issuing CA chain as PEM →
`duo-authproxy/certs/ad-ldaps-ca.pem` on the VPS
(see that directory's README).
## 6. Duo Admin Panel
Applications → Protect an Application → **OpenVPN** (RADIUS). Copy the
integration key, secret key, and API hostname into `.env`. Recommended
policy: enrolled users only; new-user policy deny.
## 7. Public DNS
Create `vpn.atlashorizon.net` → RackNerd static IP (public registrar DNS,
not AD). Used by roaming clients and both site WG endpoints.
+79
View File
@@ -0,0 +1,79 @@
# Test plan
Run the stages in order — each depends on the previous one.
## 0. Host plumbing (on the VPS)
```bash
sysctl net.ipv4.ip_forward # = 1
wg show wg0 # both peers: recent "latest handshake"
ping -c3 172.31.255.2 # Trochalakis WG box
ping -c3 172.31.255.3 # Oswald WG box
ping -c3 <TROCH_DC1_IP> # AHDC01 across the tunnel
ping -c3 <OSWALD_DC_IP> # AH-OSWLDC across the tunnel
```
## 1. Unbound (on the VPS)
```bash
docker compose ps unbound # healthy
# AD SRV record via conditional forward (the money query):
dig @127.0.0.1 _ldap._tcp.dc._msdcs.ad.atlashorizon.net SRV +short
dig @127.0.0.1 ahdc01.ad.atlashorizon.net +short
dig @127.0.0.1 ah-oswldc.ad.oswaldtheotter.net +short
dig @127.0.0.1 -x <TROCH_DC1_IP> +short # reverse zone
dig @127.0.0.1 google.com +short # public recursion
```
## 2. Duo Auth Proxy (on the VPS)
```bash
docker compose logs duo-authproxy # connectivity tool output: LDAPS bind
# to both DCs OK, Duo API reachable
# End-to-end RADIUS (expect a push to your phone, then Access-Accept):
apt-get install -y freeradius-utils
radtest '<aduser>' '<adpassword>' 127.0.0.1:1812 10 "$RADIUS_SECRET"
# Negative: wrong password -> immediate Access-Reject, no push.
```
This stage proves the **LDAP bind** leg independently of OpenVPN.
## 3. Full client connect (from outside, e.g. phone hotspot)
1. Import a built `.ovpn`, connect with AD username + password → approve
the Duo push → connected.
2. `ipconfig /all`: address in `172.31.8.0/24`, DNS `172.31.8.1`, suffix
`ad.atlashorizon.net`.
3. DNS through the tunnel:
`nslookup -type=SRV _ldap._tcp.dc._msdcs.ad.atlashorizon.net`
4. Reachability, one host per site:
`ping ahdc01.ad.atlashorizon.net` and `ping ah-oswldc.ad.oswaldtheotter.net`
5. AD actually works: `dir \\ad.atlashorizon.net\SYSVOL` then `klist`
(Kerberos tickets present, no NTLM fallback).
6. Passcode-append fallback: reconnect using `password,<passcode>` from the
Duo app — must succeed with no push.
## 4. Routing correctness
- On AHDC01, Security log 4624/4768 for the test user shows the **real**
client IP (`172.31.8.x`), not a NAT address — confirms routed (no
masquerade) design.
- From the client: `tracert <TROCH_DC1_IP>` → first hop `172.31.8.1`.
- From a DC at each site: `tracert 172.31.8.x` → leaves via the **local**
WG box (no path through the other site = no asymmetric routing).
- From a Trochalakis host: `tracert <oswald LAN IP>` still uses the direct
site-to-site tunnel (RackNerd never appears).
## 5. Exposure check (from any outside box)
```bash
nmap -sU -p 53,1194,51820 <racknerd_public_ip> # 53 must NOT respond
nmap -sT -p 22,53,636,1812,7505 <racknerd_public_ip> # only 22 open
```
## 6. Persistence
```bash
docker compose down && docker compose up -d --build # survives cleanly
reboot # then: wg show, docker compose ps, re-run stage 3 quick connect
```