====== 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
[[https://openvpn.net/index.php/open-source/|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 [[http://www.fwbuilder.org/|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:
{{ :linux:fwbuilderpolicy.png?direct&600 |}}
And then a NAT rule to send VPN traffic to and from the outside world; the ''outside'' device is ''eth0'' on my server.
{{ :linux:fwbuildernat.png?direct&600 |}}
==== The client end ====
And finally, what to tell the clients? The following is working for me on [[https://tunnelblick.net/|Tunnelblick on Mac]] and
[[https://play.google.com/store/apps/details?id=de.blinkt.openvpn&hl=en|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.