Skip to main content

As many of you that has an homelab at home, that might be the need to connect to it while you are not at home, maybe for testing quickly one thing, maybe because you miss your homelab so much so you want to login and doing some stuff.

The entire homelab network is managed through an Ubiquity Edgerouter-X, this little guy was needed for me for managing the network with a physical simple router, and also because with (a the moment”) a single ESXi host was though to work with NSX-T and BGP peering. So in the end I bought it and configure my entire homelab networks. And to be honest I’m really happy with it.

The need now is how to connect remotely to my homelab when I’m out, so I started looking at some VPN configuration and I found that the Edgerouter-x is supporting OpenVPN so why not to try it.

N.B. Openvpn server is only supported via CLI ONLY so there is no way to configure it via EdgeMAX UI.

So let’s start configuring OpenVPN on EdgeRouter-x.

Create a user for logging into OpenVPN server

First you need to create a user for our OpenVPN connections. Even though we give it a long secret password, this is never used for authentication, it’s just there to prevent brute force attacks via SSH or the webinterface.

configure
set system login user openvpn-user authentication plaintext-password
set system login user openvpn-user level operator
commit

Create a CA authority, a server certificate and a user certificate

Our first job is to make a directory where all the certificates will be. It’s important to save it under /config, because this directory will survive a firmware update. All certificate commands are run with /config/openvpn as the current directory.

sudo -i
mkdir /config/openvpn
cd /config/openvpn

Now we create a certificate authority that will be signing all future certificates on the Edgerouter.

/usr/lib/ssl/misc/CA.sh -newca
CA certificate filename (or enter to create): <enter>
Enter PEM pass phrase: <CApassword>
Verifying - Enter PEM pass phrase: <CApassword>
Country Name (2 letter code) [AU]: DK
State or Province Name (full name) [Some-State]: Some-State
Locality Name (eg, city) []: Some City
Organization Name (eg, company) [Internet Widgits Pty Ltd]: Some Corp
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []: My CA
Email Address []:
Please enter the following 'extra' attributes to be sent with your certificate request
A challenge password []:
An optional company name []:
Enter pass phrase for ./demoCA/private/./cakey.pem: <CApassword>

A certification authority is now created in /config/openvpn/demoCA

Now we need to create a server certificate for the OpenVPN server.

/usr/lib/ssl/misc/CA.sh -newreq
Generating a 2048 bit RSA private key
Enter PEM pass phrase: <tempserverkeypassphrase>
Verifying - Enter PEM pass phrase: <tempserverkeypassphrase>
Country Name (2 letter code) [AU]: DK
State or Province Name (full name) [Some-State]: Some State
Locality Name (eg, city) []: Some City
Organization Name (eg, company) [Internet Widgits Pty Ltd]: Some Corp
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []: my.domain.org
Email Address []:
A challenge password []:
An optional company name []:

Then we sign the server certificate with our CA

/usr/lib/ssl/misc/CA.sh -sign
Enter pass phrase for ./demoCA/private/cakey.pem: <CApassword>
Sign the certificate? [y/n]: y
1 out of 1 certificate requests certified, commit? [y/n]: y

Now we rename the files to something recognizable and then we decrypt the server key so that OpenVPN can use it without prompting for a passphrase

mv newcert.pem server.pem
mv newkey.pem server.key
rm newreq.pem
openssl rsa -in server.key -out server-decrypted.key
Enter pass phrase for /config/auth/server.key: <tempserverkeypassphrase>

Now we create the Diffie Hellman parameters for perfect forward secrecy. This can take a looooooooooong time…. First time it took about 1,5 hours, second time it took 20 minutes! If you can’t wait you can decrease the keylength to 1024, but that is not recommended.

openssl dhparam -out dh2048.pem -2 2048

Now we generate the user certificate for the user that will connect to our openvpn server

/usr/lib/ssl/misc/CA.sh -newreq
Enter PEM pass phrase: <tempusercertpass>
Verifying - Enter PEM pass phrase: <tempusercertpass>
Country Name (2 letter code) [AU]: DK
State or Province Name (full name) [Some-State]: Some State
Locality Name (eg, city) []: Some City
Organization Name (eg, company) [Internet Widgits Pty Ltd]: Some Corp
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []: openvpn-user
Email Address []:
A challenge password []:
An optional company name []:

Now we sign the new user certificate with our CA

/usr/lib/ssl/misc/CA.sh -sign
Enter pass phrase for ./demoCA/private/cakey.pem: <CApassword>
Sign the certificate? [y/n]: y
1 out of 1 certificate requests certified, commit? [y/n]: y

Now we rename the files to something recognizable and then we decrypt the user-certificate key so that we later can transfer it to our device

mv newcert.pem openvpn-user.pem
mv newkey.pem openvpn-user.key
rm newreq.pem
openssl rsa -in openvpn-user.key -out openvpn-user-decrypted.key
Enter pass phrase for /config/auth/openvpn-user.key: <tempusercertpass>

Setting up the OpenVPN server

Now that all certificates are in place, we need to setup an openVPN interface. I chose to set it up with UDP on port 1194 which is standard. I created a special subnet for the interface (192.168.200.0/24) and made it possible for clients to connect to my home management network (192.168.0.0/24).

exit #exit out of our previous sudo session
set interfaces openvpn vtun0
set interfaces openvpn vtun0 description "OpenVPN server"
set interfaces openvpn vtun0 mode server
set interfaces openvpn vtun0 encryption aes256
set interfaces openvpn vtun0 hash sha256
set interfaces openvpn vtun0 server subnet 192.168.200.0/24
set interfaces openvpn vtun0 server push-route 192.168.0.0/24
set interfaces openvpn vtun0 server name-server 192.168.1.9
set interfaces openvpn vtun0 tls ca-cert-file /config/openvpn/demoCA/cacert.pem
set interfaces openvpn vtun0 tls cert-file /config/openvpn/server.pem
set interfaces openvpn vtun0 tls key-file /config/openvpn/server-decrypted.key
set interfaces openvpn vtun0 tls dh-file /config/openvpn/dh2048.pem
set interfaces openvpn vtun0 openvpn-option "--port 1194"
set interfaces openvpn vtun0 openvpn-option --tls-server
set interfaces openvpn vtun0 openvpn-option "--comp-lzo yes"
set interfaces openvpn vtun0 openvpn-option --persist-key
set interfaces openvpn vtun0 openvpn-option --persist-tun
set interfaces openvpn vtun0 openvpn-option "--keepalive 10 120"
set interfaces openvpn vtun0 openvpn-option "--user nobody"
set interfaces openvpn vtun0 openvpn-option "--group nogroup"
commit

Remember also to put this line for listed the DNS queries on the OpenVPN interface

set service dns forwarding listen-on vtun0

Creating an .ovpn file for our client

On the client you need to create a .ovpn file that looks like this:

client
dev tun
proto udp
remote <FQDN or WANIP of the Edgerouter> 1194
cipher AES-256-CBC
auth SHA256
resolv-retry infinite
redirect-gateway def1
nobind
comp-lzo yes
persist-key
persist-tun
user nobody
group nogroup
verb 3
setenv ALLOW_PASSWORD_SAVE 0
auth-user-pass

<ca>
-----BEGIN CERTIFICATE-----
-----END CERTIFICATE-----

</ca>

<cert>
-----BEGIN CERTIFICATE-----
-----END CERTIFICATE-----

</cert>

<key>
-----BEGIN RSA PRIVATE KEY-----
-----END RSA PRIVATE KEY-----

</key>

The three certificate sections of the .ovpn file should be filled out with the certificate information from your Edgerouter. You can got these three pieces of information with the command here below:

cat /config/openvpn/demoCA/cacert.pem
cat /config/openvpn/openvpn-user.pem
cat /config/openvpn/openvpn-user-decrypted.key

This will finalize all the needed configuration, remember to eventually do the portforwarding for port UDP 1194 on your Home Router to let the traffic arrive to the OpenVPN server and then just try it.

Enjoy your VPN connection to your homelab!

Leave a Reply

Giovanni Dominoni's Tech Blog