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

+13
View File
@@ -0,0 +1,13 @@
FROM debian:bookworm-slim
# libpam-radius-auth: PAM -> RADIUS bridge to the Duo Auth Proxy on 127.0.0.1
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
openvpn libpam-radius-auth iproute2 procps ca-certificates \
&& rm -rf /var/lib/apt/lists/*
COPY pam-openvpn /etc/pam.d/openvpn
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
+14
View File
@@ -0,0 +1,14 @@
#!/bin/sh
set -eu
: "${RADIUS_SECRET:?RADIUS_SECRET must be set in .env}"
# pam_radius format: server[:port] secret timeout
# 60s timeout leaves room for the user to approve a Duo push.
printf '127.0.0.1:1812\t%s\t60\n' "$RADIUS_SECRET" > /etc/pam_radius_auth.conf
chmod 600 /etc/pam_radius_auth.conf
mkdir -p /var/lib/openvpn
[ -c /dev/net/tun ] || { mkdir -p /dev/net; mknod /dev/net/tun c 10 200; }
exec openvpn --cd /etc/openvpn --config server.conf
+5
View File
@@ -0,0 +1,5 @@
# PAM service used by openvpn-plugin-auth-pam.
# pam_radius_auth reads /etc/pam_radius_auth.conf (written by entrypoint.sh)
# and forwards the username/password to the Duo Auth Proxy on 127.0.0.1:1812.
auth required pam_radius_auth.so
account required pam_permit.so
+50
View File
@@ -0,0 +1,50 @@
# OpenVPN PKI — offline CA workflow
The CA private key **never touches the VPS**. Run easy-rsa on an offline
machine (or at minimum a machine that isn't this server), then copy only the
issued material here.
## One-time CA + server cert (on the offline machine)
```bash
git clone https://github.com/OpenVPN/easy-rsa.git && cd easy-rsa/easyrsa3
./easyrsa init-pki
./easyrsa build-ca # sets the CA passphrase — keep offline
./easyrsa build-server-full racknerd-vpn nopass
openvpn --genkey tls-crypt ta.key # shared tls-crypt key
./easyrsa gen-crl
```
## Copy to the VPS (this directory)
| File on offline box | Name here |
|--------------------------------------|---------------|
| `pki/ca.crt` | `ca.crt` |
| `pki/issued/racknerd-vpn.crt` | `server.crt` |
| `pki/private/racknerd-vpn.key` | `server.key` |
| `ta.key` | `ta.key` |
| `pki/crl.pem` (optional, see server.conf) | `crl.pem` |
`chmod 600 server.key ta.key` after copying.
## Per-user client certs (offline)
```bash
./easyrsa build-client-full nick nopass
```
Build the client's `.ovpn` from `client/client.ovpn.template`, pasting
`ca.crt`, the client cert/key, and `ta.key` into the inline blocks.
CN should match the AD username — the server logs use it
(`username-as-common-name` keeps them consistent).
## Revoking a client
```bash
./easyrsa revoke nick && ./easyrsa gen-crl
```
Copy the fresh `crl.pem` here, uncomment `crl-verify` in `server.conf`, and
`docker compose restart openvpn`.
Everything in this directory except this README is gitignored.
+65
View File
@@ -0,0 +1,65 @@
# OpenVPN road-warrior endpoint — RackNerd hub
# Auth chain: client cert (offline CA) + user/pass -> PAM -> RADIUS
# -> Duo Auth Proxy (127.0.0.1:1812) -> LDAPS to the DCs.
port 1194
proto udp4
dev tun0
topology subnet
server 172.31.8.0 255.255.255.0
ifconfig-pool-persist /var/lib/openvpn/ipp.txt
# Split tunnel: only the AD sites + transfer net ride the VPN.
push "route 192.168.20.0 255.255.255.0"
push "route 192.168.7.0 255.255.255.0"
push "route 172.31.255.0 255.255.255.0"
# All client DNS goes to Unbound on this box (block-outside-dns stops
# Windows from leaking AD lookups to the local LAN resolver).
push "dhcp-option DNS 172.31.8.1"
push "dhcp-option DOMAIN ad.atlashorizon.net"
push "dhcp-option DOMAIN-SEARCH ad.atlashorizon.net"
push "dhcp-option DOMAIN-SEARCH ad.calliecorner.net"
push "dhcp-option DOMAIN-SEARCH ad.oswaldtheotter.net"
push "dhcp-option DOMAIN-SEARCH ad.trochalakis.net"
push "block-outside-dns"
# PKI — issued from the offline CA, see pki/README.md
ca /etc/openvpn/pki/ca.crt
cert /etc/openvpn/pki/server.crt
key /etc/openvpn/pki/server.key
dh none
tls-crypt /etc/openvpn/pki/ta.key
# Enable once you publish a CRL from the offline CA (revoked laptops etc.):
;crl-verify /etc/openvpn/pki/crl.pem
remote-cert-tls client
tls-version-min 1.2
data-ciphers AES-256-GCM:CHACHA20-POLY1305
auth SHA256
# User auth via Duo (password only = push; "password,123456" = passcode)
plugin /usr/lib/openvpn/openvpn-plugin-auth-pam.so openvpn
verify-client-cert require
username-as-common-name
hand-window 120 # allow time for the Duo push round-trip
reneg-sec 0 # no mid-session TLS renegotiation (would re-prompt Duo)
auth-gen-token 43200 # reconnects within 12h reuse a token instead of a new push
keepalive 10 60
explicit-exit-notify 1
# wg0 MTU is 1420; keep the client tunnel small enough that client->site
# packets never fragment inside the WireGuard leg.
tun-mtu 1400
mssfix 1360
user nobody
group nogroup
persist-key
persist-tun
status /var/lib/openvpn/status.log 30
management 127.0.0.1 7505
verb 3