Before my last extended period travelling and using public networks, I decided to set up a new low spec virtual machine on one of my hosted servers. I trust my datacenter and their uplinks more than I trust the free WiFi and public networks I travel through, and so while all my internet traffic is being routed over an encrypted tunnel to my dedicated server, I’m a lot happier.

I threw Squid3 into the mix, as it caches common assets and the sites I visit. This speeds up my web access and page load time.

OpenVPN can be configured more simply with a ‘static key’ configuration, however I’ve chosen to go down the PKI route for future growth. On my new VPN server I run:

apt-get install openvpn

Once OpenVPN is installed, I’ll need to set up my PKI system, certificate authority (CA), server certificate (vpn) and my first client certificate (npn)

mkdir /usr/share/doc/openvpn/examples/easy-rsa/2.0/keys
cd /usr/share/doc/openvpn/examples/easy-rsa/2.0

Edit ‘vars’ with your own details, cutting out the last 5 lines. In my case, the file now ends with:

export KEY_COUNTRY="GB"
export KEY_PROVINCE="London"
export KEY_CITY="London"
export KEY_ORG="IO Digital Sec"
export KEY_EMAIL="npn@iodigitalsec.com"

Once done, run:

source ./vars
./clean-all
./build-dh
./pkitool --initca   #build your CA
export KEY_CN=vpn KEY_NAME=vpn
./pkitool --server vpn   #build your server key and certificate, signed by CA
export KEY_CN=npn KEY_NAME=npn
./pkitool npn   #build a client key and certificate, signed by CA

cd /etc/openvpn
ln -s /usr/share/doc/openvpn/examples/easy-rsa/2.0/keys /etc/openvpn/keys

Now create and edit ‘openvpn.conf’:

dh /etc/openvpn/keys/dh1024.pem
ca /etc/openvpn/keys/ca.crt
cert /etc/openvpn/keys/vpn.crt
key /etc/openvpn/keys/vpn.key
comp-lzo
dev-type tap
dev tap0
keepalive 10 120
persist-key
persist-tun
port 1194
proto tcp-server
ifconfig 172.16.10.1 255.255.255.0
ifconfig-pool 172.16.10.2 172.16.10.254 255.255.255.0
mode server
tls-server
status openvpn-status.log
push dhcp-option DNS 8.8.8.8
verb 3
client-to-client

In this configuration, we specify that the server will run on TCP port 1194. The keys and certs are configured at the top. Our own IP bound to the tap0 adapter will be 172.16.10.1 while clients are given addresses between 172.16.10.2 and 172.16.10.254 on a 255.255.255.0 (/24) subnet. Client to client communication through the VPN tunnel is allowed. This is the opposite of client isolation. comp-lzo enables LZO compression.

OpenVPN can now be started on the server with:

openvpn ./openvpn.conf

Using scp, copy npn.key, npn.crt and ca.crt from your VPN server to your client. Scp is preferably to copying and pasting as when done through a terminal screen, extra whitespace can mangle the certificate or key file. If OpenVPN complains that your certificate or key can’t be read or is invalid, this is the most likely cause.

On your client, create ‘vpn.conf’ in the same directory as your 3 key files. Then edit ‘vpn.conf’:

dev tap0
remote YOUR_VPN_SERVER_IP
port 1194
proto tcp-client
tls-client
ca ca.crt
cert npn.crt
key npn.key
dev-type tap
float
keepalive 1 11
script-security 3
comp-lzo
link-mtu 1576
pull dhcp-options

Now start OpenVPN on your client:

openvpn ./vpn.conf

Once connected, your client should be able to ping the server over the VPN link:

ping 172.16.10.1

If this succeeds, then great. Your VPN is now established and working!

The next step is allowing your VPN server to provide NAT routing for your VPN clients. On the server:

iptables -t nat -I POSTROUTING -s 172.16.10.0/24 -o eth0 -j MASQUERADE
echo 1 > /proc/sys/net/ipv4/ip_forward

This can be added to your startup scripts in order to retain the settings on reboot.

Now you need to modify your client to route traffic through your VPN. We’ll need to replace the client’s default gateway. Once we do that, it will be unable to access the internet – VPN server included, so we’ll need to set a static route to the VPN server created first.

My client’s LAN router’s IP is 192.168.1.1:

Windows:

route add YOUR_VPN_SERVER_IP mask 255.255.255.255 192.168.1.1
route delete 0.0.0.0/0
route add 0.0.0.0 mask 0.0.0.0 172.16.10.1

Linux:

route add -host YOUR_VPN_SERVER_IP gw 192.168.1.1
route del -net 0.0.0.0/0
route add default gw 172.16.10.1

Your should now be able to ping out from your Client:

ping 8.8.8.8

Checking your external IP at http://checkip.dyndns.org/ should confirm that your IP is that of your VPN server.

Next, to install Squid3:

apt-get install squid3
cd /etc/squid3
mv squid.conf squid.conf.old

edit ‘squid.conf’:

acl localhost src 172.16.10.0/24 ::1
http_access allow localhost
http_access deny all

http_port 172.16.10.1:3128 transparent
cache_effective_user proxy
cache_effective_group proxy

Now restart Squid with the new configuration:

/etc/init.d/squid3 restart

Lastly, transparently proxy your VPN client’s outbound HTTP (port 80) traffic through Squid running on port 3128:

iptables -t nat -A PREROUTING -s 172.16.10.0/24 -p tcp --dport 80 -j REDIRECT --to-port 3128

Again, this code can be added to your system’s startup scripts to persist on reboot.

You should be able to monitor Squid activity on your VPN server as you browse the web on your Client with:

tail -f /var/log/squid3/access.log