IPv6/VPNs: Difference between revisions

From BitFolk
Jump to navigation Jump to search
(Add a step to enable IPv6 packet forwarding, and defeat the Bitfolk Debian install's hard disabling of this feature.)
(Update for nmew #48s and 2020s)
Line 1: Line 1:
This page lists some of the techonologies you can use to create VPNs that utilize IPv6. You might want to use it to IPv6-enable your home, for instance.
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 ==
== Using tincd ==
<br />
{{warning|If you want to route a /64 or larger to a remote site then you will need to first request an IPv6 /56 from support, as BitFolk VPSes by default come with only a single /64.}}
<br />
These instructions have been tested with at least the following packaged versions of tinc:
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.16 on CentOS 5.x/6.x
Line 10: Line 26:
* 1.0.11-1 on Ubuntu 10.04 (Lucid)
* 1.0.11-1 on Ubuntu 10.04 (Lucid)


Configurations are stored in <tt>/etc/tinc</tt>. If you want to run multiple VPN tunnels you can create "named instances" by utilising a folder structure, i.e. <tt>/etc/tinc/&lt;instance-name&gt;</tt>
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/&lt;instance-name&gt;'''
 
'''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


Tinc directs traffic to named "peers", which are static or dynamic remote host:port combinations of remote tinc daemons.
<syntaxhighlight lang="text">
The Linux TUN/TAP driver is required to operate tinc, and is enabled by default, but it doesn't hurt to have
tun
<syntaxhighlight>/modprobe tun
</syntaxhighlight>
</syntaxhighlight>
in your <tt>/etc/rc.local</tt> file.
 
in a file such as '''/etc/modules-load.d/tun.conf''' file.


=== Step 1. Create the basic config file ===
=== Step 1. Create the basic config file ===
<br />
{{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.}}
{{warning|In this document, references to <b>/etc/tinc</b> should be substituted with <b>/etc/tinc/instance-name</b>, as appropriate where named instances are to be used.}}
<br />


Create a file '''/etc/tinc/tinc.conf'''; a sample is below:
Create a file '''/etc/tinc/tinc.conf'''; a sample is below:
<syntaxhighlight>
<syntaxhighlight lang="text">
Name          = tegan
Name          = tegan
ConnectTo    = susan
ConnectTo    = susan
Line 30: Line 47:
Device        = /dev/net/tun
Device        = /dev/net/tun
DeviceType    = tap
DeviceType    = tap
BindToAddress = 85.119.83.XXX
BindToAddress = 85.119.82.121
Port          = 655
Port          = 655
Mode          = switch
Mode          = switch
</syntaxhighlight>
</syntaxhighlight>


; 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.
; 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.
; 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.
; 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.
; Device        : Path to your virtual network device.
Line 47: Line 64:


=== Step 2. Generate encryption keys ===
=== 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 <tt>--generate-keys</tt> (short form: <tt>-K</tt>):
The next step is to generate an X.509 private key and corresponding certificate. '''tinc''' makes this easy with the <code>--generate-keys</code> (short form: <code>-K</code>):


<syntaxhighlight>
<syntaxhighlight lang="text">
# tincd [-n instance-name] -K
# tincd [-n instance-name] -K
</syntaxhighlight>
</syntaxhighlight>
Line 56: Line 73:


=== Step 3. Configure your virtual endpoint ===
=== 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:
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 <code>switch</code> 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:


<syntaxhighlight>
<syntaxhighlight lang="text">
#!/bin/sh
#!/bin/sh


ip link set dev $INTERFACE address 00:xx:xx:xx:xx:xx
ip link set dev "$INTERFACE" address 00:xx:xx:xx:xx:xx
ip address add 10.xx.xx.254/24 dev $INTERFACE
ip address add 10.254.1.254/24 dev "$INTERFACE"
ip address add 2001:ba8:xxxx:xxxx::fe/64 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" promisc on
ip link set dev $INTERFACE up
ip link set dev "$INTERFACE" up


exit 0
exit 0
</syntaxhighlight>
</syntaxhighlight>


Tinc automatically sets the environment variable <tt>INTERFACE</tt> before running the program, so you can easily re-use this script.  
'''tinc''' automatically sets the environment variable <code>INTERFACE</code> 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 <tt>Mode=switch</tt>). You also only need to enable promiscuous mode if you need to accept multicast, such as OSPF.
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 <code>Mode=switch</code>). You also only need to enable promiscuous mode if you need to accept multicast, such as OSPF.


Make sure to set '''tinc-up''' executable:
Make sure to set '''tinc-up''' executable:


<syntaxhighlight>
<syntaxhighlight lang="text">
# chmod +x /etc/tinc/tinc-up
# chmod +x /etc/tinc/tinc-up
</syntaxhighlight>
</syntaxhighlight>
Line 84: Line 101:
Now edit '''/etc/tinc/hosts/''Name''''':
Now edit '''/etc/tinc/hosts/''Name''''':


<syntaxhighlight>
<syntaxhighlight lang="text">
Subnet  = 10.xx.xx.254/32
Subnet  = 10.254.1.254/32
Subnet  = 2001:ba8:xxxx:xxxx:0:0:0:fe/128
Subnet  = 2a0a:1100:1018:1:0:0:0:fe/128
Address = 212.13.195.XXX
Address = 85.119.82.121
Port    = XXXXX
Port    = XXXXX
-----BEGIN RSA PUBLIC KEY-----
-----BEGIN RSA PUBLIC KEY-----
Line 95: Line 112:
</syntaxhighlight>
</syntaxhighlight>


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.
The <code>Subnet</code> lines correspond to the definitions in '''tinc-up'''. If your public IP is static, <code>Address</code> and <code>Port</code> 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.}}
{{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 ===
=== 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
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


<syntaxhighlight>
<syntaxhighlight lang="text">
#net.ipv6.conf.all.forwarding=1
#net.ipv6.conf.all.forwarding=1
</syntaxhighlight>
</syntaxhighlight>


in /etc/sysctl.conf. If you're running the Bitfolk-provided Debian install, then it explicitly disables IPv6 routing in the address configuration file, which will override your change to /etc/sysctl.conf. To avoid this you will also need to comment out or remove the lines
in '''/etc/sysctl.conf'''.
 
<syntaxhighlight>
      pre-up echo "/proc/sys/net/ipv6/conf/default/forwarding=0" && echo 0 > /proc/sys/net/ipv6/conf/default/forwarding || true
      pre-up echo "/proc/sys/net/ipv6/conf/all/forwarding=0"    && echo 0 > /proc/sys/net/ipv6/conf/all/forwarding    || true
</syntaxhighlight>
 
 
in /etc/network/interfaces
 


=== Step 5. Exchange data with peer ===
=== Step 5. Exchange data with peer ===
Line 123: Line 131:
All being well, start the VPN at each end with:
All being well, start the VPN at each end with:


<syntaxhighlight>
<syntaxhighlight lang="text">
# tincd [-n instance-name]
# tincd [-n instance-name]
</syntaxhighlight>
</syntaxhighlight>
Line 129: Line 137:
You can use '''tcpdump''' to snoop tunnel traffic before encryption so you can see what's going to the peer:
You can use '''tcpdump''' to snoop tunnel traffic before encryption so you can see what's going to the peer:


<syntaxhighlight>
<syntaxhighlight lang="text">
# tcpdump -i tunnel-name
# tcpdump -i tunnel-name
</syntaxhighlight>
</syntaxhighlight>
Line 135: Line 143:
The command:
The command:


<syntaxhighlight>
<syntaxhighlight lang="text">
# tincd [-n instance-name] -d5 -D
# tincd [-n instance-name] -d5 -D
</syntaxhighlight>
</syntaxhighlight>
Line 141: Line 149:
runs the tunnel without daemonizing into the background and with verbosity, so you can debug if things are going badly.
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, <tt>^Z</tt> and <tt>kill %1</tt> kills it off; it's difficult to escape with <tt>^C</tt>.
To escape from this mode, {{Key press|Ctrl|z}} and <code>kill %1</code> kills it off; it's difficult to escape with {{Key press|Ctrl|c}}.


=== Step 7. Launch VPN at boot ===
=== Step 7. Launch VPN at boot ===
Line 147: Line 155:
{{Note|Some versions of CentOS, and possibly other Linux flavours, don't create an init-script.}}
{{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.
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'''.
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.
Then, the existing init script ('''/etc/init.d/tinc''') will start '''tinc''' and run the tunnels specified.
 
If you don't have an init-script, the following code in '''/etc/rc.d/rc.local''' is functionally equivalent:
 
<syntaxhighlight>
for i in `cat /etc/tinc.d/nets.boot`; do
  /usr/sbin/tincd -n $i
done
</syntaxhighlight>

Revision as of 01:45, 31 October 2024

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