Configure EgdeRouter OpenVPN
Lars Jönsson 2024-02-17
How to setup an OpenVPN server on EdgeRouter with password protected client keys using a separate CA. The CA uses the easy-rsa 3 script to ensure that the certificates suits hardened OpenVPN security.
This guide consists of three parts:
- Initial setup
- Configure new clients
- Renew certificates for clients
- Revoking existing clients
Overview
The OpenVPN server is setup according to the official guide EdgeRouter - OpenVPN Server, with the main difference that the Certificate Authority (CA) is outside the EdgeRouter. This makes it easier to improve the security.
The different key and certificate files, used by OpenVPN server and clients, are used as follows:
Filename | Needed By | Purpose | Secret |
---|---|---|---|
ca.crt | server + all clients | Root CA certificate | NO |
ca.key | key signing machine only | Root CA key | YES |
dh{n}.pem | server only | Diffie Hellman parameters | NO |
server.crt | server only | Server Certificate | NO |
server.key | server only | Server Key | YES |
client1.crt | client1 only | Client1 Certificate | NO |
client1.key | client1 only | Client1 Key | YES |
client2.crt | client2 only | Client2 Certificate | NO |
client2.key | client2 only | Client2 Key | YES |
client3.crt | client3 only | Client3 Certificate | NO |
client3.key | client3 only | Client3 Key | YES |
All non-secret parts, as certificates, Diffie-Hellman key and Certification Revocation List, are generated on the CA. The secret parts are as follows:
- The server key is generated on the server and never leaves the server
- The CA key is generated on the CA and never leaves the CA
- The client keys are also generated on the CA, but they are always password protected and it shall not be a problem to move it to the clients as a part of a configuration file
Preparations
The CA is created on a Linux computer that runs Fedora 32. The easy-rsa 3 package (see OpenVPN/easy-rsa) will be used for managing the certificates. The entire CA will be stored on a safe storage (see Safe storage) that can be stored on a USB stick, but these instructions assumes that the safe storage is stored locally on the Linux computer.
Install the easy-rsa package.
sudo dnf install easy-rsa
Create the base of the OpenVPN CA at ~/OpenVPN-CA
.
cd
mkdir OpenVPN-CA
cd ~/OpenVPN-CA
Create a safe storage for the pki.
dd if=/dev/zero bs=1M count=100 of=secret-device.img
sudo cryptsetup luksFormat secret-device.img
sudo cryptsetup open --type luks secret-device.img secret-device
sudo mkfs.ext4 /dev/mapper/secret-device
mkdir safe-storage
sudo mount /dev/mapper/secret-device safe-storage
sudo chown $USER:`id -gn` safe-storage
Create a link to the easyrsa script and copy the example configuration file.
cd safe-storage
ln -s /usr/share/easy-rsa/3/easyrsa
cp /usr/share/doc/easy-rsa/vars.example vars
Create CA
By default, the CA root certificate expires after 10 years, signed certificates expires after 2 years and the revocation list (CRL) expires are 180 days.
Set the expire date to 10 years for all by setting these varibles in
the vars
file.
set_var EASYRSA_CERT_EXPIRE 3650
set_var EASYRSA_CRL_DAYS 3650
Initialize the pki.
cd ~/OpenVPN-CA/safe-storage
./easyrsa init-pki
Build the CA.
./easyrsa build-ca
Create OpenVPN server
Configuring the OpenVPN server follows the official guide EdgeRouter - OpenVPN Server with some modifications.
Create key and CSR on the EdgeRouter
Login to the EgdeRouter and create the key/CSR (Certificate Signing
Request). Select a temporary password and enter '.' in the other
fields, except the Common Name
, to make them empty.
sudo su
cd /usr/lib/ssl/misc
./CA.pl -newreq
Enter PEM pass phrase: <TEMPORARY_PASS>
Verifying - Enter PEM pass phrase: <TEMPORARY_PASS>
Common Name: server
Sign the CSR on the CA
Move and rename the server key file to the /config/auth directory and remove the password.
mv newkey.pem /config/auth/server.key
openssl rsa -in /config/auth/server.key -out /config/auth/server-no-pass.key
mv /config/auth/server-no-pass.key /config/auth/server.key
Return to operational mode. There is no need to logout from the EdgeRouter at this point, as we will soon come back and configure the OpenVPN server.
exit
Return to the Linux computer to copy the CSR from the EdgeRouter and import it into the CA.
scp admin@192.168.0.1:/usr/lib/ssl/misc/newreq.pem .
./easyrsa import-req newreq.pem server
rm newreq.pem
Sign the CSR and copy the certificate to the EdgeRouter.
./easyrsa sign-req server server
scp pki/issued/server.crt admin@192.168.0.1:/config/auth/server.pem
Create the Certificate Revocation List (CRL) and copy it to the EdgeRouter.
./easyrsa gen-crl
scp pki/crl.pem admin@192.168.0.1:/config/auth/
Copy the CA certificate to the EdgeRouter.
scp pki/ca.crt admin@192.168.0.1:/config/auth/cacert.pem
The OpenVPN server uses a Diffie-Hellman key. I can be generated on the EdgeRouter, but it takes a very long time (more than 30 minutes). It is much faster (less than one minute) to generate it on the Linux computer and copy it to the EdgeRouter.
Generate the key and copy it to the EdgeRouter.
./easyrsa gen-dh
scp pki/dh.pem admin@192.168.0.1:/config/auth/
Lock up the safe storage if all CA work is done.
Configure the OpenVPN server
NOTE When changing any of the TLS files like certificates and CRL, the openvpn configuration needs to be removed and recreated. Maybe it is enough to just remove and recreate the
interfaces openvpn vtun0 tls
part, but that has not been tested. According to the community,interfaces openvpn vtun0
needs to be removed and recreated.
The OpenVPN server is now ready to be configured. Go back to the EgdeRouter and login, if needed.
Enter configuration mode.
configure
Add a firewall rule for the OpenVPN traffic to the WAN_LOCAL firewall policy.
set firewall name WAN_LOCAL rule 30 action accept
set firewall name WAN_LOCAL rule 30 description openvpn
set firewall name WAN_LOCAL rule 30 destination port 1194
set firewall name WAN_LOCAL rule 30 protocol udp
Configure the OpenVPN virtual tunnel interface. Ensure that
name-server
and push-route
corresponds to the used addresses.
set interfaces openvpn vtun0 mode server
set interfaces openvpn vtun0 server subnet 172.16.1.0/24
set interfaces openvpn vtun0 server push-route 192.168.0.0/24
set interfaces openvpn vtun0 server name-server 192.168.0.1
Setup aes256 encryption to improve security.
set interfaces openvpn vtun0 encryption aes256
Link the server certificate/keys and DH key to the virtual tunnel interface.
set interfaces openvpn vtun0 tls ca-cert-file /config/auth/cacert.pem
set interfaces openvpn vtun0 tls cert-file /config/auth/server.pem
set interfaces openvpn vtun0 tls key-file /config/auth/server.key
set interfaces openvpn vtun0 tls crl-file /config/auth/crl.pem
set interfaces openvpn vtun0 tls dh-file /config/auth/dh.pem
Add the virtual tunnel interface to the DNS forwarding interface list.
set service dns forwarding listen-on vtun0
Commit the changes and save the configuration.
commit ; save
Return to operational mode.
exit
The OpenVPN server is now up and running. Logout from the EdgeRouter and go ahead to create client configuration(s).
Create OpenVPN Client configuration
First Open the safe storage, if needed.
For convenience, the OpenVPN server name and client name, are set in environment variables.
NOTE Replace
example.com
with the name of the name of the OpenVPN server andclient1
with an appropriate client name.
ovpn_server=example.com
ovpn_client=client1
Change to the OpenVPN CA directory.
cd ~/OpenVPN-CA/safe-storage
Generate the certificate and key files for the client. Remember the password of the private key as it needs to entered when the client connects to the server.
./easyrsa gen-req $ovpn_client
Sign the certificate.
./easyrsa sign-req client $ovpn_client
Create the OpenVPN client file.
{
echo "client"
echo "dev tun"
echo "proto udp"
echo "remote $ovpn_server 1194"
echo "float"
echo "resolv-retry infinite"
echo "nobind"
echo "persist-key"
echo "persist-tun"
echo "verb 3"
echo "cipher AES-256-CBC"
echo "auth-nocache"
echo "remote-cert-tls server"
echo "<ca>"
openssl x509 -in pki/ca.crt
echo "</ca>"
echo "<cert>"
openssl x509 -in pki/issued/$ovpn_client.crt
echo "</cert>"
echo "<key>"
cat pki/private/$ovpn_client.key
echo "</key>"
} > $ovpn_client.ovpn
An .ovpn file similar to this should be created:
client
dev tun
proto udp
remote example.com 1194
float
resolv-retry infinite
nobind
persist-key
persist-tun
verb 3
cipher AES-256-CBC
auth-nocache
remote-cert-tls server
<ca>
-----BEGIN CERTIFICATE-----
MIIDvTCCAqWgAwIBAgIJANvkOPYA/0TTMA0GCSqGSIb3DQEBBQUAMHUxCzAJBgNV
...
pg==
-----END CERTIFICATE-----
</ca>
<cert>
-----BEGIN CERTIFICATE-----
MIID4jCCAsqgAwIBAgIJANvkOPYA/0TVMA0GCSqGSIb3DQEBBQUAMHUxCzAJBgNV
...
ULQvAqMyg3hvUoMU2PUwvh0wCUoKjZ7ewv3kXYZZ6KJcGJ+B610=
-----END CERTIFICATE-----
</cert>
<key>
-----BEGIN ENCRYPTED PRIVATE KEY-----
MIIFDjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIcjdGY+dkxccCAggA
...
xIk=
-----END ENCRYPTED PRIVATE KEY-----
</key>
Import the .ovpn file to the OpenVPN client software. Use the clients private key password when connecting to the server.
Lock up the safe storage if all CA work is done.
Renew certificate for OpenVPN Client
NOTE The steps in this section is not verified, because the expiration date of the client certificates and is set to 10 years now.
First Open the safe storage, if needed.
For convenience, the OpenVPN server name and client name, are set in environment variables.
NOTE Replace
example.com
with the name of the name of the OpenVPN server andclient1
with an appropriate client name.
ovpn_server=example.com
ovpn_client=client1
Change to the OpenVPN CA directory.
cd ~/OpenVPN-CA/safe-storage
Renew the certificate and using the existing key file for the client. Use the current password of the private key, which is also entered when the client connects to the server.
./easyrsa renew $ovpn_client
Create the OpenVPN client file.
{
echo "client"
echo "dev tun"
echo "proto udp"
echo "remote $ovpn_server 1194"
echo "float"
echo "resolv-retry infinite"
echo "nobind"
echo "persist-key"
echo "persist-tun"
echo "verb 3"
echo "cipher AES-256-CBC"
echo "auth-nocache"
echo "remote-cert-tls server"
echo "<ca>"
openssl x509 -in pki/ca.crt
echo "</ca>"
echo "<cert>"
openssl x509 -in pki/issued/$ovpn_client.crt
echo "</cert>"
echo "<key>"
cat pki/private/$ovpn_client.key
echo "</key>"
} > $ovpn_client.ovpn
An .ovpn file similar to this should be created:
client
dev tun
proto udp
remote example.com 1194
float
resolv-retry infinite
nobind
persist-key
persist-tun
verb 3
cipher AES-256-CBC
auth-nocache
remote-cert-tls server
<ca>
-----BEGIN CERTIFICATE-----
MIIDvTCCAqWgAwIBAgIJANvkOPYA/0TTMA0GCSqGSIb3DQEBBQUAMHUxCzAJBgNV
...
pg==
-----END CERTIFICATE-----
</ca>
<cert>
-----BEGIN CERTIFICATE-----
MIID4jCCAsqgAwIBAgIJANvkOPYA/0TVMA0GCSqGSIb3DQEBBQUAMHUxCzAJBgNV
...
ULQvAqMyg3hvUoMU2PUwvh0wCUoKjZ7ewv3kXYZZ6KJcGJ+B610=
-----END CERTIFICATE-----
</cert>
<key>
-----BEGIN ENCRYPTED PRIVATE KEY-----
MIIFDjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIcjdGY+dkxccCAggA
...
xIk=
-----END ENCRYPTED PRIVATE KEY-----
</key>
Import the .ovpn file to the OpenVPN client software. Use the clients private key password when connecting to the server.
Lock up the safe storage if all CA work is done.
Revoke certificates
Sometimes certificates needs to be revoked. Typical reasons for wanting to revoke a certificate include:
- The private key associated with the certificate is compromised or stolen.
- The user of an encrypted private key forgets the password on the key.
- You want to terminate a VPN user’s access.
First Open the safe storage, if needed.
NOTE Replace client1 with the name of your certificate
cd ~/OpenVPN-CA/safe-storage
./easyrsa revoke client1
Rebuild the crl file and copy it to the OpenVPN server.
./easyrsa gen-crl
scp pki/crl.pem admin@192.168.0.1:/config/auth/
There is no need to restart the OpenVPN server, because the uploaded crl file will be used at the next connection attempt.
Lock up the safe storage if all CA work is done.
Safe storage usage
Open safe storage
Before the CA can be used, the safe storage needs to opened.
cd ~/OpenVPN-CA
sudo cryptsetup open --type luks secret-device.img secret-device
sudo mount /dev/mapper/secret-device safe-storage
Lock up safe storage
When all certificates are created, the safe storage can be locked up (and optionally stored in a safe place).
cd ~/OpenVPN-CA
sudo umount safe-storage
sudo cryptsetup close secret-device