I recently figured it would be a good idea to set up a VPN server, to be
able to route internet traffic securely to a point of departure I trust
as safe. I happen to control a server located in Germany, and so it was
fairly easy to find a spot to set things up on. Figuring out exactly how
to get things working was slightly more different though.
The problem
If you, like me, just google for info on how to install openvpn, you'll
soon get confused on an important point: do you use TUN or TAP? Most of
the guides I came across don't mention the distinction but just go on to
use one (primarily TAP) of them. The reason this might be a concern to
you is that one of them involves making low-level changes to your
networking - and if your server is not in the next room, easily
accessible, you might not want to mess to much with something that'll
leave it inaccessible.
If you want to actually figure out what the difference is, read further
on wikipedia. Briefly, both TUN
and TAP are virtual network devices, but TAP is used with a network
bridge while TUN is used with routing. What this means is that when you
setup openvpn, with TAP you need to create a network bridge (which means
changing network configuration and thus bringing the network down and
up), while with TUN you need to setup proper NAT routing (not messing
with network configuration but with firewall rules - which can also end
up bad, but is easier to plan for).
Given these considerations, I opted for TUN, which is what the rest of
the post will be about. If you want to setup an openvpn server using
TAP, there are plenty of guides out there.
The plan
My use case for openvpn is installing the server on a debian machine
(running lenny) and connecting from a ubuntu machine (running 12.04).
The following steps are required:
- Install the openvpn server
- Create certificate and keys
- Edit server config
- Setup routing
- Setup client
- Enjoy
Step 1 - install openvpn
Yeah. That was the easy part.
Step 2 - create certificate and keys
The next bit is creating the certificate and keys needed for
authentication and encryption. Because openvpn is based on SSL and TLS
you need certificates to get things working. This might sound like
something very tedious to get working, but fortunately there are some
easy to use scripts that come with the openvpn package. These are most
likely situated in /usr/share/doc/openvpn/examples/easy-rsa/2.0/ - copy
that folder to /etc/openvpn/easy-rsa and cd into it. Then edit the vars
file and fill in details for:
KEY_SIZE=2048 # might as well set it high for good measure
CA_EXPIRE=3650 # 10 years so it doesn't suddenly run out
KEY_EXPIRE=3650
KEY_COUNTRY="Your country"
KEY_PROVINCE="Your province"
KEY_CITY="Your city"
KEY_ORG="Name of organization"
KEY_EMAIL="Relevant email address"
Entering the details in the above file means you do it once even if you
have to redo the certificates. After doing that, go through the
following steps:
# this exports the variables into the environment
./vars
# this makes sure you start from scratch (it removes all files from the ./key folder
./clean-all
# this builds the openvpns root certificate
./build-ca
# this builds the diffie-hellman parameter file needed
./build-dh
# this builds the specific certificate the server uses
./build-key-server server
# this builds a certificate set for a client
./build-key client
Additionally, you can also go through the extra step of creating an
extra key for tls authentication. According to the openvpn
documentation,
this adds an extra signature to packets, giving extra protection. Not
all clients support it though, so check first if you can use it. You
generate the secret key this way:
openvpn --genkey --secret ta.key
After this, all generated files are located in ./keys/. On the server
end, you need the following files:
- ca.crt
- server.crt
- server.key
- dh2048.pem
- ta.key (if you decided to use it)
On the client end you need these files:
- ca.crt
- client.crt
- client.key
- ta.key (if you decided to use it)
Step 3 - server configuration
Next, you need to edit your openvpn server config. The config is located
at /etc/openvpn/server.conf. You should make sure the following values
are set as follows (leave any others as default):
port 1194 # port openvpn will be listening on
proto udp # protocol that will be used
dev tun # network device type used
ca /etc/openvpn/easy-rsa/keys/ca.crt # root certificate used for signing certificates
cert /etc/openvpn/easy-rsa/keys/server.crt # servers certificate for authentication
key /etc/openvpn/easy-rsa/keys/server.key # servers private key for certificate
dh /etc/openvpn/easy-rsa/keys/dh2048.pem # diffie-hellman vars for establishing connection
server 10.9.0.0 255.255.255.0 # subnet that openvpn will assigning clients ip's from
ifconfig-pool-persist ipp.txt # file to record persistent ip's in, so clients get the same ip
push "redirect-gateway def1 bypass-dhcp" # directive to make clients redirect traffic through vpn
push "dhcp-option DNS 8.8.8.8" # directive to make clients use googles dns
tls-auth /etc/openvpn/easy-rsa/ta.key 0 # if you decided to use tls.-auth
user nobody # user the openvpn daemon runs as
group nogroup # group the openvpn daemon runs as
After editing the server.conf, time to restart the openvpn daemon. Run
/etc/init.d/openvpn restart, and the openvpn daemon should come up,
creating a tun0 network device in the proper subnet - check with
ifconfig.
Step 4 - setup routing
When you're through setting up the VPN server you need some firewall
rules to make sure packets go the proper place. Using iptables, here are
the commands that should get the routing part setup properly:
# use IP masquerading
iptables -t nat -A POSTROUTING -s 10.9.0.0/24 -o eth0 -j MASQUERADE
# accept all packets in the forward chain from device tun0 to device eth0
iptables -t filter -A FORWARD -i tun0 -o eth0 -j ACCEPT
# forward packages for related and established connections
iptables -t filter -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
After adding these rules to iptables, it's a good idea to save them to a
script with iptables-save - you can then later apply them again (if
needed) with iptables-apply. And obviously you can make sure they're
reloaded automatically on a server reboot.
Other than changing iptables rules, you also need to make sure that the
kernel allows IP forwarding. This is done with
sysctl -w net.ipv4.ip_forward=1
To make sure the change sticks, edit /etc/sysctl.conf (or add a file
with the same content to /etc/sysctl.d/) and add:
With these changes, the server should happily route incoming VPN
connections to the internet.
Step 5 - setup client
Finally, you need to setup your client to access the server. If using
Ubuntu (or any of the variants, presumably including a desktop version
of Debian), you can let NetworkManager abstract some of the concerns
away. Right click the network icon in the system tray, select VPN
connections and click on Configure VPN - then click on Add VPN. Choose
OpenVPN. Note that in later versions of Ubuntu, you might need to
install network-manager-openvpn first, to see the OpenVPN option:
sudo apt-get install network-manager-openvpn network-manager-openvpn-gnome openvpn
With these installed, you should be able to choose the proper VPN server
to connect to.
Moving on, you should fill in a connection name (so you can remember
what it is you're connecting to), the Gateway (use either the domain
name you connect to or an IP address of the VPN server), type of
connection (in our case Certificates) and then choose the path for the
two certificates and the private key generated in step 2. User
certificate should be client.crt, CA certificate should be ca.crt and
private key should be client.key.
Next, click on the Advanced button, select the TLS Authentication tab,
and mark the Use additional TLS authentication checkbox. Select the
ta.key and select 1 under key direction. This should be all the
configuration needed for the client - save the connection info and try
connecting.
Step 6 - enjoy
If everything went according to plan, you should now be able to browse
the net through your VPN connection. Test the connection using a browser
and https://whatismyip.org/ - you should see the IP address of your
server.