Setup an IPv6 VPN with an OVH server
Languages: French
April 02, 2014
Introduction
This tutorial combines a solution to two different but related problems:
- The desire that machines not necessarily adjacent belong to the same
LAN
. This is typically the role of a VPN - The fact that the majority of the Internet (IPv4) today consists of
machines hidden behind subnets and therefore is impossible to contact them
publicly
without using port redirection (which prevents then having two machines in the network providing the same service on the same port).
In the specific case that I will discuss, I have a personal server (by OVH),
with a unique IPv4 address (198.51.100.24
), and a /64 IPv6 subnet
(2001:db8:200:13::/64
), both fixed.
Besides that, I have several PCs with different configurations and Internet access, more or less restricted, in different networks and not necessarily connected to each other (not even in the same country) and I that I would like to connect with a virtual network.
To create the virtual network, we have two options:
- Either we create a private IPv4 subnet (but then attention to headaches if by chance the machine happens to be on an identical physical network
- Otherwise... We have access to no less than 264 IPv6 addresses via our OVH server that we can take advantage of!
Creating a virtual subnet
To create this network, I use tinc. This program is quite simple, and intuitive once you understand what a VPN is.
In this particular case, interconnectin our machines is quite simple: all of them are able to contact the server (which has a public Ipv4), so we just need to ask each of them to connect to the server. tinc will then take care the interconnection!
Common part
This part has to be done on both the clients and the server of the VPN:
-
We start by installing tinc (via the software manager of our favorite distribution)
-
tinc is able to manage multiple VPN networks, in which case the different configurations go in separate subfolders of the form
/etc/tinc/NAME
(NAME
doesn't have to be common among the different hosts of the same network)- On a Debian-like distribution, you need a file
/etc/tinc/nets.boot
that contains the list of configurations that are automatically started at boot time (provided that the service is enabled) - On a distribution that works with systemd, you need to enable separately
each
tincd@NAME.service
.
- On a Debian-like distribution, you need a file
-
We create a file called
tinc.conf
with at least:Name = HostName Interface = vpn6 Mode = switch
Here
Name
is the name of the host in the VPN, andInterface
is the interface name associated to the VPN that will be created. -
It might be necessary to add a
Device
line if the default value is incorrect.# The tap device tinc will use. # Default is /dev/tap0 for ethertap or FreeBSD, # /dev/tun0 for Solaris and OpenBSD, # and /dev/net/tun for Linux tun/tap device. Device = /dev/net/tun
If necessary, load the tun module
modprobe tun
-
We then create the public/private key pair that will be used by the host:
tincd -n NAME -K
Put the public part (.pub) in
/etc/tinc/NAME/hosts/HostName
(publicly readable, create the hosts directory), and keep the private part in/etc/tinc/NAME/
readable only by root. -
That's it for the common part.
Server part
The server part is the more complex one. Let's go into more details:
-
tinc can run two scripts
tinc-up
andtinc-down
if they are present (and executable) in/etc/tinc/NAME/tinc-{up,down}
when the service starts/stops. We need to add a few commands there:# tinc-up #!/bin/bash echo 1 > /proc/sys/net/ipv6/conf/eth0/proxy_ndp echo 1 > /proc/sys/net/ipv6/conf/all/forwarding ip -6 link set $INTERFACE up mtu 1280 txqueuelen 1000 ip -6 addr add 2001:db8:200:13:1::1/96 dev $INTERFACE ip -6 route add 2001:db8:200:13:1::/80 dev $INTERFACE ip neigh add proxy 2001:db8:200:13:1::1 dev eth0
and
# tinc-down #!/bin/bash echo 0 > /proc/sys/net/ipv6/conf/eth0/proxy_ndp echo 0 > /proc/sys/net/ipv6/conf/all/forwarding ip neigh del proxy 2001:db8:200:13:1::1 dev eth0 ip -6 addr del 2001:db8:200:13:1::1/96 dev $INTERFACE ip -6 link set $INTERFACE down
Don't forget to change
eth0
by the interface on which the IPv4 is linked, and the IPv6 addresses by yours.
Here I chose to use only the part2001:db8:200:13:1::/80
for the VPN, and to assign the first of it to the server.
The lineecho 1 > /proc/sys/net/ipv6/conf/eth0/proxy_ndp
is important in that case because we will only provide addresses in the/64
part of it, and without this packets will not broadcast from the outside of the VPN inward (conversely, if you want to remain closed in the VPN, you can remove this line).
The explanation is a little unclear to me, but if I understood correctly the last 64 bits of the address are assumed to be local and therefore not routed. More specifically, when the server receives oneth0
a request of the formWhere can I contact
(by the OVH router to which it is linked), he will answer2001:db8:200:13:1::42
?me
(under some conditions that we will see afterwards), and then will follow it to it's target inside of the VPN. -
Now the
configuration
part is done for the server. We'll have to tell him afterwards who are the clients. We should keep the file/etc/tinc/Immae/hosts/HostName
accessible since it will have to be transmitted to each of the clients.
Client part
I'll use here the term ServerName
to design the name of the
server as defined on line Name
of the configuration file
tinc.conf
on the server.
-
Get
/etc/tinc/Immae/hosts/ServerName
on the server and put it in/etc/tinc/Immae/hosts/
(next to your own), edit it and add a line at the top of the file:Address = 198.51.100.24
(Replace the ip address by the IPv4 address of the server, or possibly its domain name)
-
Edit the file
tinc.conf
and add the informations for him to connect to the server:# The internet host to connect with. # Comment these out to make yourself a listen-only connection # You must use the name of another tinc host. # May be used multiple times for redundance. ConnectTo = ServerName
-
We will also create files
tinc-up
andtinc-down
as on the server, but now we don't need to activate a proxy of forward:# tinc-up #!/bin/bash ip -6 link set $INTERFACE up mtu 1280 ip -6 addr add 2001:db8:200:13:1::42/96 dev $INTERFACE ip -6 route add default via 2001:db8:200:13:1::1
and
# tinc-down #!/bin/bash ip -6 addr del 2001:db8:200:13:1::42/96 dev $INTERFACE ip -6 link set $INTERFACE down
Be careful of course not to chose the same ip for two clients of the same VPN.
Client-Server connexion
Here I use ClientName
to designate the name chosen by a client.
-
Now we need to inform the server that the client is authorized in the VPN. For that, we send the file
/etc/tinc/NAME/hosts/ClientName
from the client to the server in the corresponding directory (keep the same name). -
Finally, we need to create two (executable) files
ClientName-up
andClientName-down
in the subfolderhosts/
on the server to set up and destroy the proxy when the client comes and goes:# hosts/NomDuClient-up #!/bin/bash ip neigh add proxy 2001:db8:200:13:1::42 dev eth0
and
# hosts/NomDuClient-down #!/bin/bash ip neigh del proxy 2001:db8:200:13:1::42 dev eth0
End, configuration details
Now you just need to start the different tinc services on the machines, and
everyone will be interconnected and be able to access to the IPv6 Internet! To
sum up, the folders /etc/tinc/NAME/
should look like that:
# Server$ ls -1R /etc/tinc/NAME
/etc/tinc/NAME:
hosts
rsa_key.priv
tinc-down
tinc-up
tinc.conf
/etc/tinc/NAME/hosts:
Server
Client1
Client1-up
Client1-down
Client2
Client2-up
Client2-down
and
# Client1$ ls -1R /etc/tinc/NAME
/etc/tinc/NAME:
hosts
rsa_key.priv
tinc-down
tinc-up
tinc.conf
/etc/tinc/NAME/hosts:
Server
Client1
Important note
By default, recent Linux distribution give priority to
IPv6 for Internet connection. That means that all the connections will
go through the server as soon as IPv6 is available for the requested service. To
avoid that, you can edit the file /etc/gai.conf
, in which a section
explains exactly how to do that (i.e. give priority to l'IPv4). Note that this
configuration can be triggered independently on each client (see below).
-
By default:
# /etc/gai.conf # Add another rule to the RFC 3484 precedence table. See section 2.1 # and 10.3 in RFC 3484. The default is: # #precedence ::1/128 50 #precedence ::/0 40 #precedence 2002::/16 30 #precedence ::/96 20 #precedence ::ffff:0:0/96 10 # # For sites which prefer IPv4 connections change the last line to # #precedence ::ffff:0:0/96 100
-
To give priority to IPv4 connectivity:
# /etc/gai.conf # Add another rule to the RFC 3484 precedence table. See section 2.1 # and 10.3 in RFC 3484. The default is: # precedence ::1/128 50 precedence ::/0 40 precedence 2002::/16 30 precedence ::/96 20 #precedence ::ffff:0:0/96 10 # # For sites which prefer IPv4 connections change the last line to # precedence ::ffff:0:0/96 100