Setup OpenVPN server with OpenWrt

Tzu Hao Chung
3 min readOct 7, 2023

--

Steps to setup OpenVPN server with OpenWrt

Preparation

You should already install OpenWrt in your router. If not, follow the steps in https://medium.com/@tzuhaochung/install-openwrt-on-your-router-629ea869d67b

Install package

In default, there is no OpenVPN function in OpenWrt, you need to download it. ( Of course., it let you customize your router).

Open the command lin (CMD) or Power Shell if you are using Windows machine, promt below command to connect to your router

ssh root@192.168.1.1

Run below commands to install required packages for OpenVPN

opkg update
opkg install openvpn-openssl openvpn-easy-rsa

Run these commands to setup some parameters that we would use later. It defines the folder and IP address we will use to setup VPN server.

VPN_DIR="/etc/openvpn"
VPN_PKI="/etc/easy-rsa/pki"
VPN_PORT="1194"
VPN_PROTO="udp"
VPN_POOL="192.168.8.0 255.255.255.0"
VPN_DNS="${VPN_POOL%.* *}.1"
VPN_DN="$(uci -q get dhcp.@dnsmasq[0].domain)"

NET_FQDN="$(uci -q get ddns.@service[0].lookup_host)"
. /lib/functions/network.sh
network_flush_cache
network_find_wan NET_IF
network_get_ipaddr NET_ADDR "${NET_IF}"
if [ -n "${NET_FQDN}" ]
then VPN_SERV="${NET_FQDN}"
else VPN_SERV="${NET_ADDR}"
fi

Generate Key for OpenVPN server

OpenVPN server requires certificate and key to establish the connection with client. Run the commands in your command line to create the stuff.

Define parameters

cat << EOF > /etc/profile.d/easy-rsa.sh
export EASYRSA_PKI="${VPN_PKI}"
export EASYRSA_TEMP_DIR="/tmp"
export EASYRSA_CERT_EXPIRE="3650"
export EASYRSA_BATCH="1"
EOF
. /etc/profile.d/easy-rsa.sh

Initialize the target folder

easyrsa init-pki

Generate DN parameter. Note that this will take long time. For Netgear R6260 my case, it take 10 minutes.

easyrsa gen-dh

You can’t interrupt the process or disconnect with router. If it happenes, remove the file to do above command again.

rm /etc/easy-rsa/pki/dh.pem

Create CA

easyrsa build-ca nopass

Generate server keys, certificate for server and client

easyrsa build-server-full server nopass

openvpn --genkey tls-crypt-v2-server ${EASYRSA_PKI}/private/server.pem
easyrsa build-client-full client nopass

openvpn --tls-crypt-v2 ${EASYRSA_PKI}/private/server.pem \
--genkey tls-crypt-v2-client ${EASYRSA_PKI}/private/client.pem

Setup Firewall

Execute below commands to allow connection can access via VPN port.

uci rename firewall.@zone[0]="lan"
uci rename firewall.@zone[1]="wan"
uci del_list firewall.lan.device="tun+"
uci add_list firewall.lan.device="tun+"
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="${VPN_PORT}"
uci set firewall.ovpn.proto="${VPN_PROTO}"
uci set firewall.ovpn.target="ACCEPT"
uci commit firewall
/etc/init.d/firewall restart

Setup VPN Service

umask go=
VPN_DH="$(cat ${VPN_PKI}/dh.pem)"
VPN_CA="$(openssl x509 -in ${VPN_PKI}/ca.crt)"
ls ${VPN_PKI}/issued \
| sed -e "s/\.\w*$//" \
| while read -r VPN_ID
do
VPN_TC="$(cat ${VPN_PKI}/private/${VPN_ID}.pem)"
VPN_KEY="$(cat ${VPN_PKI}/private/${VPN_ID}.key)"
VPN_CERT="$(openssl x509 -in ${VPN_PKI}/issued/${VPN_ID}.crt)"
VPN_EKU="$(echo "${VPN_CERT}" | openssl x509 -noout -purpose)"
case ${VPN_EKU} in
(*"SSL server : Yes"*)
VPN_CONF="${VPN_DIR}/${VPN_ID}.conf"
cat << EOF > ${VPN_CONF} ;;
user nobody
group nogroup
dev tun
port ${VPN_PORT}
proto ${VPN_PROTO}
server ${VPN_POOL}
topology subnet
client-to-client
keepalive 10 60
persist-tun
persist-key
push "dhcp-option DNS ${VPN_DNS}"
push "dhcp-option DOMAIN ${VPN_DN}"
push "redirect-gateway def1"
push "persist-tun"
push "persist-key"
<dh>
${VPN_DH}
</dh>
EOF
(*"SSL client : Yes"*)
VPN_CONF="${VPN_DIR}/${VPN_ID}.ovpn"
cat << EOF > ${VPN_CONF} ;;
user nobody
group nogroup
dev tun
nobind
client
remote ${VPN_SERV} ${VPN_PORT} ${VPN_PROTO}
auth-nocache
remote-cert-tls server
EOF
esac
cat << EOF >> ${VPN_CONF}
<tls-crypt-v2>
${VPN_TC}
</tls-crypt-v2>
<key>
${VPN_KEY}
</key>
<cert>
${VPN_CERT}
</cert>
<ca>
${VPN_CA}
</ca>
EOF
done
/etc/init.d/openvpn restart
ls ${VPN_DIR}/*.ovpn

To start VPN Server

/etc/init.d/openvpn restart

To stop VPN Server

/etc/init.d/openvpn stop

To check status VPN Server

/etc/init.d/openvpn status

After complete, you can find the OpenVPN client file under the path

ls ${VPN_DIR}/*.ovpn

/etc/openvpn/client.ovpn

Use command to view and copy content a new file in your local machine. Or you can use FTP or SCP service to download the file from router into your

cat /etc/openvpn/client.ovpn

Provide the file client.ovpn to the user who will connec to your VPN server.

--

--