claude generated first pass
This commit is contained in:
1 parent
81553590df
commit
911b1f8c5d
24 files changed
+899
-1
No files matched your search
@@ -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"]
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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.
|
||||
@@ -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
|
||||
Reference in new issue
Block a user