OpenVPN and IPv6
OpenVPN and IPv6
OpenVPN and IPv6
Success!
Man, oh man, the hours of research and experimentation it took to nally
discover the rightoptions in OpenVPN to make my IPv6 routing go. Still, now I
know how it works, and now I can explain it to you.For the impatient, the
trickis to use the client-con g-dir option on the server.
Starting out, Ill show the con guration les for my setup, then explain how
things work.
Because OpenVPN requires that I con gure the routing information I want to set
up using a separate le per client, I decided to additionally put my site-speci c
routing information into a separate le /etc/openvpn/ccd/routes.conf,and
include it from the main con guration.Turns out, setting up this way you only
have to put 1 or 2 lines in that le.
port 1194
proto udp
dev tun
user nobody
group nogroup
persist-key
persist-tun
status openvpn-status.log
verb 4
mute 20
mute-replay-warnings
# MTU magic
tun-mtu 1480
fragment 1428
mssfix 1428
;comp-lzo
# http://winaero.com/blog/speed-up-openvpn-and-get-faster-speed-over-its-
channel/
# suggested for use over UDP:
sndbuf 212992
rcvbuf 212992
push "sndbuf 212992"
push "rcvbuf 212992"
# Private ULA network for the tunnel itself. Doesn't get routed.
;server-ipv6 fd00::/112
https://cuzimageek.wordpress.com/2016/09/21/openvpn-and-ipv6/ 2/15
8. 7. 2017 OpenVPN and IPv6 Because I'm a geek
ca ca.crt
cert server.crt
key server.key
tls-auth ta.key 0
dh dh2048.pem
(This should hopefully work without modi cation where youre at but
remember if yours is di erent enough that this hiccups, please dont get angry
at me!)
Now, /etc/openvpn/ccd/routes.conf. This will be di erent for every site, and
uses the information from the tunnelbroker.nettunnel detail page.
https://cuzimageek.wordpress.com/2016/09/21/openvpn-and-ipv6/ 3/15
8. 7. 2017 OpenVPN and IPv6 Because I'm a geek
# Routed /64:
iroute-ipv6 2001:db8:b:b02::/64
# I've assigned megan the first subnet from our routed /48.
# the :0: here makes explicit what is implied
iroute-ipv6 2001:db8:1234:0::/64
If you will onlyever have one client, you can simplyname this leccd/DEFAULT
instead.
The client
For the client (in my case, a Raspberry Pi 1B running Debian jessie), I again
removed the client-speci c data into its own le, which I named
/etc/openvpn/client.params.
###############################################
# client-side OpenVPN config file
# for connecting to IPv6 gateway
tls-client
cipher AES-128-CBC
# MTU magic
tun-mtu 1480
fragment 1428
# set on the server side
;mssfix 1428
;comp-lzo
https://cuzimageek.wordpress.com/2016/09/21/openvpn-and-ipv6/ 4/15
8. 7. 2017 OpenVPN and IPv6 Because I'm a geek
persist-key
persist-tun
ns-cert-type server
config client.params
Once again, this is the generic portion of the con guration, with nothing site-
speci c.
# Here, we have inlined ca, cert, key, and tls-auth key files.
#ca ca.crt
#cert client.crt
#key client.key
#tls-auth ta.key 1
<ca>
...
</ca>
https://cuzimageek.wordpress.com/2016/09/21/openvpn-and-ipv6/ 5/15
8. 7. 2017 OpenVPN and IPv6 Because I'm a geek
<cert>
...
</cert>
<key>
...
</key>
<tls-auth>
...
</tls-auth>
Note that with Debian jessie on the Pi, you have to enable the OpenVPN
connection by name using systemctl:
Routing, part 1
https://cuzimageek.wordpress.com/2016/09/21/openvpn-and-ipv6/ 6/15
8. 7. 2017 OpenVPN and IPv6 Because I'm a geek
Routing, part 1
Setting up OpenVPN is simple enough, there are recipes all over the Internet for
doing that. But in my speci c case, I also want to tunnelIPv6 tra c through the
VPN. So after the clientis connected, some kind of routing information will
have to be con gured, such that the server knows that the given client is
responsible for a given network (or networks) that lives down that
connection, and the client knows that the rest of the IPv6 Internet lives up
the VPN connection.
In order to use the client-con g-dir option, we need to use the server option
(and in our case, server-ipv6 as well). And in order to use server, we are
required to use TLS (tls-server and tls-client).
And in order to use TLS, we must createkeys and certi cates for the server and
for each client (even if theres only one).
https://cuzimageek.wordpress.com/2016/09/21/openvpn-and-ipv6/ 7/15
8. 7. 2017 OpenVPN and IPv6 Because I'm a geek
Copying everything around and not missing any details was a little confusing to
straighten out. But in searching for instructions on how to do this properly, I
found the concept of inline les for OpenVPN con guration. Speci cally, rather
than require a le like client.crt to be present, and to be mentioned in the
con g le like so:
cert client.crt
we can instead inline the contents of the le client.crt directly into the
con g le, using an XML-like syntax:
<cert>
[certificate data]
</cert>
This can be done with ca, cert, key, dh (only required for the server), and tls-
auth.
Normally, the tls-auth directive looks like this, with a 0 for the server side, and
1 for the client side:
tls-auth ta.key 0
However, the inline le support doesnt handle the extra number at the end.
Insteadthe key-direction optionis used to specify thesecond value.
key-direction [0 or 1]
So, after generating all of the certi cates, and cut/pasting the le data inline,
the certi cate and key data will looklook about like this:
https://cuzimageek.wordpress.com/2016/09/21/openvpn-and-ipv6/ 8/15
8. 7. 2017 OpenVPN and IPv6 Because I'm a geek
<ca>
...
</ca>
key-direction [0 or 1]
<tls-auth>
...
</tls-auth>
<cert>
...
</cert>
<key>
...
</key>
It should be noted that if the client con guration is all present in a single le
and renamed to have a .ovpn extension, this is the normal way to distribute a
con guration le for the GUI version of OpenVPN, and to work with things like
Network Manager in Ubuntu.
Ive managed to distill my con guration down so I could divide it into the part
that is always the same, and the part that is site or client dependent. OpenVPN
has no problem reading external les for additional con g information, so Ive
got my setup for both client and server down to a main con g le that is static,
and a le thats included that has my speci c address information.
On the server side,I have to use a ccd/ directory anyway, and since that folder
holds client-speci c data on routing, it made sense to me as a place to store the
secondary include le routes.conf.
https://cuzimageek.wordpress.com/2016/09/21/openvpn-and-ipv6/ 9/15
8. 7. 2017 OpenVPN and IPv6 Because I'm a geek
For the server-ipv6 option, at rst I had a problem where do I get the
addresses from, to go on each end of the tunnel? Since I hadnt yet discovered
the client-con g-dir option, using private addresses didnt seem to
work.Isolved it at rst by splitting my assigned /64 in half, into two /65
networks. Then I used the second half of the network
(2001:db8:b:b02:8000::/65 vs 2001:db8:b:b02:0000::/65) for the tunnel
endpoint addresses. Which worked, but was tricky to deal with because most
everything expects to see /64 networks, and NOT /65 (speci cally, dnsmasq has
a way to specify the bits, but unless I used a small, static pool of addresses for
DHCP, the con g wouldnt read the number 65 in the con gurationwithout
throwing an error).
server-ipv6 2001:db8:b:b02:8000::/65
Another optionI consideredwas to use the whole /64 for justthe point-to-point
connection, and then useone or more of the networks ofmy routed /48 on the
local side.
https://cuzimageek.wordpress.com/2016/09/21/openvpn-and-ipv6/ 10/15
8. 7. 2017 OpenVPN and IPv6 Because I'm a geek
confusing about this, because the o cial RFC documents reserve the networks
FC00::/7, but whats not immediately obvious is that the /7 means the nal bit
is not speci ed but the network range speci ed by 0 is invalid! With that bit
holding a 1, the valid neworke range becomes FD00::/8. Also according to the
docs, you are supposed to pick a string of 40 random bitsto ll in the rest of the
rst 64 bits of the network address, in case your organization ever connects
with another, and so your individual ULA addresses wont con ict. This is of
course, way, WAY more than Im worried about, so I just went with the simplest
version, using a /112 netmask, which restricts the address pool to the 65k
addresses available in the last 2 bytes:
server-ipv6 fd00::/112
And it WORKED! It worked exactly as I had originally hoped it would, and freed
up the addresses I had used out of my routed /64, and simpli ed my local server
setup considerably.
One thing changed in a way I didnt expect wasthatnow traceroute6 (or tracert
on Windows) showed the OpenVPN hop quite clearly:
C:\>tracert -d ipv6.he.net
1 1 ms 1 ms <1 ms 2001:db8:b:b02::1
2 25 ms 24 ms 25 ms fd00::1
3 42 ms 36 ms 36 ms 2001:db8:a:b02::1
4 36 ms 43 ms 32 ms 2001:470:0:9b::1
5 54 ms 69 ms 62 ms 2001:470:0:1fe::1
6 59 ms 56 ms 51 ms 2001:470:0:2f::1
7 53 ms 53 ms 56 ms 2001:470:0:64::2
Trace complete.
https://cuzimageek.wordpress.com/2016/09/21/openvpn-and-ipv6/ 11/15
8. 7. 2017 OpenVPN and IPv6 Because I'm a geek
But I wasnt done ddling with it yet. Mentioned in the article on ULAs was that
there was an older version of the concept, called Site-Local Addresses. The only
di erence from MY point of view as a sysadmin was that the addresses started
with FExxinstead of FDxx. WhenI tried it, It worked just the same as the ULA
did, with one important di erence: this time, the traceroute did NOT show the
address of the OpenVPN endpoint, but the real IPv6 address of the next hop:
C:\>tracert -d ipv6.he.net
1 1 ms 1 ms 1 ms 2001:db8:b:b02::1
2 27 ms 25 ms 25 ms 2001:db8:a:b02::2
3 62 ms 43 ms 39 ms 2001:db8:a:b02::1
4 46 ms 37 ms 35 ms 2001:470:0:9b::1
5 62 ms 59 ms * 2001:470:0:1fe::1
6 54 ms 53 ms 52 ms 2001:470:0:2f::1
7 69 ms 55 ms 55 ms 2001:470:0:64::2
Trace complete.
Since its private, and it works, and does so in an interesting and useful way,
Im sticking with that. So I picked a valid Site Local pre x thats easy to
remember. Now, my v6_server.conf says:
server-ipv6 feed::/112
And when my client connects, it gets the endpoint address feed::1000, with an
upstream address (the server) as feed::1.
Server Routes
The leroutes.conf on the server needs to have aroute option for every
network this server intends to handle. Speci cally, we need one for our
assigned /64 network, and if we have a routed /48, one for that as well.
CCD Files
https://cuzimageek.wordpress.com/2016/09/21/openvpn-and-ipv6/ 12/15
8. 7. 2017 OpenVPN and IPv6 Because I'm a geek
CCD Files
The le included by the client-con g-dir option isloaded when a client with
that name (as listed in their client.crt le) connects. If you only ever intend to
run one client, you can just name this le ccd/DEFAULT.
The le must contain aniroute directive for each network that client is
responsible for. If you only have the single /64, it only needs 1 line:
iroute-ipv6 2001:db8:b:b02::/64
If, as in my case, you have a routed /48, you can direct the entire thing to the
client with another, similar line:
iroute-ipv6 2001:db8:123::/48
Once the routing is correct, the most critical piece of understanding and setup
involveschoosing the correct MTU settings. The MTU is the Max Transmission
Unit, which means the largest packet size, including headers, that is allowed to
go over a given wire (Layer 2 link). For example, Ethernet has a real wire, and
https://cuzimageek.wordpress.com/2016/09/21/openvpn-and-ipv6/ 13/15
8. 7. 2017 OpenVPN and IPv6 Because I'm a geek
the MTU is 1500. WiFi has a radio wire, and also uses 1500.Usually this is
handled without any user intervention.
However, all this tunneling adds a few wrinkles. First of all, the initial
6in4tunnel immediately reduces MTU by 20 bytes down to 1480, because the
information being transferred consists of IPv6 headers and data, INSIDE of a
packet with a 20-byte IPv4 header.
And thenOpenVPN adds its own serious chunk of overhead data to the packet
data, which is not always the same number of bytes (depending on how its
con gured), and is very non-obvious to determine because of the way OpenVPN
handles its own internal bu ers. Normally, OpenVPN has reasonable default
settings that work ne, however our case is enough di erent that the defaults
wont work out of the box. The short version is,even if the rest of the
tunneling is set up correctly, youre going to have nothing but problems until
the MTU is correctly accounted for. This is mostly becausethe VPN tunnel eats
the ICMP messages that would normally cause this to be automatically and
transparently adjusted without you needing to know or care about it.
I knew fromthe beginning of this project that I would be serving IPv6 from this
machine, and for that reason I was drawn to using dnsmasq for my DHCP
needs, as it can handle IPv4 DHCP requests, IPv6 DHCP requests, and IPv6
autocon guring router advertisements, all in addition to functioning as a DNS
forwarder and cache.
It turns out that dnsmasq will autocon gure its IPv6 information using the
assigned address of giveninterface. This meansI dont have to add my speci c
network con guration to/etc/dnsmasq.conf.
https://cuzimageek.wordpress.com/2016/09/21/openvpn-and-ipv6/ 14/15
8. 7. 2017 OpenVPN and IPv6 Because I'm a geek
Im still playing with the optimum con guration, but for now it looks as if the
ra-stateless option makes most clients work, ra-names is the preferred mode
for iPhone/iPad, and ra-advrouter was what made my Android phone start
working correctly. I still havent managed to gure out the distinctions between
all of the modes yet, but this con gurationworks, so thats good enough for
now.
Advertisements
https://cuzimageek.wordpress.com/2016/09/21/openvpn-and-ipv6/ 15/15