Despite Wireguard being the hot new choice for a VPN on unixy systems, I’ve still stuck to OpenVPN. I’ll be trying WG at some point, but OVPN has mostly-worked for me, despite some painful past experiences.
As I’ve needed to move some servers around, I’ll be reinstalling OpenVPN and figured it’s best to document my actions this time.
For my purposes, I do not use OpenVPN to proxy traffic, mostly just to be able to access a few services from outside of my home network. Additionally, some hardening options are enabled, but this isn’t intended to be the most secure setup; Notably I’ve no CRL and I use tls-auth instead of tls-crypt.
Obvious step, installation:
pkg_add openvpn easy-rsa
Review and edit the easy-rsa vars file as needed:
cp /usr/local/share/easy-rsa/vars{.example,} && vim /usr/local/share/easy-rsa/vars
Creating directories as OpenBSD appears to not give us the courteousy, with a bit of an odd setup so we can chroot:
install -m 700 -d /etc/openvpn/clients
# ^ personal preference for creating new client configs on the server side, see script below
install -m 700 -o _openvpn -d /var/openvpn/var/log/openvpn
# ^ Not entirely sure if this is still necessary, openvpn opens logs before chroot
install -m 700 -d /var/openvpn/etc/openvpn/ccd
install -m 700 -o _openvpn -d /var/openvpn/tmp
touch /var/openvpn/var/log/openvpn/openvpn.log
ln -s /var/openvpn/etc/openvpn/ccd /etc/openvpn/ccd
ln -s /var/openvpn/var/log/openvpn/ /var/log/openvpn
Next we’ll generate our CA and associated certificates and keys using easy-rsa. You’ll want to go through this line-by-line, some parts are interactive:
alias easyrsa=/usr/local/share/easy-rsa/easyrsa
cd /etc/openvpn/
easyrsa init-pki
easyrsa build-ca nopass
easyrsa build-server-full server polynomial.space nopass
easyrsa gen-dh
openvpn --genkey --secret ta.key
Drop in a basic config, uncommented for brievety, probably best to reference some sample configs:
cat <<\EOF > /etc/openvpn.conf
ca /etc/openvpn/pki/ca.crt
cert /etc/openvpn/pki/issued/server.crt
key /etc/openvpn/pki/private/server.key
dh /etc/openvpn/pki/dh.pem
tls-auth /etc/openvpn/ta.key 0
por 61194
proto tcp
proto udp
dev tun
topology subnet
server 172.16.32.0 255.255.255.0
push "route 172.16.32.0 255.255.255.0"
keepalive 10 120
client-to-client
ifconfig-pool-persist /var/log/openvpn/ipp.txt
client-config-dir /etc/openvpn/ccd
status /var/log/openvpn/openvpn.log
verb 2
tls-version-min 1.2
tls-ciphers TLS-DHE-RSA-WITH-AES-256-CBC-SHA256
ncp-ciphers AES-256-GCM
cipher AES-256-GCM
auth SHA256
persist-key
persist-tun
user _openvpn
group _openvpn
chroot /var/openvpn
explicit-exit-notify 1
EOF
And now a script to generate client .ovpn files on the server side, optionally allowing static IP assignment.
#!/bin/sh
CLIENT="${1}"
IP="${2}"
if [ -z "${CLIENT}" ]; then
exit 1
fi
cd /etc/openvpn
/usr/local/share/easy-rsa/easyrsa build-client-full "${CLIENT}" nopass
cat <<\EOF > clients/"${CLIENT}".ovpn
client
dev tun
;proto tcp
proto udp
remote 104.207.150.221 61194 #CHANGEME
route 172.16.32.0 255.255.255.0
nobind
persist-tun
user openvpn
group openvpn
cipher AES-256-GCM
auth SHA256
persist-key
key-direction 1
verb 2
mute 20
EOF
echo '<ca>' >> clients/"${CLIENT}".ovpn
cat pki/ca.crt >> clients/"${CLIENT}".ovpn
echo '</ca>' >> clients/"${CLIENT}".ovpn
echo '<cert>' >> clients/"${CLIENT}".ovpn
cat pki/issued/"${CLIENT}".crt >> clients/"${CLIENT}".ovpn
echo '</cert>' >> clients/"${CLIENT}".ovpn
echo '<key>' >> clients/"${CLIENT}".ovpn
cat pki/private/"${CLIENT}".key >> clients/"${CLIENT}".ovpn
echo '</key>' >> clients/"${CLIENT}".ovpn
echo '<tls-auth>' >> clients/"${CLIENT}".ovpn
cat ta.key >> clients/"${CLIENT}".ovpn
echo '</tls-auth>' >> clients/"${CLIENT}".ovpn
rm pki/private/"${CLIENT}".key pki/issued/"${CLIENT}".crt
if [ -n "${IP}" ]; then
echo "ifconfig-push ${IP} 255.255.255.0" > ccd/"${CLIENT}"
fi
echo "written to: $(pwd)/clients/${CLIENT}.ovpn"
After testing the server, enable as a service:
rcctl enable openvpn
rcctl set openvpn flags "--config /etc/openvpn.conf"
rcctl start openvpn