IPv6/VPNs
This page lists some of the technologies you can use to create VPNs that utilize IPv6. You might want to use it to IPv6-enable your home, for instance.
Example addresses used
In this document we will assume the following addresses are in use.
- Customer /48 assignment
- 2a0a:1100:1018::/48 (the 018 part will be different for you)
- Customer IPv4 address
- 85.119.82.121 (the last two octets will be different for you)
- IPv4 network to route to client
- 10.254.1.0/24
- IPv6 subnet to route to client
- 2a0a:1100:1018:1::/64
- IPv4 address in VPN
- 10.254.1.254/32
- IPv6 address in VPN
- 2a0a:1100:1018:1::fe/128
Using WireGuard
Probably the more sensible choice in the 2020s, but, help?
Using tincd
These instructions have been tested with at least the following packaged versions of tinc:
- 1.0.16 on CentOS 5.x/6.x
- 1.0.8-2 on Debian lenny
- 1.0.11-1 on Ubuntu 10.04 (Lucid)
Configurations are stored in /etc/tinc. If you want to run multiple VPN tunnels you can create "named instances" by utilising a folder structure, i.e. /etc/tinc/<instance-name>
tinc directs traffic to named "peers", which are static or dynamic remote host:port combinations of remote tinc daemons. The Linux TUN/TAP driver is required to operate tinc, and is enabled by default, but it doesn't hurt to have
tun
in a file such as /etc/modules-load.d/tun.conf file.
Step 1. Create the basic config file
Warning: | In this document, references to /etc/tinc should be substituted with /etc/tinc/instance-name, as appropriate where named instances are to be used. |
Create a file /etc/tinc/tinc.conf; a sample is below:
Name = tegan
ConnectTo = susan
Interface = susan
Device = /dev/net/tun
DeviceType = tap
BindToAddress = 85.119.82.121
Port = 655
Mode = switch
- Name
- The name you wish to refer to your current host by, e.g. your DNS name. Note that non-alphanumeric characters are best avoided in naming in tinc.
- ConnectTo
- Tells tinc to initiate a connection to the remote peer with this name. If the remote end is dynamic and you don't know its IP, don't add this line.
- Interface
- Optional; this will give your VPN virtual interface a nice name instead of tun0 or such-like. I like to use the name of the remote peer. If you have other loopback interfaces or multiple VPNs, this is especially useful.
- Device
- Path to your virtual network device.
- DeviceType
- The type of virtual network device to use. tap is used so that it will behave like Ethernet.
- BindToAddress
- The local IP address that your tincd will be listening on. So if you are inside a NAT routed network you need to put the private IP address. If this host has a dynamic IP, leave off BindToAddress and just use Port (if omitted, default port 655 is used). Be sure to allow traffic through on iptables to and from your peer! Note that tunnels with IPv6-based endpoints haven't been tested by the author.
- Port
- Those local port that your tincd will be listening on.
- Mode
- Switch mode is required if the topology at each end is not permanently fixed. For instance if you (host A) have two remote hosts B and C in a triangular VPN, and dynamic or fallback routing - on link A-B, C would not normally need to use it, but if one the two links on C fails, C might route through A to get to B, or C might route through B to get to A, so C couldn't be fixed at either the A or B end of the link. If you did add it the topology of either end, packets originating at the wrong end get dropped in router mode.
Create the folder /etc/tinc/hosts. This will enable the host encryption certificate to be put in the correct place, in the next step.
Step 2. Generate encryption keys
The next step is to generate an X.509 private key and corresponding certificate. tinc makes this easy with the --generate-keys
(short form: -K
):
# tincd [-n instance-name] -K
This will by default generate private key in /etc/tinc/rsa_key.priv (mode 600) and the public certificate in /etc/tinc/hosts/Name where Name is the name for this host in tinc.conf.
Step 3. Configure your virtual endpoint
Before your VPN is usable, it'll need an address or two. The VPN will transport either or both IPv4 and IPv6 (and, at least in theory in switch
mode, non-IP traffic as well). The file /etc/tinc/tinc-up is a script run by tincd at start up to configure that tunnel. Here's an example:
#!/bin/sh
ip link set dev "$INTERFACE" address 00:xx:xx:xx:xx:xx
ip address add 10.254.1.254/24 dev "$INTERFACE"
ip address add 2a0a:1100:1018:1::fe/64 dev $INTERFACE
ip link set dev "$INTERFACE" promisc on
ip link set dev "$INTERFACE" up
exit 0
tinc automatically sets the environment variable INTERFACE
before running the program, so you can easily re-use this script.
You don't normally need to set the MAC address, but I do because it makes the IPv6 link-local addresses (fe80::) easy to read (the device needs to be a TAP type, with Mode=switch
). You also only need to enable promiscuous mode if you need to accept multicast, such as OSPF.
Make sure to set tinc-up executable:
# chmod +x /etc/tinc/tinc-up
or your tunnel will fail.
Now edit /etc/tinc/hosts/Name:
Subnet = 10.254.1.254/32
Subnet = 2a0a:1100:1018:1:0:0:0:fe/128
Address = 85.119.82.121
Port = XXXXX
-----BEGIN RSA PUBLIC KEY-----
MII...
...QAB
-----END RSA PUBLIC KEY-----
The Subnet
lines correspond to the definitions in tinc-up. If your public IP is static, Address
and Port
lines correspond to the visible address of your endpoint. The public key was already added by step 2.
Warning: | IPv6 Subnet lines must have every word specified; don't compress the address with double-colon or they'll be ignored. |
Step 4. Enable packet forwarding
Since your BitFolk host is going to be routing IPv6 packets, that function has to be enabled in the kernel. To do this uncomment the line
#net.ipv6.conf.all.forwarding=1
in /etc/sysctl.conf.
Step 5. Exchange data with peer
Copy your /etc/tinc/hosts/Name to the host that will be the other end of your VPS tunnel, and copy their /etc/tinc/hosts/Remote-Name into your /etc/tinc/hosts directory.
Step 6. Launch your VPN
All being well, start the VPN at each end with:
# tincd [-n instance-name]
You can use tcpdump to snoop tunnel traffic before encryption so you can see what's going to the peer:
# tcpdump -i tunnel-name
The command:
# tincd [-n instance-name] -d5 -D
runs the tunnel without daemonizing into the background and with verbosity, so you can debug if things are going badly.
To escape from this mode, Ctrl+z and kill %1
kills it off; it's difficult to escape with Ctrl+c.
Step 7. Launch VPN at boot
Note: | Some versions of CentOS, and possibly other Linux flavours, don't create an init-script. |
Having confirmed that the VPN works in step 5, you most likely want tinc to start at boot-time.
This is easiest with named instances; all that is required is placing the instance name in /etc/tinc/nets.boot.
Then, the existing init script (/etc/init.d/tinc) will start tinc and run the tunnels specified.