Quick and dirty guide to OpenVPN on Slackware Linux and Android

Like many of you, I’m concerned about security, especially when working remotely. Generally I would simply create a tunnel using SSH, but then I must set all my programs to use the socks5 tunnel. This isn’t always possible without first opening the program, which will generally try to form a connection. Perhaps, not the best way to keep safe on a network you don’t trust (like a coffee shop).

Unlike using SSH to create a secured tunnel, which requires setting proxy settings for all your programs, using something like OpenVPN you can redirect all your traffic through the encrypted tunnel without having to configure anything. All thanks to using iptables.

Here is my quick and dirty guide on getting your very own OpenVPN server setup on Linux, as well as setup for two types of clients. One being a Linux client, the other being Cyanogenmod’s Android.

With this guide, I’m going to assume you already have OpenVPN installed and ready to go. Also that the configuration files are in /etc/openvpn/

Server Setup

First off, we need to generate some keys. This will be used to secure the connection. OpenVPN comes with all the tools you need to generate keys and indexes. Look for the easy-rsa directory that comes with OpenVPN. In my case, it’s in /usr/doc/openvpn-2.2.2/easy-rsa/2.0/

In that directory you will see a lot of scripts. Before doing anything you need to edit the file vars. In this file are several settings. Most important is with dealing with the openssl key. Here is a quick example you can base your configuration off of with all the comments removed.

export EASY_RSA="`pwd`"
export OPENSSL="openssl"
export PKCS11TOOL="pkcs11-tool"
export GREP="grep"
export KEY_CONFIG=`$EASY_RSA/whichopensslcnf $EASY_RSA`
export KEY_DIR="/etc/openvpn/keys"
export PKCS11_MODULE_PATH="dummy"
export PKCS11_PIN="dummy"
export KEY_SIZE=1024
export CA_EXPIRE=3650
export KEY_EXPIRE=3650
export KEY_COUNTRY="US"
export KEY_PROVINCE="CA"
export KEY_CITY="City"
export KEY_ORG="domain name"
export KEY_EMAIL="emailaddress@domain"

Note the export KEY_DIR. This is important. You will get warnings about running ./clean-all. This will delete ALL your keys.

After editing the vars file, we need to execute it to store the values in memory, then clean the keys directory. Do so by running:

. vars
./clean-all

Yes, you read that right, period, space, vars.

Now we are going to generate keys for the server and two clients.

For the server, we just need to run a couple of quick and easy commands.

./build-ca
./build-dh
./build-key-server server

The last command will build a server.key file. This is needed when running the server for key exchanges and such.

Now there are 3 different ways to build keys for clients.
./build-key client (no password protection, not recommended)
./build-key-pass client (with password protection, recommended)
./build-key-pkcs12 client (PKCS #12 format, good for Android)

For the client configuration. I’m not sure if you can use the PKCS #12 format. I haven’t tried, but if it works for you, please let me know.

Now we need to edit /etc/openvpn/openvpn.conf for our network setup. Most of the config files are self explanatory. Here is my example:

cd /etc/openvpn #yes, you do need this for some damn reason
local localIP
proto udp
port 1194
comp-lzo
verb 3
log-append /var/log/openvpn.log
dev tun0
persist-tun
persist-key
server 172.16.1.0 255.255.255.0
ifconfig-pool-persist /var/log/ipp.txt
client-to-client
push "route 10.0.0.0 255.255.255.0"
push "dhcp-option DNS 10.0.0.1"
push "dhcp-option DOMAIN domain.tld"
push "redirect-gateway def1"
keepalive 10 120
cipher BF-CBC
ca keys/ca.crt
dh keys/dh1024.pem
key keys/server.key
user nobody
group nobody
status /var/log/openvpn-status.log

Be sure to change localIP to the server’s IP address AND (if applicable) forward UDP port 1194 to the server.

NOTE: There is one issue I have run into. By using the option push “redirect-gateway def1” does seem to work fine and redirect all through the VPN, I have an issue getting the DNS and DOMAIN to work through both the OpenVPN software or my Android. This means that all DNS queries do not appear to be going through the VPN. This may not be the case. I have yet to setup a packet sniffer to check. So for the time being, I simply created a bash script that will edit my /etc/resolv.conf file when I start the VPN, and revert it back when done. If someone knows of a really easy way to check without having to use a sniffer, please let me know.

Now that all of the keys are built, and the openvpn.conf file is setup, we are ready to start the server. While I have run into some strange behavior in my configuration, you may have better luck in yours. In mine, I had to create the device tun edit ip_forward and manually configure the IP tables.

Here is my simple script I run on the server what I want to have the OpenVPN server up and running (yes, I do this at boot). Explanation of items below.

mkdir /dev/net
mknod /dev/net/tun c 10 200
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -I FORWARD -i tun0 -o eth0 -s 172.16.1.0/24 -d 10.0.0.0/24 -m conntrack --ctstate NEW -j ACCEPT
iptables -I FORWARD -i tun0 -o eth0 -s 172.16.1.0/24 -m conntrack --ctstate NEW -j ACCEPT
iptables -I FORWARD -i eth0 -o eth0 -s 10.0.0.0/24 -m conntrack --ctstate NEW -j ACCEPT
iptables -I FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
iptables -t nat -I POSTROUTING -o eth0 -s 172.16.1.0/24 -j MASQUERADE
iptables -t nat -I POSTROUTING -o eth0 -s 10.0.0.0/24 -j MASQUERADE
openvpn --config /etc/openvpn/openvpn.conf --cert /etc/openvpn/keys/server.crt &

Most places I have found this stuff are not very specific about IPs. So let me give you a quick rundown on each item.

First we create the device with some special settings. That is the mkdir /dev/net (if /dev/net already exists, it will do nothing), then mknod /dev/net/tun c 10 200. Then set ip_forward to true. The fun part is with the iptables.

So in my example, tun0 is the virtual device that is the VPN and eth0 is my ethernet. 172.16.1.0/24 is the IP range I’m giving to the VPN (tun0), and my physical network is 10.0.0.0/24. You can leave the VPN network on the 172.16.1.0/24 network, simply adjust the 10.0.0.0/24 to your networking configuration (ie 192.168.0.0/24). How all those iptables work… yea, I’m not going into it. They work, I’m fine with that.

After running those commands, your OpenVPN server should be up and running. The final process is background so you get your terminal back. Wait a few seconds and hit enter again. If you don’t see the process has ended, then you have done everything correctly. If it did error, check /var/log/openvpn.log for information on what is causing the problem.

Client Configuration

Now that the server is setup, lets get the client side going. This part will be for the OpenVPN software running on Linux. See the next section for CyanogenMod’s Android.

This part is much easier than the server setup, but you need to get your keys to the client. I highly recommend you do with via scp. You will need ca.crt, client.crt, and client.key. Assuming you called your keys “client”. Put these files in /etc/openvpn/keys. Then create the file /etc/openvpn/openvpn.conf and put this in it.

remote IP/DNS 1194
proto udp
dev tun  
cd /etc/openvpn/
ca keys/ca.crt
cert keys/client.crt
key keys/client.key
client
ns-cert-type server
keepalive 10 120
comp-lzo 
user nobody
group nobody
persist-key
persist-tun
status /var/log/openvpn-status.log

Change IP/DNS to the IP or DNS name your server is reachable at. You should now be able to connect to your OpenVPN server by typing:

openvpn --config /etc/openvpn/openvpn.conf

That’s pretty much it. Once you get a handle on the settings, it is actually pretty easy. However, as mentioned before. I have found a possible issue with DNS. I would highly recommend editing /etc/resolv.conf to point to your DNS server. In my example, the DNS server is also at the gateway (10.0.0.1). You can script this. In fact, use my script.

#!/bin/bash
pid=`pgrep openvpn`
if [ -z "$pid" ]; then
echo "Starting OpenVPN Client"
cp /etc/resolv.conf /etc/resolv.conf.backup
echo "nameserver 10.0.0.1" > /etc/resolv.conf
openvpn --config /etc/openvpn/openvpn.conf &
else
echo "Stopping OpenVPN Client"
mv /etc/resolv.conf.backup /etc/resolv.conf
kill $pid
fi

Pretty strait forward if I do say so myself. You may have an issue if you have a passphrase on your key! If you are having an issue, remove the ampersand (&) from the end of the openvpn –config line. This will not background the process, but you can do it manually by typing ctrl+z then bg which will background the process.

CyanogenMod’s Android Configuration

Because I don’t run the Android that came with my phone, I can use OpenVPN with ease. If you are not running a custom rom, you can still run OpenVPN by getting the client software from the Android Market (now called the Play Store). The following instructions are for CyanogenMod 7.2, but should work in newer versions just fine.

Remember when you made your client key? Well you need to make one that works great with Android. It’s the PKCS #12 format. This will give you a file that ends in a .p12 extension. Copy this file over to the root of your sdcard.

Install the certificate by going to Settings->Location & Security->Install from SD card (under Credential storage at the bottom on the menu). It should find the file and ask for the password to unlock it. Then it will ask for a new password (you can use the same one as before) and you can also give it a custom name.

Build the client by going to Settings->Wireless & Networks->VPN Settings->Add VPN. You just need to select the OpenVPN type. In the new menu there are several settings.

VPN name (this can be anything you want)
Set VPN server (the IP or domain name of the server)
User authentication (leave unchecked)
Set CA certificate (click this and select the key you just installed)
Set user certificate (same as above)
DNS search domains (these are optional, but you can set 10.0.0.1 like in the bash script above)

Hit the menu button then Advanced.

Server port (default is 1194)
Protocol to use (udp is default)
Device to use (tun, which is fine)
LZO compression (check it!)
Redirect gateway (check it!)
Remote Sets Addresses (Should also be checked)

Everything below that I left as default. You do NOT need to enable TLS-Auth. For this type of setup it is unnecessary.

Hit back, then save. From here you should be able to connect to your VPN. Note that in my tests, the VPN is much slower. I’m not sure if it is something I have done wrong in my setup, or if my provider throttles VPNs.

Conclusion

Everything should be up and running now. I hope you found this useful. Please feel free to leave a comment below. If you have any suggestions or questions you can drop those below as well. I’m not an expert on OpenVPN, I just like learning.

Sources:
http://openvpn.net/index.php/open-source/documentation/miscellaneous/77-rsa-key-management.html
http://openvpn.net/index.php/open-source/documentation/howto.html
http://blog.johnford.org/openvpn-tunnel-to-home-server/

Leave a Reply