I'm making a compiled version of the solution in case someone else runs into the issue.
This complied guide borrows from these guides:
OpenWRT OpenVPN Basic
OpenWRT OpenVPN PKI Extras
OpenWRT DDNS
For setting up the VPN initially, we need to SSH into the router. After we SSH into the router, we need to first install all of the necessary packages
opkg update
opkg install openvpn-openssl openvpn-easy-rsa luci-app-openvpn openssh-sftp-server
If you plan on using a Dynamic DNS address, then follow this guide, if not, then continue on. In my case, I used DuckDNS.
Now we configure the firewall. Consider VPN network as private and assign VPN interface to LAN zone to minimize firewall setup. Allow access to VPN server from WAN zone
uci rename firewall.@zone[0]="lan"
uci rename firewall.@zone[1]="wan"
uci rename firewall.@forwarding[0]="lan_wan"
uci del_list firewall.lan.device="tun0"
uci add_list firewall.lan.device="tun0"
uci -q delete firewall.ovpn
uci set firewall.ovpn="rule"
uci set firewall.ovpn.name="Allow-OpenVPN"
uci set firewall.ovpn.src="wan"
uci set firewall.ovpn.dest_port="1194"
uci set firewall.ovpn.proto="udp"
uci set firewall.ovpn.target="ACCEPT"
uci commit firewall
/etc/init.d/firewall restart
Then copy and paste these commands to set up the parameters
export EASYRSA_PKI="/etc/easy-rsa/pki"
export EASYRSA_REQ_CN="Octoprint CA"
Then we need to generate the PKI file, run this command to clear old clients and generate a new PKI. The --branch
parameter in front of all of the commands is for allowing for running all of the commands back to back (without having to run each independently)
easyrsa --batch init-pki
Then we need to create DH parameter, however this will take a long time on the router
easyrsa --batch gen-dh
Now we create a CA, the nopass
parameter will allow the CA to be generated without having to encrypt it; the same case is for the next for commands
# Create a new CA
easyrsa --batch build-ca nopass
Then we generate a keypair and sign locally for a server, you can name the server to whatever you like
easyrsa --batch build-server-full server nopass
Generate a keypair and sign locally for a client, you can name the client whatever you like. You can repeat the command however many times you need for each device you plan on connecting the VPN to. In my case, I creating clients for 3 devices (my laptop, desktop, and phone)
easyrsa --batch build-client-full client nopass
#Additional Clients
easyrsa --batch build-client-full client1 nopass
easyrsa --batch build-client-full client2 nopass
easyrsa --batch build-client-full client3 nopass
Now we generate the TLS PSK file
OVPN_PKI="/etc/easy-rsa/pki"
openvpn --genkey --secret ${OVPN_PKI}/tc.pem
Fetch IP addresses and the full name of the DDNS (if you are using a DDNS)
# Fetch IP address
. /lib/functions/network.sh
network_flush_cache
network_find_wan NET_IF
network_get_ipaddr OVPN_SERV "${NET_IF}"
# Fetch FQDN from DDNS client
OVPN_FQDN="$(uci -q get "$(uci -q show ddns \
| sed -n -e "/\.enabled='1'$/s//.lookup_host/p" \
| sed -n -e "1p")")"
if [ -n "${OVPN_FQDN}" ]
then
OVPN_SERV="${OVPN_FQDN}"
fi
Now we generate the configuration files for the server and client files
# Configuration parameters
OVPN_DIR="/etc/openvpn"
OVPN_PKI="/etc/easy-rsa/pki"
OVPN_DEV="$(uci get firewall.lan.device | sed -e "s/^.*\s//")"
OVPN_PORT="$(uci get firewall.ovpn.dest_port)"
OVPN_PROTO="$(uci get firewall.ovpn.proto)"
OVPN_POOL="192.168.8.0 255.255.255.0"
OVPN_DNS="${OVPN_POOL%.* *}.1"
OVPN_DOMAIN="$(uci get dhcp.@dnsmasq[0].domain)"
OVPN_DH="$(cat ${OVPN_PKI}/dh.pem)"
OVPN_TC="$(sed -e "/^#/d;/^\w/N;s/\n//" ${OVPN_PKI}/tc.pem)"
OVPN_CA="$(openssl x509 -in ${OVPN_PKI}/ca.crt)"
NL=$'\n'
# Configure VPN server and generate client profiles
umask u=rw,g=,o=
ls ${OVPN_PKI}/issued \
| sed -e "s/\.\w*$//" \
| while read -r OVPN_ID
do
OVPN_KEY="$(cat ${OVPN_PKI}/private/${OVPN_ID}.key)"
OVPN_CERT="$(openssl x509 -in ${OVPN_PKI}/issued/${OVPN_ID}.crt)"
OVPN_CERT_EXT="$(openssl x509 -in ${OVPN_PKI}/issued/${OVPN_ID}.crt -purpose)"
OVPN_CONF_SERVER="\
user nobody
group nogroup
dev ${OVPN_DEV}
port ${OVPN_PORT}
proto ${OVPN_PROTO}
server ${OVPN_POOL}
topology subnet
client-to-client
keepalive 10 60
persist-tun
persist-key
push \"dhcp-option DNS ${OVPN_DNS}\"
push \"dhcp-option DOMAIN ${OVPN_DOMAIN}\"
push \"redirect-gateway def1\"
push \"persist-tun\"
push \"persist-key\"
<dh>${NL}${OVPN_DH}${NL}</dh>"
OVPN_CONF_CLIENT="\
dev ${OVPN_DEV%%[0-9]*}
nobind
client
remote ${OVPN_SERV} ${OVPN_PORT} ${OVPN_PROTO}
auth-nocache
remote-cert-tls server"
OVPN_CONF_COMMON="\
<tls-crypt>${NL}${OVPN_TC}${NL}</tls-crypt>
<key>${NL}${OVPN_KEY}${NL}</key>
<cert>${NL}${OVPN_CERT}${NL}</cert>
<ca>${NL}${OVPN_CA}${NL}</ca>"
case ${OVPN_CERT_EXT} in
(*"SSL server : Yes"*) cat << EOF > ${OVPN_DIR}/${OVPN_ID}.conf ;;
${OVPN_CONF_SERVER}
${OVPN_CONF_COMMON}
EOF
(*"SSL client : Yes"*) cat << EOF > ${OVPN_DIR}/${OVPN_ID}.ovpn ;;
${OVPN_CONF_CLIENT}
${OVPN_CONF_COMMON}
EOF
esac
done
/etc/init.d/openvpn restart
ls ${OVPN_DIR}/*.ovpn
Then we generate a CRL, this enables the client to verify the client keys (in case you go and revoke a certificate, it won't allow a client to connect with invalid keys)
easyrsa --batch gen-crl
OVPN_CRL="$(cat ${EASYRSA_PKI}/crl.pem)"
NL=$'\n'
sed -i -e "
/^<crl-verify>/,/^<\/crl-verify>/s/^/#/
\$a <crl-verify>\n${OVPN_CRL//${NL}/\n}\n</crl-verify>
" /etc/openvpn/server.conf
/etc/init.d/openvpn restart
NOTE: You may have to do cat ${EASYRSA_PKI}/crl.pem
and manually add the contents from the crl file into the server file via vim as there's some sort of bug with the above script that causes the contents from it to get added into server.conf
incorrectly, which will cause issues with CRL verificiation. The CRL verification line in server.conf should appear as the following:
<crl-verify>
-----BEGIN X509 CRL-----
THE CRL KEY SHOULD BE HERE
-----END X509 CRL-----
</crl-verify>
Finally, perform OpenWrt backup. Then extract client profiles from the archive and import them to your clients to your devices.
If you want to redirect all VPN traffic to a single device, then we create a rule like this
config rule
option src 'lan'
option family 'ipv4'
option dest 'lan'
list dest_ip '!10.0.0.1'
option target 'REJECT'
option name 'vpn to RPi'
list src_ip '192.168.8.0/24'
And we change 10.0.0.1
to the ip of the device.
After that, it's all setup and ready to go! The server.conf
file will already be running on the sever, however it will not appear in Luci, in order to have it appear in there you must import the file (after getting the files onto your computer via backup or a STFP server), Go to VPN > OpenVPN > OVPN configuration file upload and upload the file from there; then be sure to delete the server.conf file off the router (but do keep it on your computer for safe keeping).