OpenVPN on VyOS

OpenVPN Client/Server Implemenation

==== key signing ====
You can host the certificate authority on the vyos device itself. This is obviously not as secure as hosting it on a separate system. If someone was to get into the vyos they would have access to all your keys and would be able to sign new keys against the CA. Nonetheless, it is convenient and secure-enough for many sites. This is how it can be done.
From the VyOS, copy the easy-rsa directory into /config, where it won’t get lost on an upgrade.

cp -rv /usr/share/doc/openvpn/examples/easy-rsa/2.0/ /config/easy-rsa2
vi /config/easy-rsa2/vars

edit the options at the bottom of /config/easy-rsa2/vars to personalize them. Increasing KEY_SIZE to 2048 is recommended. Also, you can increase the certificate authority and key expiration. These are the defaults:

 ...
# Increase this to 2048 if you
# are paranoid.  This will slow
# down TLS negotiation performance
# as well as the one-time DH parms
# generation process.
export KEY_SIZE=1024

# In how many days should the root CA key expire?
export CA_EXPIRE=3650

# In how many days should certificates expire?
export KEY_EXPIRE=3650

export KEY_COUNTRY="US"
export KEY_PROVINCE="CA"
export KEY_CITY="SanFrancisco"
export KEY_ORG="Fort-Funston"
export KEY_EMAIL="me@myhost.mydomain"

now load the variables

$ cd /config/easy-rsa2/
$ source ./vars

start fresh in case there is something old lingering around in there. This will delete all keys, etc.

$ ./clean-all

Build the certificate authority files

$ ./build-ca

Build the diffie-hellman key exchange

$ ./build-dh

Build the key for the server

$ ./build-key-server js-server

Copy the certs and keys into /config/auth

sudo cp /config/easy-rsa2/keys/ca.crt /config/auth/
sudo cp /config/easy-rsa2/keys/dh1024.pem /config/auth/
sudo cp /config/easy-rsa2/keys/js-server.key /config/auth/
sudo cp /config/easy-rsa2/keys/js-server.crt /config/auth/

Now you can build the key for the client and distribute to them
use ./build-key to generate a certificate that will connect to the vpn without a pass-phrase and ./build-key-pass if you want the user to enter a pass-phrase before connecting. ./build-key-pass is more secure in case someone steals your certificate and key they will still need to enter a password to connect.

$ ./build-key jimmy

answer all questions accordingly and be sure to answer yes to “Sign the certificate?” the “1 out of 1 certificate requests certified, commit?”
Now copy the keys and certs and create a config for Jimmy to remote in with. This is how I do it.
first make a directory for the client in /config/easy-rsa2/keys

cd /config/easy-rsa2/keys
mkdir jimmy
cp jimmy* jimmy/
cp ca.crt jimmy/

create a client config with your favorite text editor,

vi jimmy/jsvpnserver.ovpn

and add the following

client
proto udp
remote-cert-tls server
verb 2
dev tun0
cert jimmy.crt
key jimmy.key
ca ca.crt
remote [vpn-server host or ip] 1194

From your local computer download the config directory (jimmy) from the vpn server

$ scp -r vyos@10.101.101.1:/config/easy-rsa2/keys/jimmy .

this copies the jimmy directory into the current directory on your computer (the period designates current directory). If your on MS Windows you will need to use cygwin or putty-scp to do this. Also, if using MS Windows you will need to run unix2dos on those files
from your computer where you downloaded the jimmy folder to.

unix2dos jimmy/*

I wrote a script to do all this for you -> http://jasonschaefer.com/stuff/easyrsa-user-setup-vyos.sh.txt

Setting up the OpenVPN Server

The server subnet needs to be a different subnet from your LAN. Set it to something unique that will be unlikely on any remote networks your clients will be on.
The “–push route 10.101.101.0 255.255.255.0” needs to be changed to the subnet on the LAN of the router. The one you will VPN in to access.

set interfaces openvpn vtun0 mode server
set interfaces openvpn vtun0 server subnet 10.206.109.0/24
set interfaces openvpn vtun0 server name-server 10.101.101.1
set interfaces openvpn vtun0 server domain-name jasonschaefer.com
set interfaces openvpn vtun0 server push-route 10.101.101.0/24
set service dns forwarding listen-on vtun0
set interfaces openvpn vtun0 tls cert-file /config/auth/js-server.crt
set interfaces openvpn vtun0 tls key-file /config/auth/js-server.key
set interfaces openvpn vtun0 tls ca-cert-file /config/auth/ca.crt
set interfaces openvpn vtun0 tls dh-file /config/auth/dh1024.pem

#Set the firewall to allow openvpn through

set firewall name wan-local rule 40 action accept
set firewall name wan-local rule 40 destination port openvpn
set firewall name wan-local rule 40 protocol udp
commit
save

Thats it! Your done!

STATIC CLIENT ADDRESS

The static ip address for each client is done with this command:

set interfaces openvpn vtun0 server client leroy ip 10.206.109.123

The name “leroy” is the Common Name of the certificate. After this is committed leroy will receive .123 on his laptop each time he connects to the vpn.

ROUTING VARIOUS LAN’s OVER VPN

The routing between a remote LAN (iroute) is done like this:

set interfaces openvpn vtun0 server client leroyhome ip 10.206.109.0.3
set interfaces openvpn vtun0 server client leroyhome subnet 10.101.103.0/24

The “subnet” option is openvpn’s internal route (iroute) function. This tells openvpn what the remote LAN subnet is. In this example, 10.101.103.0/24 is leroys house LAN.

Now you can add a static route in order to route to this remote LAN.

set protocols static route 10.101.103.0/24 next-hop 10.206.109.1

10.206.109.1 is the openvpn routers interface vtun0 ip address.

If your designing a network with multiple remote sites its convenient to make their addresses contiguous and route to them all with a single route.

10.101.101.0/24 (my house)
10.101.102.0/24 (geoff’s house)
10.101.103.0/24 (leroy’s house)

I use subnetcalc to figure out the host ranges

$ subnetcalc 10.101.101.0/22
  Host Range    = { 10.101.100.1 - 10.101.103.254 }
  - 10.101.101.0 is a HOST address in 10.101.100.0/22

So, a slash 22 cover from .100-.103, that’s perfect for our small network.

set protocols static route 10.101.100.0/22 next-hop 10.206.109.1

and you need to push this route to all the clients

set interfaces openvpn vtun0 server push-route 10.101.100.0/22

SITE TO SITE VPN

basic instructions:

generate the passive key for head office from inside the easyrsa folder

source ./vars
./build-key-server site2site_server-passive
scp keys/site2site_server-passive.* user@vpn-server-passive-host:/config/auth/

#active key for branch office, this side initiates the vpn handshakes

./build-key site2site_active
scp keys/site2site_active.* user@vpn-server-active-host:/config/auth/

active site files in /config/auth/
ca.crt,
site2site_active.key,
site2site_active.crt

passive site files in /config/auth/
ca.crt,
site2site_server-passive.key,
site2site_server-passive.crt,
dh1024.pem

==================

#site to site openvpn

set interfaces openvpn vtun9
set interfaces openvpn vtun9 local-address 172.16.9.[1 | 2]
set interfaces openvpn vtun9 remote-address 172.16.9.[1 | 2]
set interfaces openvpn vtun9 remote-host [remote-vpn-host]

#standard openvpn port is 1194, best used for client/server mode. prevents ovpn config from needing port setting

set interfaces openvpn vtun9 local-port 1195
set interfaces openvpn vtun9 remote-port 1195
set interfaces openvpn vtun9 mode site-to-site
set interfaces openvpn vtun9 tls ca-cert-file /root/ca.crt
#the passive site cert/key needs to be signed as a server!
set interfaces openvpn vtun9 tls key-file /root/[passive.key | active.key ]
set interfaces openvpn vtun9 tls cert-file /root/[passive.crt | active.crt]
set interfaces openvpn vtun9 tls role [active | passive]
#dh1024.pem is required on passive host only!
set interfaces openvpn vtun9 tls dh-file /root/dh1024.pem
commit;save

#open firewall for openvpn

set firewall name wan-local rule 20 action accept
set firewall name wan-local rule 20 destination port 1195
set firewall name wan-local rule 20 protocol tcp_udp

#set static routes to networks on other side of vpn, if any

set protocols static route 192.168.7.0/24 next-hop 172.16.9.[1 | 2]
set protocols static route 192.168.8.0/24 next-hop 172.16.9.[1 | 2]
commit;save

DYNAMIC DNS

How to reach your vpn server and avoid using a static ip. We will be using afraid.org to automatically update a hostname’s A record with the public ip of your Vyos VPN server.

You will need to register for an account at https://freedns.afraid.org. Then create a subdomain, for this example it will be myvpnserver.mooo.com. Go to the “Dynamic DNS” section and copy the “Direct URL”.

Create a script under /config/scripts on your Vyos.
vi /config/scripts/myvpnserver.mooo.com.sh

#!/bin/bash
/usr/bin/curl -k [paste your direct url here]

Make it executable
chmod 755 /config/scripts/myvpnserver.mooo.com.sh

Now tell Vyos to run this with cron.
set system task-scheduler task dynamicDNS executable path /config/scripts/myvpnserver.mooo.com.sh
set system task-scheduler task dynamicDNS interval 15m

REVOKE KEYS ON VYOS

vyos@router:~$ cd /config/easy-rsa2/

vyos@router:/config/easy-rsa2$ ./revoke-full jimmy

Using configuration from /config/easy-rsa2/openssl.cnf
Revoking Certificate 0E.
Data Base Updated
Using configuration from /config/easy-rsa2/openssl.cnf
jimmy.crt: /C=US/ST=NM/L=SantaFe/O=Blah/CN=jimmy/emailAddress=jimmy@localhost.local
error 23 at 0 depth lookup:certificate revoked

The error 23 at 0 … is normal and expected.

Now copy the updated CRL (certificate revocation list) to /config/auth
vyos@router:/config/easy-rsa2$ cp keys/crl.pem /config/auth/

If this is the first revocation you need to add it to the config as well:

vyos@router:~$ configure
vyos@router# set interfaces openvpn vtun0 tls crl-file /config/auth/crl.pem
vyos@router# save; commit; exit
Saving configuration to ‘/config/config.boot’…
Done
No configuration changes to commit
exit

VERIFY REVOKED CERTIFICATES

You can verify the revoked keys with the openssl command
vyos@router:~$ openssl crl -in /config/auth/crl.pem -text

Revoked Certificates:
    Serial Number: 08
        Revocation Date: Jan 30 00:19:24 2016 GMT
    Serial Number: 0E
        Revocation Date: Jul 13 22:51:50 2016 GMT

In the above example keys 08 and 0E have been revoked
vyos@router:~$ cat /config/easy-rsa2/keys/index.txt

V	230804225528Z		        02	unknown	/C=US/ST=NM/L=SantaFe/O=SITC/CN=jason/emailAddress=jason@local
R	230806213443Z	160130001924Z	08	unknown	/C=US/ST=NM/L=SantaFe/O=Blah/CN=john/emailAddress=john@localhost
R	260711225142Z	160713225150Z	0E	unknown	/C=US/ST=NM/L=SantaFe/O=Blah/CN=jimmy/emailAddress=jimmy@localhost.local

From this file index.txt, you can ascertain which serial numbers belong to which users!


Comments

21 responses to “OpenVPN on VyOS”

  1. Hi,

    I have gotten everything in this configuration to work in regards to the client-server configuration… except i ran into what might be a serious bug, I’m not sure yet… but it appears the the Open VPN configuration does NOT successfully push the route my host machine. I tested this using the following configuration:

    set interfaces openvpn vtun0 mode server
    set interfaces openvpn vtun0 server subnet 10.206.109.0/24
    set interfaces openvpn vtun0 server name-server 8.8.8.8
    set interfaces openvpn vtun0 server name-server 8.8.4.4
    set interfaces openvpn vtun0 server name-server 208.67.222.222
    set interfaces openvpn vtun0 server name-server 208.67.220.22
    set interfaces openvpn vtun0 server domain-name test.com
    set interfaces openvpn vtun0 server push-route 10.10.10.0/24
    set service dns forwarding listen-on vtun0
    set interfaces openvpn vtun0 tls cert-file /config/auth/js-server.crt
    set interfaces openvpn vtun0 tls key-file /config/auth/js-server.key
    set interfaces openvpn vtun0 tls ca-cert-file /config/auth/ca.crt
    set interfaces openvpn vtun0 tls dh-file /config/auth/dh1024.pem

    zone based firewalling is effect, however the problem is definitely due to the route-pushing feature in OpenVPN… is there something bugged? I do get a successful OpenVPN connection to the control plane (local) zone of the firewall no problems, I even get assigned an appropriate IP address from the VPN pool that is generated automatically. I noticed the the problem was occuring pretty quickly because my rules are all in place, but as soon as I couldn’t ping my test windows 7 machine on the LAN side of the firewall from the OpenVPN connection I knew it wasn’t due to rules because I have defined a default-accept for testing purposes from LAN to VPN and VPN to LAN.

    I ran a route print in windows 7 and noticed that my windows 7 test host machine did NOT receive the route to 10.10.10.0/24. as soon as I manually entered the route using the following command:

    route add 10.10.10.0 mask 255.255.255.0 10.206.109.1 metric 1 if 27

    I then was able to communicate with my test host on the VPN connection to the LAN and from the LAN to the VPN client… so… its routing issue… I’m thinking about running a wireshark capture to see if any routes are indeed sent over to my machine or not… although I feel like that would be impossible or darn near very difficult to decipher given the data is encrypted by the certificate :(…

    any insights into if OpenVPN on the Vyos system has issues or not would be appreciated! thank you!

  2. Hi,

    just checked the OpenVPN log… this is interesting:

    Thu Dec 25 00:04:50 2014 ROUTE: route addition failed using CreateIpForwardEntry: Access is denied. [status=5 if_index=27]
    Thu Dec 25 00:04:50 2014 env_block: add PATH=C:\Windows\System32;C:\WINDOWS;C:\WINDOWS\System32\Wbem
    Thu Dec 25 00:04:50 2014 ERROR: Windows route add command failed [adaptive]: returned error code 1

    I’ll investigate and report back.

  3. ran OpenVPN as an administrator, derped this, thats all it took and solved the issue. thank you

  4. Hi Max

    Thanks for your troubleshooting comments about running as administrator. This will be helpful for others. A common step to overlook.
    On a related note I have updated my post about installing openvpn client on windows. I now use a batch script instead of the gui. Its much more reliable. Just be sure to run it as admin ;-)
    http://jasonschaefer.com/installing-openvpn-on-windows/

    Jason

  5. trick.ster Avatar
    trick.ster

    seems command is wrong:

    set interfaces openvpn vtun0 server subnet 10.206.109.0/24

    must be:

    set interfaces openvpn vtun0 server subnet 10.101.101.0/24

    because “name-server 10.101.101.1” and “push-route 10.101.101.0/24”

  6. No, it is correct. 10.206.109.0/24 is the subnet of the openvpn interface. This is openvpn’s subnet topology and is the recommended topology.

  7. Ed Ayvazyan Avatar
    Ed Ayvazyan

    Hi!
    I’ve configured Openvpn on VyOS and it works perfectly with most clients, but not with too old 1.0.3 windows clients. They need the topology net30 option, however current release of openvpn (2.1.3-2+squeeze3) running on VyOS seems not to support this topology.
    Did anyone face a similar issue? Has anybody found a solution?

  8. Hi Ed
    net30 has been deprecated. Your only solution is to upgrade your clients. Is that not an option for some reason?

  9. Can we just toss a .conf file into the /etc/openvpn folder?

    I have an issue now where my far end point is on a dynamic IP and I really would like to set the remote address to resolve via DNS. I’ve not found anything on the internet that has helped with this problem on VyOS.

  10. Hi Byrn

    >Can we just toss a .conf file into the /etc/openvpn folder?

    The openvpn config is built from the configuration (/config/config.boot) and cannot be mixed. You could setup openvpn server yourself and not use the configuration. After all VyOS is Debian based. Although, you would lose out on the nifty configuration management.

    >I have an issue now where my far end point is on a dynamic IP and I really would like to set the remote address to resolve via DNS.

    I will add a little how-to on my recommended way to do this. Over the years I have learned to avoid static ip’s. They are mostly unnecessary. ISP’s seem to use it as an opportunity to shaft their customers (Comcast is the worst about this). Anyhow, I use afraid.org dynamic dns. Very flexible and reliable service. I even use my own domain with this service!

  11. Great guide, straight to the point , thanks.

    However, I had an issue on VyOs 1.1.5, it wasn’t working.

    I had the following message in logs :
    “openvpn Connection refused (code=111)”

    I removed on bot ends the custom ports , i.E.

    interfaces openvpn vtun9 local-port 1195
    interfaces openvpn vtun9 remote-port 1195

    and then it worked.

    Just in case anyone has the same issue

  12. @jfl
    Thanks!
    It sounds like one end of your site-to-site vpn didn’t have the port set to 1195 or the firewall wasn’t allowing it through. I like to get everything working on a router and then apply firewall rules. Can save a lot of headache.
    The non-standard port is needed if you already have a openvpn server setup on the standard port of 1194. If you only need one openvpn you should use the default openvpn port of 1194 and forgo the non-standard ports.

  13. […] Another good guide based on VyOS can be found here, it uses an alternative method to generate keys and also talks how to configure dynamic IP services. […]

  14. Hi, I tried setting up the client server config. everything went will except I cannot surf the web, cannot ping the gateway seems like I have not route.
    It would be helpful if you elaborated on your network layout.

    Thanks

  15. @Sash – Maybe you could be more specific? Your comment gives me zero information to respond to. From my experience, I would guess that you need to run openvpn on your client computer as administrator/root user. Otherwise routes and such won’t get setup. Just a guess, write back with more specific questions. Tnx.

  16. Could you please provide steps to create 2048 bit encryption keys? The default steps create 1024 only.

    thank you

  17. @Polk
    Thanks, I expanded on this.
    Its in the vars file (/config/easy-rsa2/vars)

  18. Hello Jason,

    Do you know how to configure multiple connections with the same key/account in client/server mode ?

    Regards,
    Kaloyan

  19. @Kaloyan
    From the openvpn man page:
    –duplicate-cn
    Allow multiple clients with the same common name to
    concurrently connect. In the absence of this option, OpenVPN will
    disconnect a client instance upon connection of a new client having the
    same common name.

    Try this and let us know if it worked: set interfaces openvpn vtun0 openvpn-option –duplicate-cn

  20. smiroshn Avatar
    smiroshn

    for recent VyOS release please update your zip’s script section to:

    if [ ! -x /usr/bin/zip ];then
    echo -e “\n zip not found.. To install zip add the following to /etc/apt/sources.list \n
    “deb http://archive.debian.org/debian squeeze main” and \n
    “deb http://archive.debian.org/debian squeeze-lts main” \n
    add “Acquire::Check-Valid-Until false;” to /etc/apt/apt.conf \n
    sudo apt-get udpate && apt-get install zip && apt-get install unzip \n
    if on vyatta, uncomment the line in sources.list when done”

    squeeze (debian 6) is archived

  21. @smiroshn
    Spasibo. I have updated the script to reflect your useful changes.

Leave a Reply

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