How do I setup OpenVPN so I can securely use the internet from an unsecured hotspot?

I have the exact question a few months ago, but additionally, I wanted to have an IPv6 connection if possible. You might be interested in my questions on Serverfault:

  • How do I configure OpenVPN for accessing the internet with one NIC?
  • How can I setup OpenVPN with IPv4 and IPv6 using a tap device?

I had only one NIC ("network interface") on my server for use. In my setup, NetworkManager was not sufficient because I need to run a custom script to support IPv6. For simplicity however, I will use NetworkManager here and omit the IPv6 support.

First, just make a decision on the authentication method. I'll be using the safer certificate method which works like SSL: during the handshake a common secret is chosen which will be used for the session. The other methods are a shared key; a username and password.

Server

1. Prepare

First, install the openvpn server. This is as easy as sudo apt-get install openvpn. The difficult part is configuring it. The configuration is present in /etc/openvpn.

2. Configure authentication

The server needs certificates for identifying itself and its clients. These certificate are retrieved from a CA (Common Authority). The creation of the certificates and related private keys can be done on any machine, it does not have to be done on the server. If you're really paranoid, you should do it on a machine which is not connected to a network, and use a memory stick for transferring the certificates.

Create a CA and certificates for the server

This step has to be done once unless your CA's private key got compromised. In that case, valid certificates can be created which will be accepted by the server, resulting in a security breach.

The official documentation suggests to do the administration in /etc/openvpn. I am not a big fan of running everything as root, so I will put it in a different directory.

  1. Create the administration directory and copy the files in it by running:

    mkdir ~/openvpn-admin
    cd ~/openvpn-admin
    cp -r /usr/share/doc/openvpn/examples/easy-rsa/2.0/ ./easy-rsa
    cd easy-rsa
    
  2. Edit defaults in vars as needed, for example setting KEY_SIZE=2048 because you are paranoid.
  3. Load the variables and create the key directory by running:

    . vars
    
  4. If you get an error that No ... openssl.cnf file could be found Further invocations will fail, run ln -s openssl-1.0.0.cnf openssl.cnf, then . vars again.

  5. If this is your first time using this CA, prepare the keys environment. Do not run this command if you want to maintain your previously created CA. Doing so will require you to deploy a new ca.crt.

    ./clean-all
    
  6. Create the CA by executing ./build-ca. You can fill any details in you want, but note that this information will be visible in log files when the clients connects to the server. This will create the files ca.key and ca.crt in the subfolder keys. Keep the ca.key file secret in all circumstances. Failure to do so will allow anyone with the key to connect to your server.
  7. If you have a previous certificate that is lost or expired, you need to revoke the old one first with ./revoke-full server. Otherwise you get a database error.
  8. Create the certificate for the server by running:

    ./build-key-server server
    

    When being asked for a password, leave it empty unless you are willing to enter the password each time the server starts (not recommended). Confirm on signing the certificate and committing it. Two new files will appear in the directory keys: server.key and server.crt.

DH and use prepare for tls-auth

Generate Diffie-Hellman parameters using:

./build-dh

Per hardening tips, use tls-auth. For that, generate the shared-secret key using:

openvpn --genkey --secret ta.key

The resulting file (ta.key) must be distributed to clients as well, but you should not put it in public.

Create certificates for clients

For each client, these steps should be repeated:

  1. Enter the directory in which you created your CA and server certificate:

    cd ~/openvpn-admin/easy-rsa
    
  2. If you've skipped the CA creation step because you've already one, you need to load the variables first:

    . vars
    
  3. If you are creating new certificates because the old ones are lost or expired, you need to revoke the old one first with ./revoke-full you. Otherwise you get a database error.
  4. Create the clients certificate you.key and its corresponding certificate you.crt:

    ./build-key you
    

    The CommonName should be unique. Leave the password empty if you're using KDE as it's not supported yet as of 10.10. As with the server certificate generation, confirm signing the cert and committing the changes.

3. Setup the OpenVPN service

By default, OpenVPN runs as root when accepting connections. Not a good idea if the service is reachable from the evil Internet.

  1. Create the a dedicated user for OpenVPN, say openvpn:

    sudo useradd openvpn
    
  2. Copy the files server.key, server.crt, ca.crt and dh1024.pem (or dh2048.pem if you've changed key size) from the keys directory into /etc/openvpn. A permission of 400 (read-only for owner) is fine.

    sudo cp ~/openvpn-admin/easy-rsa/keys/{server.key,server.crt,ca.crt,dh*.pem} /etc/openvpn
    sudo chmod 400 /etc/openvpn/{server.key,server.crt,ca.crt}
    
  3. Copy the file ta.key as well:

    sudo cp ~/openvpn-admin/easy-rsa/ta.key /etc/openvpn
    sudo chmod 400 /etc/openvpn/ta.key
    
  4. Create the file /etc/openvpn/server.conf and put the next lines into it:

    proto udp
    dev tap
    ca ca.crt
    cert server.crt
    key server.key
    dh dh1024.pem
    server 10.8.0.0 255.255.255.0
    push "redirect-gateway def1"
    ifconfig-pool-persist ipp.txt
    keepalive 10 120
    tls-auth ta.key 0
    # Compress data to save bandwidth
    comp-lzo
    user openvpn
    group openvpn
    persist-key
    persist-tun
    # Logs are useful for debugging
    log-append openvpn-log
    verb 3
    mute 10
    
  5. Set the appropriate permissions on it, it does not need to be secret, but I prefer not leaking configuration details so:

    sudo chmod 640 /etc/openvpn/server.conf
    

4. Finishing the server

If you've created the certificates on the server, it's a good idea to encrypt it or move it off the server. In any case, do not lose the ca.key and server.key. In the first case others will be able to connect to your server. In the latter, a MITM is possible.

Client

Besides the server IP address, the server administrator should hand over the following files:

  • ca.crt: for verifying the certificates
  • server.crt: for verifying the server and communicating with it
  • ta.key: for hardening the security
  • you.crt: to identify yourself with the server
  • you.key: it's like your password, file permissions should be 400 (read-only for owner)

1. Installation

Install OpenVPN and the NetworkManager plugin (suitable for KDE and Gnome):

sudo apt-get install openvpn network-manager-openvpn

network-manager-openvpn is in the universe repository.

2. Configuration

In the control panel, use the following details:

  • Gateway: the server IP address
  • Type: "Certificates (TLS)" (Gnome) or "X.509 Certificate" (KDE)
  • CA Certificate: path to ca.crt
  • User Certificate: path to you.crt
  • Private Key: path to you.key

At Advanced:

  • Gateway port: Automatic (1194) (does not need to be changed)
  • Use LZO data compression: enabled
  • Use TCP connection: disabled
  • Use TAP device: enabled
  • Cipher: default
  • HMAC authentication: default
  • Use TLS-authentication: enabled
    Specify the Key File path to ta.key and set "Key Direction" to 1.
  • (todo - checking it out) the server pushes the default gateway so all traffic goes over the VPN connection. The last time I checked, the network-manager-openvpn plugin did not do it.

If you cannot get NetworkManager working or do not want to use it, put the files (ca.crt, ...) in /etc/openvpn and create the file /etc/openvpn/client.conf file:

client
dev tap
proto udp
# replace 1.2.3.4 by your server IP
remote 1.2.3.4 1194
resolv-retry infinite
nobind
persist-key
persist-tun
ca ca.crt
cert you.crt
key you.key
ns-cert-type server
tls-auth ta.key 1
comp-lzo
user nobody
group nogroup
verb 3
mute 20

If you do not want to enable this VPN on boot time, edit /etc/default/openvpn and uncomment the next line by removing the #:

#AUTOSTART="none"

To start this connection, run:

sudo /etc/init.d/openvpn start client

client should be renamed if your configuration file is not named client.conf. Example: if you've named your configuration file safe.conf, you need to run sudo /etc/init.d/openvpn start safe.

To stop OpenVPN, you have to run:

sudo /etc/init.d/openvpn stop

You don't actually need to fiddle with any applications. This works "just like VPN."

  1. First install the tsocks package (temporary socks):

    sudo apt-get install tsocks
    
  2. Then edit /etc/tsocks.conf and enter

    server = 127.0.0.1
    server_port = 3333
    
  3. Now, open a terminal and type (this connects you):

    ssh -ND 3333 ssh.url.to.your.home.machine
    
  4. Run (via another terminal or ALT-F2):

    tsocks firefox
    

Now, Firefox transmits all communication through to the SOCKS server on your computer that SSH created. This further gets tunneled to your home machine, where it goes to the web. All you need on your home machine is an SSH server. After the first time, just repeat steps 3 and 4.

It works like a charm! Alas, chromium doesn't like tsocks, but hey, Firefox works.


The SSH tunnel solution is easier than you think. A program like gSTM will start/stop the tunnels for you with a GUI. Then just open Network Proxy and change it from Direct internet connection to Manual proxy configuration, hit "Apply system-wide" and all your apps should send their data down the tunnel - no need to fiddle with each one individually.