86 lines
3.2 KiB
Plaintext
86 lines
3.2 KiB
Plaintext
# OpenVPN road-warrior endpoint — RackNerd hub
|
|
# Auth chain: AD user/pass -> PAM -> RADIUS
|
|
# -> Duo Auth Proxy (127.0.0.1:1812) -> LDAPS to the DCs.
|
|
# No individual client certs: identity is LDAP + Duo only. tls-crypt
|
|
# (shared key in the profile) still gates who can attempt a handshake.
|
|
|
|
port 1194
|
|
proto udp4
|
|
dev tun0
|
|
topology subnet
|
|
|
|
server 172.31.8.0 255.255.255.0
|
|
|
|
# Identity = AD username (username-as-common-name), and one user WILL
|
|
# connect from several devices (laptop + phone). duplicate-cn allows the
|
|
# concurrent sessions and gives each its own pool IP. Sticky per-user IPs
|
|
# (ifconfig-pool-persist) are incompatible with that — do not re-enable.
|
|
duplicate-cn
|
|
|
|
# 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 Technitium. Deliberately NO "dhcp-option DOMAIN"
|
|
# or DOMAIN-SEARCH here: in OpenVPN3 clients (Connect on macOS/iOS/
|
|
# Android/Windows) those options MEAN split-DNS — pushing them scopes the
|
|
# VPN DNS to just those domains. With only DNS pushed, 172.31.8.1 becomes
|
|
# the default resolver for every query. ADAPTER_DOMAIN_SUFFIX sets the
|
|
# Windows connection-specific suffix (short names like "ahdc01" still
|
|
# resolve) without triggering split-DNS. block-outside-dns additionally
|
|
# stops Windows from leaking queries to the local LAN resolver.
|
|
push "dhcp-option DNS 172.31.8.1"
|
|
push "dhcp-option ADAPTER_DOMAIN_SUFFIX ad.atlashorizon.net"
|
|
push "block-outside-dns"
|
|
|
|
# PKI — server certificate only (offline CA, see pki/README.md);
|
|
# clients present no certificate.
|
|
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
|
|
|
|
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 none
|
|
username-as-common-name
|
|
hand-window 120 # allow time for the Duo push round-trip
|
|
# Hourly rekey + 12h auth token: renegotiations are satisfied silently by
|
|
# the pushed token (no mid-session Duo prompts); a fresh password + push
|
|
# is only required once the token expires. (auth-gen-token requires a
|
|
# non-zero reneg-sec — do not set reneg-sec 0 here.)
|
|
reneg-sec 3600
|
|
auth-gen-token 43200
|
|
|
|
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
|
|
|
|
# Register each client as <username>.$VPN_DNS_ZONE (A + PTR) in Technitium
|
|
# on connect, clean up on disconnect. Invoked via sh so the mounted script
|
|
# needs no exec bit; env (TECHNITIUM_ADMIN_PASSWORD, VPN_DNS_ZONE) comes
|
|
# from the container environment.
|
|
script-security 2
|
|
learn-address "/bin/sh /etc/openvpn/learn-address.sh"
|
|
|
|
status /var/lib/openvpn/status.log 30
|
|
# Unix socket (root-only) instead of a passwordless TCP port:
|
|
# docker compose exec openvpn sh -c "socat - UNIX:/var/lib/openvpn/mgmt.sock"
|
|
management /var/lib/openvpn/mgmt.sock unix
|
|
verb 3
|