Edgerouter Security, Part5

OpenVPN

Now i want to setup an OpenVPN server on my Edgerouter. I am feeling pretty nervous about just securing this with a username and password. I want to be able to connect to my network from a PC I don’t trust 100%. The way to do this is by using a combination of a certificate and a google authenticator passcode. In this way, if that PC gets compromised, the attacker would also need my phone to authenticate to my edgerouter! This step requires that Google Authenticator has already been installed. It will be if you followed this series on Edgerouter Security.

Create a user for logging into our OpenVPN server

First we 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 superlongsecretpassword=5
set system login user openvpn-user level operator
commit

Now we set up google authenticator for our user. All the answers are the same as the setup for our SSH user.

sudo su -c "google-authenticator --label=\"A good name for the openvpn user\"" openvpn-user

The private key should be scanned or typed into your phone.

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

First step is to setup PAM to do Google Authentication for OpenVPN

cd /etc/pam.d
cp common-account openvpn
echo "auth required pam_google_authenticator.so" >> openvpn

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 internal management network (192.168.10.0/24).  The last config line enables Google Authenticator authentication, and it works because we already install Google Authenticator for SSH access.

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.10.0/24
set interfaces openvpn vtun0 server name-server 192.168.200.1
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"
set interfaces openvpn vtun0 openvpn-option '--plugin /usr/lib/openvpn/openvpn-auth-pam.so openvpn'
commit

Now we need to punch a hole in our WAN interface to allow incoming OpenVPN traffic.

set firewall name WAN_LOCAL rule 20 action accept
set firewall name WAN_LOCAL rule 20 description 'Allow OpenVPN'
set firewall name WAN_LOCAL rule 20 destination port 1194
set firewall name WAN_LOCAL rule 20 protocol udp

We also need to listen to DNS queries on the OpenVPN interface

set service dns forwarding listen-on vtun0

Creating an .ovpn file for our client

On our client we 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 the Edgerouter. I got these three pieces of information with these commands listed in correct order

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

The finalized file can now be distributed to the client device securely. Eg. I used itunes and a usb cable to transfer the .ovpn file to my iphone. Never use email or dropbox to transfer this file!

What do we have?

Now we can connect to our Edgerouter with OpenVPN. It’s secured with a certificate, and you need a Google Authenticator to generate the passphrases to authenticate. The performance on OpenVPN is about 7 Mbits which is enough for my purposes.

9 thoughts to “Edgerouter Security, Part5”

  1. Excellent instructions. I am wondering about Google authenticator. I don’t need it for my devices, can I just eliminate those lines from your instructions to get the openvpn server running with just username and password? Any help would be great.

    1. You should be able to do that if you skip this config-line:
      set interfaces openvpn vtun0 openvpn-option '--plugin /usr/lib/openvpn/openvpn-auth-pam.so openvpn'

  2. Great guide
    I has to add “-s /bin/bash” to sudo su -c “google-authenticator –label=\”A good name for the openvpn user\”” openvpn-user

    or i will get “This account is currently not available” because operator use another shell

  3. Just one question. the portforward there is on the server can not be reached from vpn. i can contact when i use the local ip. but on lan i can also use domain.com but it dont work on vpn ?

    Do you have a solution ?

  4. Hi there – great instructions! I have configured everything following your steps, but alas, after pushing the .ovpn file onto my iPhone, I am unable to connect to my router… it times out. In the logs, it appears to be attempting to connect to the correct WAN IP address. I get EVENT: CONNECTION_TIMEOUT [ERR] and then it disconnects.

    Any thoughts on what could be wrong?

    1. Be sure you are not on your internal network/wifi. That could be the cause.
      Try to portscan yourself from the outside to see if your vpn server is listening

  5. Thanks for guide, it helps!

    but I made big problem with firewall setting… I used it exactly as it is written but rule 20 have existed already … please write note, that you should find your last firewall rule.

    Thx! It will save severals hours.

    here is command to list yours rules:
    show firewall name WAN_LOCAL

Leave a Reply

Your email address will not be published. Required fields are marked *