LowEndBox - Cheap VPS, Hosting and Dedicated Server Deals

Getting started with OpenVPN (server)

lowendtutorial

There are various ways to set up a Virtual Private Network (VPN). With the various protocols available to use for VPN and all the software out there, it’s often a spider’s web when you just want to set up a VPN. Well, rest assured: it’s not that hard!

A VPN can be useful for various things, but it’s often used for one of these:

  • Secure connection to an internal office network not accessible from the outside
  • Secure connection to the internet on public wifi (although from the VPN server on it’s back to “default” security)
  • Hiding your real IP/masking your location (for example: using Netflix outside the USA)

I’m going to show you how to set up OpenVPN using a ‘tap’ device. For this, you need a KVM or Xen VPS, or an OpenVZ VPS which supports TAP. If you use an OpenVZ VPS, be sure to enable TAP first from the control panel (it requires a reboot). Other than that, there’s no real system requirements. This guide works on both CentOS and Ubuntu.

I’ve chosen OpenVPN because it’s a well-established open source solution with good client software support. Alternatives I considered were PPTP, which has some security issues, and IPSec/L2TP, which has a more complicated setup and software that has some “quirks”.

Installing software

First of all, let’s install the software.

Ubuntu

sudo apt-get install openvpn

CentOS

sudo yum install openvpn

Enable IPv4 forwarding

IPv4 forwarding needs to be enabled, otherwise packets can’t go from the internet, via the VPS to you. To enable this, open up /etc/sysctl.conf and fine a line that looks like:

net.ipv4.ip_forward=1

The value for this option should be ‘1’. Sometimes it’s commented (Ubuntu) and sometimes it’s a ‘0’ (CentOS). Make sure it looks like the line above, save the file and:

sudo sysctl -p

Which reloads these settings. Alternatively, reboot.

Generating keys

Now the software is installed, let’s start by generating the keys used for encryption and authentication.

First, create directory that’s going to hold the keys and the scripts to generate these keys:

sudo mkdir /etc/openvpn/easy-rsa

Next, download the key generation software:

wget https://github.com/OpenVPN/easy-rsa/archive/v2.2.0.tar.gz -O easy-rsa.tar.gz

Ubuntu already has these scripts included, but CentOS hasn’t. For the sake of simplicity, downloading them from OpenVPN’s github is the best option.

Now, let’s extract the files to the proper directory:

sudo tar xvzf easy-rsa.tar.gz -C /etc/openvpn/easy-rsa –strip-components=3 easy-rsa-2.2.0/easy-rsa/2.0/

And go to that directory:

cd /etc/openvpn/easy-rsa/

OpenVPN uses SSL (certificates) for connection security and authentication. We’re going to generate the certificates required for this:

  • Root key/certificate (ca.key/ca.crt)
  • TLS key (ta.key)
  • Server key/certificate (server.key/server.crt)
  • Client key/certificate (client.key/client.crt)

The data being used for these keys (country, organisation, etc.) can be modified. It doesn’t make a real difference if you change these or not, but it does help recognizing the certificate. You could, optionally, require a certain certificate subject (not covered by this tutorial) for added security.

Open up /etc/openvpn/easy-rsa/vars and look for the following lines:

export KEY_COUNTRY=”US”
export KEY_PROVINCE=”CA”
export KEY_CITY=”SanFrancisco”
export KEY_ORG=”Fort-Funston”
export KEY_EMAIL=mail@host.domain
export KEY_CN=changeme
export KEY_NAME=changeme
export KEY_OU=changeme

You should change these all to reflect your situation. You can remove the duplicate KEY_EMAIL export, as the second one overwrites the first one anyway. You can safely ignore the PK11 variables listed below the above ones in the file.

To be sure we have proper permissions, let’s change the group of the easy-rsa directory to sudo:

sudo chown -R root:sudo .

And set group write permissions, so members of the sudo group can write to it:

sudo chmod g+w .

With these permissions set, we can generate certificates.

First, execute the vars file you’ve just edited to all the vars are available in the environment:

source ./vars

Next, clean all the keys:

./clean-all

Generate the Diffie-Hellman parameters for the server site TLS/SSL:

./build-dh

Generate the root key and certificate:

./pkitool –initca

And finally, generate the server private key and certificate:

./pkitool –server server

Now that all the keys are generated, let’s build a TLS key and put all keys into place. Go to the ‘keys’ directory inside the ‘easy-rsa’ directory where you currently are:

cd keys/

And generate the TLS key:

openvpn –genkey –secret ta.key

Finally, copy all these keys to the openvpn directory:

sudo cp server.crt server.key ca.crt dh1024.pem ta.key ../../

And we’re done with the server-side keys! Final keys to generate now, are the client-side keys. Make sure you are in /etc/openvpn/easy-rsa/vars again and edit the variables to reflect your client. Otherwise you get an error when generating the certificate because it’s not unique.

Initialize the new environment variables:

source ./vars

And generate the client-side keys:

./pkitool client

That’s it! Keys are ready.

Finally, set the proper ownership to the ‘keys’ directory, as it’s currently owned by your user:

sudo chown root:sudo keys

Now, let’s configure OpenVPN!

Configuring OpenVPN

OpenVPN has a lot of configuration options. I’m going to cover a basic configuration which uses a tap interface.

The server configuration file is /etc/openvpn/server.conf. The default configuration file has a lot of comments in it, so it’s a good starting point to discover more about the configuration of OpenVPN. I’m going to give you the configuration that I’ve tested:

local 192.0.2.15 # Server IP address through which you connect, replace this with yours
port 1194 # Port the server runs on (default)
proto udp # Protocol to use (default)
dev tap
ca ca.crt # Root certificate
cert server.crt # Server certificate
key server.key  # Server key file
dh dh1024.pem # DH file
server 10.8.0.0 255.255.255.0
ifconfig-pool-persist ipp.txt # File that keeps track of IP leases
push “redirect-gateway def1 bypass-dhcp” # Push some options to the client
duplicate-cn
keepalive 10 120 # When should we disconnect a client?
tls-auth ta.key 0
comp-lzo # Enable compression
user nobody # Run as user nobody
group nogroup # Run as group nobody
persist-key # Avoid trying to access unavailable resources after a restart
persist-tun # Avoid trying to access unavailable resources after a restart
status openvpn-status.log # Status log for active connections
log-append  openvpn.log # Append the OpenVPN log rather then starting with a new one every time you restart
verb 3 # Log verbosity level
mute 20 # Limit the number of repeating messages
script-security 2 # Set the security level for the usage of external programs and scripts
link-mtu 1648

As you can see, I’ve added some inline comments. It would be good to read these. I’ll highlight the lines I would like to discuss in more detail, those are the most important options for you to know about.

dev tap

This line indicates we use a TAP tunnel, which is an ethernet tunnel rather than a routed IP tunnel. A TAP tunnel passes through all traffic rather than just HTTP and HTTPS. It’s the more “complete” tunnel when compared to TUN.

server 10.8.0.0 255.255.255.0

Set the internal IP range for the server and the clients. The server will get the IP 10.8.0.1 and the client IP addresses will start at 10.8.0.2. Change this to your liking or when it conflicts with other ranges on any of your clients.

duplicate-cn

This line allows multiple connections with the same client certificates. Leave this out to disable this option. If you edit the vars file for every client certificate you generate, this option can safely be disabled.

tls-auth ta.key 0

Name of the TLS key file and the “side” of the TLS connection. Since the server is 0, the client should be 1. This should be configured in you OpenVPN client software.

link-mtu 1648

This is the MTU for the VPN connection. The MTU (Maximal Tranmission Unit) is the maximum size in bytes of the largest piece of data that the link can transport. I’ve used this value because it worked for me. This will also need to be configured in your client. If you VPN doesn’t work, check the logs for MTU errors.

Once the configuration file is in place, restart OpenVPN:

sudo /etc/init.d/openvpn restart

And you should be good! Final step is adding three firewall rules to allow traffic to pass through your server:

sudo /sbin/iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
sudo /sbin/iptables -A FORWARD -i eth0 -o tap0 -m state –state RELATED,ESTABLISHED -j ACCEPT
sudo /sbin/iptables -A FORWARD -i tap0 -o eth0 -j ACCEPT

You should replace ‘eth0’ with the device name of your ethernet device. On most OpenVZ VPS this is venet0.

What these lines do, is the following (in order):

  1. Allow transparent NAT traffic over eth0
  2. Allow packets to be forwarded from eth0 to tap0 with certain connection states
  3. Allow packets to be forwarded from tap0 to eth0 regardless of the connection state

Now, with the server up and running and your firewall configured, you need to configure your client. I will cover some clients in next week’s tutorial (it was too much to combine it all in here), but here’s something to get you started on your own. To connect with a client, you need to:

  1. Have the client.crt, client.key, ca.crt and ta.key on your client
  2. Enable LZO compression
  3. Enable TAP
  4. Set the link MTU to 1648
  5. Set the TLS “side” to 1

If you’ve done that on you client, you should be able to connect!

Final notes

As you may have noticed, setting up OpenVPN isn’t hard but it isn’t very easy either. There’s a lot of steps to take, a lot of options available and a lot that can go wrong. I’ve tried to keep this guide concise and limited for the sake of clarity. If there is a clear demand for more explanation on certain subjects, please let me know. I’ll add more explanation/write a more detailed guide on a certain subject in that case.

Up next week: Getting started with OpenVPN (client)! Next week’s tutorial may be a bit later due to my supposed bachelor party. So if it’s not here on Saturday, it will be on Tuesday (latest).

mpkossen

32 Comments

  1. André:

    I wrote this “guide” as a reference to myself: http://blog.bugflux.org/2012/08/android-network-privacy-and-firewall.html

    I guess the steps are rather similar, I wish you had written this long ago! =)

    August 31, 2013 @ 1:55 pm | Reply
  2. Good effort. Nice updated tutorial on installing openvpn. I also did an attempt to write a detailed openvpn installation guide but i think it is a bit dated now. Referencing it here just to let the readers also have a graphical view of the commands that they are supposed to run. http://tipupdate.com/how-to-install-openvpn-on-centos-vps/

    August 31, 2013 @ 3:54 pm | Reply
  3. fabulous

    August 31, 2013 @ 4:07 pm | Reply
  4. I dont really understand between tun and tap.. which is better?

    August 31, 2013 @ 4:42 pm | Reply
  5. DanielM:

    i’ve found SoftEther a better option for VPN and openvpn seems to work fine without changing any virtuozzo (windows) settings. works fine with openvz too.

    August 31, 2013 @ 5:02 pm | Reply
    • I just hate it because i cant find way to enable tcp over dns.. even the page say it can tunnel tcp over dns

      August 31, 2013 @ 5:18 pm | Reply
  6. Jay:

    I have an issue where I connect to my router via an openvpn server installed on it. The problem is I can’t access a box behind the router when it is connected to a third party VPN I use and usually have a connection going with. So I can VPN into my home network and see everything except for the box connected to a seperate VPN. I have to ssh into a local box once i connect to my routers vpn and then ssh into the one behind the third party VPN to do anything with it.

    August 31, 2013 @ 6:10 pm | Reply
  7. W1V_Lee:

    Another nice tut, no use to me however the kids complain they can’t watch tv shows in the states from the UK, hmmmm…

    August 31, 2013 @ 7:20 pm | Reply
    • install vpn on a UK VPS and you are good to go.

      August 31, 2013 @ 8:48 pm | Reply
  8. Zerocool:

    If you use openvz hoster, DNAT will not work properly.
    Use SNAT:
    iptables -t nat -A POSTROUTING -o venet0 -j SNAT --to 1.2.3.4
    iptables -A FORWARD -i venet0 -o tun0 -m state --state RELATED,ESTABLISHED -j ACCEPT
    iptables -A FORWARD -i tun0 -o venet0 -j ACCEPT>

    there 1.2.3.4 – your white IP

    August 31, 2013 @ 9:20 pm | Reply
    • Maarten Kossen:

      Thanks for your feedback!

      I see you’ve applied those rules to TUN, are they the same for TAP? I’ve personally not had issues with OpenVZ yet. Out of curiosity: what are the issues you are talking about?

      September 1, 2013 @ 3:55 pm | Reply
  9. tommy:

    source ?

    September 1, 2013 @ 2:30 pm | Reply
    • Maarten Kossen:

      Source? A combination of the OpenVPN manual, the Ubuntu OpenVPN guide, my own trial and error and the inline comments of OpenVPN.

      September 1, 2013 @ 3:56 pm | Reply
  10. Would this work on a LowEndSpirit VPS?

    September 1, 2013 @ 3:17 pm | Reply
    • Maarten Kossen:

      I don’t know yet, but I was thinking of trying that soon. Think it would work, though, if you’ve change the port. But then again, not sure.

      September 1, 2013 @ 3:57 pm | Reply
    • C:

      Yes if you change your port.

      I currently run a server there.

      September 3, 2013 @ 7:21 am | Reply
  11. I wrote openvpn for Ios and android installation http://lowendtalk.com/discussion/12723/implementing-openvpn-client-on-your-ios-android#latest

    Hope it as additional tutorial.

    September 1, 2013 @ 3:49 pm | Reply
  12. AcuBcn:

    Hi !

    I’ve followed all this guide to put openvpn in my new VPS.

    I’ve founded just small things that I put here for other readers. I’m just a simple not advanced user, so I apologize if something is not ok.

    – Sometimes if they get a message is for small typing mistakes (commonly orders that must have two – (–) instead of one (-). They can check it twice here: https://help.ubuntu.com/10.04/serverguide/openvpn.html

    – The iptable 2nd rule has to be sudo /sbin/iptables -A FORWARD -i venet0 -o tap0 -m state –state RELATED,ESTABLISHED -j ACCEPT

    (the – stuff)

    Anyway, for some reason my server is not working :S maybe is the client, not sure, I will follow working on it…

    Thanks for all !

    – To edit the server.conf first we need to copy the sample one:

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

    September 2, 2013 @ 4:41 pm | Reply
    • Maarten Kossen:

      Thanks for sharing your findings!

      Just to clarify a few things:

      The iptables rule you’ve added it for a venet0 device, which is for OpenVZ. You should change ‘eth0’ to ‘venet0’ in the other commands as well, which should make everything work firewall-wise.

      The guide you refer to is quite old. Most of it is still complete, but some parts are out-dated. If some things don’t work from that guide, it wouldn’t surprise me.

      The server configuration files you refer to are either the same as the ones I download in the tutorial or older ones. The ones I download come from the OpenVPN GitHub. Both are fine to use.

      September 5, 2013 @ 9:06 am | Reply
  13. Bookmarked it, thanks!

    September 3, 2013 @ 8:26 am | Reply
  14. Jim Snow:

    if you are using the VPN to hide your real IP for e.g Hulu you can simply enable TUN/TAP device and install the Openvpn access server it comes with a free 2-slot license so if you are using the VPN for yourself all you have to do is to install the *.deb package and add a user =)

    September 8, 2013 @ 2:29 pm | Reply
  15. TSX:

    After inputing this command,

    sudo tar xvzf easy-rsa.tar.gz -C /etc/openvpn/easy-rsa –strip-components=3 easy-rsa-2.2.0/easy-rsa/2.0/

    I got this error message.

    tar: /etc/openvpn/easy-strip-components=3: Cannot open: No such file or directory
    tar: Error is not recoverable: exiting now

    September 19, 2013 @ 3:36 am | Reply
    • Tom Robbins:

      Because the option of tar is called –strip-components. Mind the two dashes. See the manual of tar. It is always a good thing to check the commands with its manual _before_ you issue them. That way you at least know wehat you are doing.

      September 19, 2013 @ 9:12 am | Reply
      • Tom Robbins:

        Ok it is two dashes. WordPress f*cks this up. It is “- – strip-components” but those two dashes must be together.

        September 19, 2013 @ 9:14 am | Reply
  16. Sean Corky:

    Here’s a good script to use to automate this…

    https://github.com/Nyr/openvpn-install

    September 19, 2013 @ 5:52 pm | Reply
  17. tj:

    is the client tutorial up ?
    sorry i tried dsearching for posts by the author and couldn’t find it

    October 8, 2013 @ 6:53 pm | Reply
  18. rami:

    Is it possible to give clients a static IP?
    and how can I see online clients?

    October 14, 2013 @ 5:41 pm | Reply
  19. patrick:

    Nice tutorial.

    I have one problem however. OpenVPN does not seem to start after a reboot of the host/VPS server (cold reboot).

    When I type “reboot now” Openvpn starts nicely.

    Should I wait for the network to be up first? How would I do that?

    October 21, 2013 @ 5:30 am | Reply
  20. Omer Naeem:

    Hey awesome guide. I wanted to know that does the vps requires multiple IP addresses, or will a vps with a single IPv4 will work too ?

    October 22, 2014 @ 9:52 pm | Reply
  21. h2o:

    Would you please fix all the dashes so the commands can be copy-pasteable? It’s `- -strip-components` not `–strip-components`.

    February 19, 2016 @ 4:03 pm | Reply

Leave a Reply

Some notes on commenting on LowEndBox:

  • Do not use LowEndBox for support issues. Go to your hosting provider and issue a ticket there. Coming here saying "my VPS is down, what do I do?!" will only have your comments removed.
  • Akismet is used for spam detection. Some comments may be held temporarily for manual approval.
  • Use <pre>...</pre> to quote the output from your terminal/console, or consider using a pastebin service.

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