Table of Contents

Setting up an OpenVPN server on Debian Jessie

It's not a classic use case for having a VPN connection available while on the road, but if your server has IPv6 connectivity, you can IPv6 enable your VPN client. I have a few hosts only accessible via IPv6, so when outside enlightened networks this enables me to access them conveniently.

In case anyone finds it useful, here's my configuration.

The server

The server runs Debian Stable, Jessie at the time of writing. I've configured OpenVPN to use a network tunnel (a tun device) rather than a network tap. I don't want to do bridging, and a tunnel seems easiest.

The basic VPN setup creates an address space in which the VPN lives. I'm using some private address ranges; 10.216.8.x for IPv4, and I generated a little piece of the IPv6 private address space using http://simpledns.com/private-ipv6.aspx, which spat out fddb:badf:fa73:5228/64.

Tunnel device setup

The server firewall has to be amended to allow traffic over the tunnel device. My firewall is a script generated by the rather fine FWBuilder using Linux iptables. The script lives in /etc/network/ip-up.d/firewall, so gets run by Debian every time a network device changes. But therein lies a catch; the script needs to refer to the tunnel device, and that device doesn't exist by default until the OpenVPN server runs.

So I use the OpenVPN persistent tunnel facility to create the tunnel device at network configuration time. I added these lines to /etc/network/interfaces.

auto tun0
iface tun0 inet static
      address 10.216.8.1
      netmask 255.255.255.0
      pre-up openvpn --mktun --dev tun0 --user nobody --group nogroup
      post-down openvpn --rmtun --dev tun0

iface tun0 inet6 static
    #address 2001:41c8:51:189::1
    #netmask 65
    address fddb:badf:fa73:5228::1
    netmask 64
# ifup tun0

then created the tunnel device and assigned server addresses to it. The addresses are what OpenVPN will assign.

OpenVPN server setup

Next step, configure the OpenVPN server. I'm having access via certificate only. Generating the certificates is covered in the OpenVPN docs, which I don't intend to repeat here.

My server.conf looks like this. Note the use of ifconfig-noexec - this stops OpenVPN trying to assign IP addresses to the tun interface. They've already been assigned earlier, so attempting to assign again will fail.

port 1194
proto udp
proto udp6
dev tun0
topology subnet

user nobody
group nogroup

cipher AES-256-CBC

ca      /etc/openvpn/easy-rsa/2.0/keys/ca.crt    # generated keys
cert    /etc/openvpn/easy-rsa/2.0/keys/server.crt
key     /etc/openvpn/easy-rsa/2.0/keys/server.key  # keep secret
dh      /etc/openvpn/easy-rsa/2.0/keys/dh2048.pem

server 10.216.8.0 255.255.255.0
server-ipv6 fddb:badf:fa73:5228::/64
# tun0 is created as a persistent tunnel, and these addresses
# bound to it in /etc/network/interfaces. The firewall script
# will therefore find tun0 present, which it expects.
# Any attempt to rebind the same addresses will fail, so skip it.
ifconfig-noexec

ifconfig-pool-persist ipp.txt

keepalive 10 120

comp-lzo         # Compression - must be turned on at both ends
persist-key
persist-tun

status openvpn-status.log

verb 3  # verbose mode
# client-to-client
push "redirect-gateway"
push "dhcp-option DNS 8.8.8.8"
push "dhcp-option DNS 8.8.4.4"
push "dhcp-option DNS 2001:4860:4860::8888"
push "dhcp-option DNS 2001:4860:4860::8844"

In this configuration, activating the VPN will cause all gateway traffic on the client to go via the VPN. This will ensure that IPv6 traffic flows via the VPN.

Enabling IP forwarding

I want the server to forward VPN traffic out to the world, so I must enable forwarding. This requires some uncommenting in /etc/sysctl.conf.

# Uncomment the next line to enable packet forwarding for IPv4
net.ipv4.ip_forward=1

# Uncomment the next line to enable packet forwarding for IPv6
#  Enabling this option disables Stateless Address Autoconfiguration
#  based on Router Advertisements for this host
net.ipv6.conf.all.forwarding=1

Firewall modifications

Finally on the server I need to allow traffic on the VPN device, and to NAT VPN traffic into the wider internet. In FWBuilder I created network objects corresponding to the IPv4 and IPv6 address ranges above, a tun0 device, and added a policy:

And then a NAT rule to send VPN traffic to and from the outside world; the outside device is eth0 on my server.

The client end

And finally, what to tell the clients? The following is working for me on Tunnelblick on Mac and OpenVPN for Android. Putting the config into NetworkManager on Linux works well too.

client
dev tun
proto udp
remote pigwidgeon.cryhavoc.org.uk 1194
remote-cert-tls server
auth-nocache
resolv-retry infinite
persist-key
persist-tun
ca ca.crt
cert jim.crt
key jim.key
cipher AES-256-CBC
comp-lzo

As an aside, I wasted a lot of time finding out that Tunnelblick needs to have the client line for it to work as a client.