summaryrefslogtreecommitdiffstats
path: root/README.txt
blob: 3b9cd9cceac42c388d3d7c6d839c56a1083df050 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
NPTv6 (IPv6-to-IPv6 Network Prefix Translation) for Linux

Sven-Ola Tuecke

Freifunk

Matthias Schiffer

Freifunk L beck

10-NOV-2011

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Table of Contents

Installation
DKMS Integration
Configuration

    Brief Version
    NAT Behavioral Requirements

IPv6/IPv4 Precedence

    Change gai.conf

These files implement a Linux netfilter target that changes the IPv6 address of
packets. The address change is done checksum neutral, thus no checksum
re-calculation for the packet is necessary. You can change the IPv6 source
address of outgoing packets as well as the IPv6 destination address of incoming
packets. This allows you to map an internal IPv6 address range to a second,
externally used IPv6 address range. IPv6 address mapping is not very similar to
IPv4 network address translation, but one can describe it as some sort of
stateless NAT. The implementation is based on RFC 6296 published here:

https://tools.ietf.org/html/rfc6296

Warning

Using NPTv6 rules together with connection tracking rules such as --ctstate is
currently untested and may not work or may cause dysfunctions.

Installation

NPTv6 implements two pieces of software: a shared library that extends the
ip6tables command and a Linux kernel module. The shared library file adds the
'-j SNPTV6' target (for source address translation) and the '-j DNPTV6' target
(for destination address translation) to the ip6tables command. To build and
install, you need ip6tables installed as well as the necessary headers. The
Linux kernel module requires the Linux source file tree and kernel
configuration files to compile. On a Debian/(EKU)buntu, the following command
prepares the build environment:

sudo apt-get install build-essential linux-headers iptables-dev

Unpack the source tgz archive below /usr/src, change to the new sub-directory
and issue "make" to build. If this compiles without errors, install the
ip6tabless extension by copying libip6t_SNPTV6.so and libip6t_DNPTV6.so to the
iptables module directory, which is probably located under /lib/xtables or /usr
/lib/iptables.

Note

The kernel modules (ip6t_SNPTV6.ko and ip6t_DNPTV6.ko) is not automatically
installed nor loaded into the kernel. You can copy the kernel module file
manually, e.g. with sudo cp ip6t_SNPTV6.ko ip6t_DNPTV6.ko /lib/modules/$(uname
-r)/.

DKMS Integration

If the next system update needs to install a new kernel version, you also need
to re-compile/re-install the NPTv6 kernel modules. With Debian/(EKU)buntu, this
can be automated with the Dynamic Kernel Module Support Framework (DKMS). For
this, the dkms.conf file is included with the NPTv6 source file package.
Install DKMS with the following command:

sudo apt-get install dkms

If not already in place, move/unpack the NPTv6 source file archive below /usr/
src/. To register the NPTv6 source to DKMS and compile/install, issue these
commands:

sudo dkms add -m ip6t_NPTV6 -v 0.6
sudo dkms build -m ip6t_NPTV6 -v 0.6
sudo dkms install -m ip6t_NPTV6 -v 0.6

Read DKMS details here: https://wiki.kubuntu.org/Kernel/Dev/DKMSPackaging

Configuration

Brief Version

You always need to add two ip6tables-rules to your netfilter configuration. One
rule matches outgoing packets and changes their IPv6 source address. The second
rule matches incoming packets and reverts the address change by altering their
IPv6 destination address. To following commands correspond to the “/48 Prefix
Mapping Example” given in RFC6296:

ip6tables -t mangle -A PREROUTING  -i eth0 -d 2001:0DB8:0001::/48 -j DNPTV6 --to-destination FD01:0203:0405::/48
ip6tables -t mangle -A POSTROUTING -o eth0 -s FD01:0203:0405::/48 -j SNPTV6 --to-source 2001:0DB8:0001::/48

This example is also printed to the screen if you issue ip6tables -j SNPTV6
--help. By design, you cannot use prefix lengths longer than 64.

NAT Behavioral Requirements

RFC 6296 states that NPTv6 translators must support hairpinning behaviour. This
means that when an NPTv6 Translator receives a datagram on the internal
interface that has a destination address that matches the site's external
prefix, it will translate the datagram and forward it internally. While it is
possible that the network works correctly without this depending on the
configuration of the external router, it is desirable to have hairpinning
behaviour. The following iptables rules will enable this:

ip6tables -t mangle -A PREROUTING -d 2001:0DB8:0001::/48 -j MARK --set-mark 42
ip6tables -t mangle -A PREROUTING -d 2001:0DB8:0001::/48 -j DNPTV6 --to-destination FD01:0203:0405::/48
ip6tables -t mangle -A POSTROUTING -m mark --mark 42 -s FD01:0203:0405::/48 -j SNPTV6 --to-source 2001:0DB8:0001::/48
ip6tables -t mangle -A POSTROUTING -o eth0 -s FD01:0203:0405::/48 -j SNPTV6 --to-source 2001:0DB8:0001::/48

If the router running NPTv6 is offering services itself, additional rules are
necessary for the services to be reachable by the external address:

ip6tables -t mangle -A OUTPUT -d 2001:0DB8:0001::/48 -j MARK --set-mark 42
ip6tables -t mangle -A OUTPUT -d 2001:0DB8:0001::/48 -j DNPTV6 --to-destination FD01:0203:0405::/48
ip6tables -t mangle -A INPUT -m mark --mark 42 -s FD01:0203:0405::/48 -j SNPTV6 --to-source 2001:0DB8:0001::/48

IPv6/IPv4 Precedence

With most Linux distributions you will notice that your browser does not show
the IPv6 version of a web site that is multi-homed when using ULA addresses for
your IPv6 Internet connection. The reason for this is an add on to the RFC 3484
rules that is compiled into the libc. The pre-installed /etc/gai.conf file will
give you a hint on this.

In short: the getaddrinfo() library function rates a private IPv4 address
higher than the ULA IPv6 address when choosing the transport protocol for a new
Internet connection if this add on to the RFC 3484 rules is compiled in. For
this reason, you may want to change the precedence rules within /etc/gai.conf
(see Change gai.conf).

Change gai.conf

The getaddrinfo() library function manages lists of label, precedence, and
scope4 type entries. If the /etc/gai.conf file does not provide a single entry
for a particular type, the compiled-in list is used. For this reason, you
cannot uncomment a single entry to overwrite the default. You need to uncomment
all entries of a particular type for this. The “label” lines compare source
addresses, the “precedence” lines compare destination addresses.

Procedure 1. Change IPv6 Precedence

 1. Open the /etc/gai.conf file as root user, e.g. by executing sudo nano /etc/
    gai.conf.

 2. Remove the leading hash character from the 8 lines starting with “#label”.

 3. Re-add the hash character to the line stating “#label fc00::/7 6”.

 4. Save the file.

 5. Restart your browser and re-try to browse to a multi-homed web site.

The above procedure removes the difference between standard IPv6 source
addresses and ULA type private IPv6 source addresses. Anything else is
unchanged.