====== 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.