Installing OpenVPN on Ubuntu Server 12.04 or 14.04 using TAP

This article will guide you in a basic OpenVPN installation on an Ubuntu server running 12.04 or 14.04 using a TAP device on the server.

The TAP solution is useful if you want the remote VPN users to use the same IP scheme that is in use on the local subnet. Very useful if you don’t have a gateway/router in the local subnet that can do static routes since, to the internal hosts, the traffic will seem to originate from a locally connected device on the same subnet. The big downside to this is that Android clients as of 4.2.2 don’t support TAP based tunnels. However, for PC/MAC/Linux clients, it works just fine.

OpenVPN has a few methods of authentication. Out of the box, OpenVPN relies on certificate based auth. However, with a recompiled client, you can also use Id/password authentication as well providing 2 factor auth into your network (something you have = the cert, something you know = the password).

Before we begin, lets get the installation of the pre-reqs done.

apt-get install bridge-utils openvpn libssl-dev openssl

On the Ubuntu Server, we need to start by configuring the bridge adapter with Bridge Utilities. OpenVPN requires this ‘virtual interface’ when setting up the tap interface it needs to pass traffic into the internal network. This is done by modifying the interfaces file.

nano /etc/network/interfaces

When editing this file, you need to remove or comment out the original eth port settings and replace with what you see below. This creates a new br0 interface and allows eth0 to essentially communicate across it (hence the label ‘bridge’). You will, of course, adjust the file for your specific subnet scheme.

 
# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

# The loopback network interface
auto lo
iface lo inet loopback

# The primary network interface
auto eth0

#iface eth0 inet static
#       address 192.168.1.15
#       netmask 255.255.255.0
#       network 192.168.1.0
#       broadcast 192.168.1.255
#       gateway 192.168.1.1
#        # dns-* options are implemented by the resolvconf package, if installed
#       dns-nameservers 192.168.1.15
#       dns-search myhome.local

auto br0
iface br0 inet static
        address 192.168.1.15
        netmask 255.255.255.0
        gateway 192.168.1.1
        network 192.168.1.0
        broadcast 192.168.1.255
        bridge_ports eth0
#### NOTE: If you are running OpenVPN in a virtual machine, then uncomment these lines:
# bridge_fd 9
# bridge_hello 2
# bridge_maxage 12
# bridge_stp off

iface eth0 inet manual
        up ifconfig $IFACE 0.0.0.0 up
        up ip link set $IFACE promisc on
        down ip link set $IFACE promisc off
        down ifconfig $IFACE down

Next, we need to allow IPv4 forwarding so the server can send out packets on the VPN’s behalf.

nano /etc/sysctl.conf

Uncomment the line net.ipv4.ip_forward=1

Restart networking and run ‘sysctl -p’ for the changes to take effect. Or just restart the server.

Create Server Keys
We need to create the server keys and client keys that we need for the OpenVPN server and the eventual client. Easy-RSA will be used to generate the items we need.

If you are on 12.04 Create the easy-rsa folder and copy the sample files into it.

sudo mkdir /etc/openvpn/easy-rsa/
sudo cp -R /usr/share/doc/openvpn/examples/easy-rsa/2.0/* /etc/openvpn/easy-rsa/
sudo chown -R $USER /etc/openvpn/easy-rsa/

If you are on 14.04, easy-rsa is an installed application with the utilities built in to create the needed directory.

 
apt-get install easy-rsa
make-cadir /etc/openvpn/easy-rsa

Edit the vars file and edit the following items for your needs. These items are located near the bottom of the vars file.

sudo nano /etc/openvpn/easy-rsa/vars

export KEY_COUNTRY="US"
export KEY_PROVINCE="NY"
export KEY_CITY="New York City"
export KEY_ORG="Queens"
export KEY_EMAIL="me@myhost.mydomain"

Next step is to generate the Server Keys

cd /etc/openvpn/easy-rsa/
source vars
./clean-all
./build-dh
./pkitool --initca
./pkitool --server server
cd keys
openvpn --genkey --secret ta.key

Note: if you get an error on the command “./pkitool –initca”
grep: /etc/openvpn/easy-rsa/openssl.cnf: No such file or directory
pkitool: KEY_CONFIG (set by the ./vars script) is pointing to the wrong
version of openssl.cnf: /etc/openvpn/easy-rsa/openssl.cnf
The correct version should have a comment that says: easy-rsa version 2.x

You are hitting a known bug #998918 https://bugs.launchpad.net/ubuntu/+source/openvpn/+bug/998918.
In a nutshell, openvpn easy-rsa is missing the openssl.cnf file in the package. As a workaround, create a softlink and rerun the pkitool using the following:

    cd /etc/openvpn/easy-rsa/
    ln -s openssl-1.0.0.cnf openssl.cnf     
    ./pkitool --initca

Continue on from there.

Now copy certain keys to the openvpn directory

cp server.crt server.key ca.crt dh1024.pem ta.key /etc/openvpn/

Create Client Certificates

If you are using the default method of authentication, have a client cert per client, then you need to create the cert on the openvpn server for the client. This is done on the server, not on the client because the server’s CA needs to sign the key. Also, the client cert process will prompt you for a client cert password. You need to give this to the client along with the cert.

cd /etc/openvpn/easy-rsa/
source vars
./pkitool client-name

Those commands will create new files int the easy-rsa/keys directory called client-name.crt and client-name.key (client-name.csr is the text request and can be ignored/deleted). These 2 files need to be copied out the client, along with the server ca.crt and the ta.key (the ta.key is used if TLS is enabled in server conf).

/etc/openvpn/ca.crt
/etc/openvpn/ta.key
/etc/openvpn/easy-rsa/keys/client-name.crt
/etc/openvpn/easy-rsa/keys/client-name.key

These files need to be copied to the client and placed in the proper folder. For a linux client, this would usually be the /home/folder for the user. For windows based machines, this would be in the openvpn client install folder where the profiles are stored.

Create OpenVPN Server scripts

We need 2 scripts in the /etc/openvpn directory to manage bringing the server up and down.

nano /etc/openvpn/up.sh

#!/bin/sh
BR=$1
DEV=$2
MTU=$3
/sbin/ifconfig $DEV mtu $MTU promisc up
/sbin/brctl addif $BR $DEV

and

nano /etc/openvpn/down.sh

#!/bin/sh
BR=$1
DEV=$2
/sbin/brctl delif $BR $DEV
/sbin/ifconfig $DEV down

Then we need to make the scripts executable:

 
sudo chmod 755 /etc/openvpn/down.sh
sudo chmod 755 /etc/openvpn/up.sh

Last step is to copy in the sample server config file and edit it to support our config. This sample is a default method using only certificates, but this could be changed to support id/pw instead of user certs (good for large subscription based services), or even 2 factor auth requiring both the cert and the password.

Also note that this config is a bridged network where the client will have an IP right on the target subnet. This sample server config reflects that solution. The Alternative is to create a 2nd subnet for the clients and have the server route between the vpn client and target subnet. For this home solution, that’s overkill, but would be useful in larger setups or where extra security is needed and the remote subnets can be used for access control.

cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz /etc/openvpn/
gzip -d /etc/openvpn/server.conf.gz
nano /etc/openvpn/server.conf

Edit the /etc/openvpn/server.conf file and make the following changes:

Change the following because we don’t want a routed solution.

;dev tap
dev tun
;to
dev tap0
;dev tun

Change the following because bridged networks don’t need it.

server 10.8.0.0 255.255.255.0
;to
;server 10.8.0.0 255.255.255.0

Change the following so OpenVPN can manage the bridged traffic ans assign IPs. (edit these to reflect your scheme).

;server-bridge 10.8.0.4 255.255.255.0 10.8.0.50 10.8.0.100
;to
server-bridge 'server-ip' 'subnetmask' 'DHCP start ip' 'DHCP Ending ip'

Change this so the vpn clients have the correct GW router for all your IP traffic (edit these to reflect your scheme)

;push "route 192.168.10.0 255.255.255.0"
;to
push "route 192.168.1.1 255.255.255.0"

Change this so all your client traffic passes through the VPN.

;push "redirect-gateway def1 bypass-dhcp"
;to
push "redirect-gateway def1 bypass-dhcp"

Change these to 1 of your internal DNS servers if you have 1, otherwise use any public dns you want.

;push "dhcp-option DNS 208.67.222.222"
;push "dhcp-option DNS 208.67.220.220"
;to
push "dhcp-option DNS 208.67.222.222"
push "dhcp-option DNS 208.67.220.220"

Change this to implement tls auth, without a proper file, the initial UDP communication is dropped. It also saves on processor time since it doesn’t have to service bad requests.

;tls-auth ta.key 0 # This file is secret
;to
tls-auth ta.key 0 # This file is secret

Change the following to increase security so the VPN service has restricted access

;user nobody
;group nogroup
;to
user nobody
group nogroup

Add this to the bottom of the file to manage starting and stopping the networking for VPN.

up "/etc/openvpn/up.sh br0"
down "/etc/openvpn/down.sh br0"
script-security 3

With that, you should be able to load the openvpn client, copy in the Ca and user certs and get a connection.

Remember the ta.key is used if ‘tls-auth’ is activated on the server.conf.

33 Responses to Installing OpenVPN on Ubuntu Server 12.04 or 14.04 using TAP

  1. RoseHosting says:

    Great tutorial! Works like a charm.

  2. Frans says:

    Brother, very thanks for your help!!
    This is smooth, clear and concise!!
    Can you explain how about improve the security using extra user/pass for autentication?
    What changes in this tutorial?
    Cheers!

  3. PeterS says:

    Thanks. I have the OpenVPN Server-Bridge working on a Windows 7 Machine. So I though I would give it a whirl on Ubuntu(14.04 fresh install), just to keep learning. I think I’m having a problem with the bridge (interfaces file).
    After editing the file and rebooting br0 works as I can get onto various local sites (music server, router). But no external internet access (google.com). What should I be looking for?
    Thanks again.

    • Chip says:

      The tutorial sets up a static IP address for br0 but it doesn’t indicate that you will need to add DNS name servers. Go back into /etc/network/interfaces and then under iface eth0 add the following
      dns-nameservers x.x.x.x y.y.y.y z.z.z.z

      where x.x.x.x y.y.y.y z.z.z.z are DNS servers, you don’t have to have three you could just use one if you like. for example using googles DNS server
      dns-nameservers 8.8.4.4

  4. Justin says:

    I was just about at my wits end when I stumbled upon your article.
    I’m using Raspbian…

    I initially got a routing VPN setup using this tutorial http://readwrite.com/2014/04/10/raspberry-pi-vpn-tutorial-server-secure-web-browsing#awesm=~oBvYD8BOiTdCQN

    But I needed a bridged VPN for a friends Windows network (needed network neighborhood discovery nonsense)

    Most of the tutorials I found just didn’t seem to get the networking working correctly (if the bridge worked at all the best I got was a bunch of “no route to host” errors)

    When I actually connected, and could see the machines on my LAN Hallelujah began playing in my head!

    You Rock!
    Thanks for this, you have saved me a migraine =)

  5. s0n1q says:

    Thank you for this step-by-step guide. This helped me to resolve issues according to openssl.

  6. Jnlanus says:

    Great tutoria, but i got confuced with the client conf (the only step left out), could you show us how it is set (im using the ovpn client for windows)

  7. Mirek Turon says:

    I guess you should update dh1024.pem to dh2048.pem.

  8. nptphoto says:

    Great instrucions and a great way to get into linux too.. I have searched the internet for days about the lack of internet access but cannot find a solution. I can vpn to my server and can access web based applications (like ownCloud) and other local network machines, but cannot get internet access. As far as I can tell, I have followed the instruction to the letter. Is it iptables? routing? Any help would be greatly appreciated.

    Interestingly my Win7 machine with openvpn works great with internet access.

  9. Turambar says:

    Thank you for your great post! Really helpful.

    On the latest ubuntu version, you’ll need to add ‘tls-server’ into server.conf.

  10. BJ says:

    Thanks for a great article. One correction:

    You wrote:
    up “/etc/openvpn/up.sh br0”
    down “/etc/openvpn/down.sh br0”
    script-security 3

    The correct entry is:
    up “/etc/openvpn/up.sh br0 tap0 1500”
    down “/etc/openvpn/down.sh br0 tap0”
    script-security 3

    Thanks again!

    • ng says:

      can someone help me im getting error mkdir:cannot create directory /etc/openvpn/easy-rsa/keys : permission denied TIA

      • Mike says:

        Check the permissions in the parent directories. Are you creating these using sudo or with an account that has proper permissions?

      • HG says:

        you actually want to sudo -s for the whole setup.
        The permissions of the easy-rsa should not allow everyone to read the keys. specifically the server key. Otherwise anyone can generate certificates for the vpn.

  11. HG says:

    I figured it out, the reason my set-up was not working was because the host OS (ubuntu server) needs to allow the VM network interface to be promiscuous. not only setting it as promiscuous in the guest OS (ubuntu server), but also on the VM configuration.
    Case Closed.
    Thank you for the tutorial !

  12. michael says:

    Thanks for the great tutorial. I have followed it, and the several corrections suggested. When I do “./up.sh” I get an error:

    mtu: ERROR while getting interface flags: No such device
    mtu: ERROR while getting interface flags: No such device
    Incorrect number of arguments for command
    Usage: brctl addif add interface to bridge

    I have likely done something wrong, but cannot yet find it. Any advice from anybody?

    • Mike says:

      If you get an error on the up.sh then you may have the wrong label for the bridge or perhaps you missed something in the bridge config. I would suggest just a simple doublecheck of the conf files and the bridge health.

  13. Fursa says:

    Hey michael,
    I have the same error. have u found a solution?

  14. David says:

    You are the best!! Thank you very much, it works perfectly! 😀

  15. brofist says:

    It Doesn’t work for me.
    i tired setting the br0 from /etc/network/interfaces.
    after restarting the server, the server cannot connect to internet.

  16. Pingback: hot spot – How apply a vpn on a hotspot with a bridge on eth0 and wlan0 | Asking

  17. zaphod says:

    My /etc/network/interfaces file doesnt look anything like what is shown here.
    # This configuration file is auto-generated.
    #
    # WARNING: Do not edit this file, your changes will be lost.
    # Please create/edit /etc/network/interfaces.head and
    # /etc/network/interfaces.tail instead, their contents will be
    # inserted at the beginning and at the end of this file, respectively.
    #
    # NOTE: it is NOT guaranteed that the contents of /etc/network/interfaces.tail
    # will be at the very end of this file.
    #

    # Auto generated lo interface
    auto lo
    iface lo inet loopback

    # Auto generated venet0 interface
    auto venet0
    iface venet0 inet manual
    up ifconfig venet0 up
    up ifconfig venet0 127.0.0.2
    up route add default dev venet0
    down route del default dev venet0
    down ifconfig venet0 down

    iface venet0 inet6 manual
    up ifconfig venet0 add :xxxx:xx:xx::xxxx:xxxx/xxx
    down ifconfig venet0 del xxxx:xxxx:xx:xx::xxxx:xxxx/xxx
    up route -A inet6 add default dev venet0
    down route -A inet6 del default dev venet0

    auto venet0:0
    iface venet0:0 inet static
    address xx.xxx.xxx.xxx
    netmask 255.255.255.255

    I would appreciate any instruction as to how to proceed

    • mike says:

      This looks like the config from a Container, possibly docker? Is that correct? I’ve not setup an openvpn on a container before. I would have to try it myself…. Did you attempt to make the changes to /etc/network/interfaces.tail as indicated?

  18. aprog says:

    Thanks for the post, but more simplest way (takes 5 minutes) is to use pre-shared key, like described here – `http://sysadm.pp.ua/linux/shifrovanie/openvpn-point-to-point.html . Does anyone used OpenSSL for certs and keys generation for OpenVPN ???

    • mike says:

      That article is for a point to point VPN…. in that case, it is acceptable to use a long PSK to secure the tunnel.

      For Road warriors, here are some reasons to use certs with keys over Preshared:
      – Pre-shared key is usually set to something short <20 characters.
      - Certs are per user.... so if you need to revoke 1 user access, it's easy. With a PSK, to change it requires all end users update the profile.
      - True 2 factor when using certs plus id/pw as there are no shared credentials (PSK) between users.

  19. Pingback: Use Steam’s In-Home Streaming across VPN (OpenVPN)? – Internet and Tecnnology Answers for Geeks

  20. Pingback: How apply a vpn (openvpn) on a hotspot with a bridge on eth0 and wlan0 - ubuntutextbook

  21. Pingback: How apply a vpn (openvpn) on a hotspot with a bridge on eth0 and wlan0 - Gomagento2

  22. Lars says:

    Hello,

    i use your Tutorial but it won´t work for me.
    i can´t connect with the client.

    the Clientlog:

    read UDP {ECONNREFUSED]: Connection refused (code=111)

    TLS ERROR: TLS Key negotiation failed to occur within 60 secondes
    TLS ERROR: TLS Handshake failed.

    What i swrong?

    • mike says:

      Seems that the client can’t reach the server on the UDP port you configured. On the server, you can use ‘netstat -lanp’ to look for open ports, make sure your server is listening on the correct one. Make sure you started the openvpn service on the host, and lastly be sure that you have a port forwarded correctly on your perimeter router.

  23. After I originally left a comment I seem to have
    clicked the -Notify me when new comments are added- checkbox
    and now whenever a comment is added I receive
    4 emails with the same comment. There has to be an easy method you can remove
    me from that service? Thanks a lot!

Leave a Reply

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

Solve : *
27 + 7 =