OpenVPN and IPv6

Hi all,

I just tried the OpenVPN support for the first time and it appears to work great for IPv4, but IPv6 is different. There’s a tun_turris with an IPv4 address assigned and also a link-local IPv6 address. While I am able to reach the other side over IPv4 without issues whatsoever, I am not able to use and IPv6 addresses of the network on the other side.

I tried pinging the link-local address of the omnia from a connected client, but no packets are returned. Ideally I think the link-local address would work and push a route for the fd53 range that is being used on my internal network.

Does anybody have more experience with this?

Link-local addresses are not Internet routable you need public IPv6 prefix for it to work. Try using some tunnel broker like HENET to get public IPv6. Also you will have to add new firewall rule for port 1194 to allow input for IPv6 to your public IP and possibly edit opvn configuration file and add remote IPv6 because I am not sure if Reforis adds it?. And you will need IPv6 connectivity on your client for it to work

No, public IPv6 addresses would be needed to establish the VPN connection itself over IPv6. (Both sides have public IPv6 addresses btw. but that’s not the point.)

Once the link is established, tun_turris is the interface used for communication across the VPN connection. This interface has link-local addresses assigned and those should work across the VPN connection link, but for some reason they do not. Only IPv4 traverses through the VPN connection tunnel.

I just checked out the configuration file in /var/etc/openvpn-server_turris.conf and it’s clear that IPv6 is simply not enabled.
There’s a line starting with server and then the IPv4 subnet to be used. To use IPv6 there also needs to be a server-ipv6 line. (Above I was mistaken as a route actually requires a non-link local address assigned to the remote party as well (doh).)

Here’s more information:
https://community.openvpn.net/openvpn/wiki/IPv6

So the Turris module for OpenVPN only switches on IPv4 support. I guess I should look at the code in GitLab and see if IPv6 could be added too. IPv6 is supported for establishing the tunnel, but not passing it inside the tunnel.

Member of Turris Team mentioned once that IPv6 prefix could be routed over OpenVPN.

1 Like

Yeah, it should be possible. I’ve been checking out the code:

Right now it’s all about IPv4, but IPv6 could be added. Most ISPs provide a /48 (some provide just a /56), so that should not be a problem. Routing the internal network prefix would also be good.

I hope to find more information on setting up a development environment to work on these projects.

1 Like

Hello @jschwart,
you can update your OVPN server with this (let’s assume you have the fd7a:2bc0:b1dc::/48 block configured in your router):

Take one /64 subnet from the ULA block that will be used as an address pool for client distribution (for example fd7a:2bc0:b1dc:cafe::/64).
Log in the router through the SSH.
Type in

uci set openvpn.server_turris.server_ipv6='fd7a:2bc0:b1dc:cafe::/64'
uci add_list openvpn.server_turris.push='route-ipv6 fd7a:2bc0:b1dc::/48'
uci commit
service openvpn restart

Try to reconnect with the OpenVPN client and you should have the ULA IPv6 addresses assigned on your tunnel interface and be able to ping other devices on your network.

3 Likes

Cool!!! This gets me further indeed, but not completely yet.

The address is assigned to the remote end, the route is set as well on the remote end, but the tun_turris interface does not have fd7a:2bc0:b1dc:cafe::1 on its interface which seems to be the address used as the endpoint for the route. (This is with br-lan having fd7a:2bc0:b1dc::1. I replaced the network with the one my Omnia picked.)

Well, works for me.

root@staging-gw-prg:~# uci show openvpn.server_turris
openvpn.server_turris=openvpn
openvpn.server_turris.dev='tun_turris'
openvpn.server_turris.ca='/etc/ssl/ca/openvpn/ca.crt'
openvpn.server_turris.crl_verify='/etc/ssl/ca/openvpn/ca.crl'
openvpn.server_turris.cert='/etc/ssl/ca/openvpn/01.crt'
openvpn.server_turris.key='/etc/ssl/ca/openvpn/01.key'
openvpn.server_turris.dh='/etc/ssl/ca/openvpn/dhparam.pem'
openvpn.server_turris.server='10.111.111.0 255.255.255.0'
openvpn.server_turris.ifconfig_pool_persist='/tmp/ipp.txt'
openvpn.server_turris.duplicate_cn='0'
openvpn.server_turris.keepalive='10 120'
openvpn.server_turris.persist_key='1'
openvpn.server_turris.persist_tun='1'
openvpn.server_turris.status='/tmp/openvpn-status.log'
openvpn.server_turris.mute='20'
openvpn.server_turris.topology='subnet'
openvpn.server_turris.proto='udp6'
openvpn.server_turris.fast_io='1'
openvpn.server_turris.enabled='1'
openvpn.server_turris.verb='4'
openvpn.server_turris.port='1196'
openvpn.server_turris.push=''\''route 10.97.1.0 255.255.255.0'\'' '\''dhcp-option DNS 8.8.8.8'\''' 'route-ipv6 fdf8:c69:cc49::/48'
openvpn.server_turris.server_ipv6='fdf8:c69:cc49:baba::/64'
root@staging-gw-prg:~# ip a sh dev tun_turris
89: tun_turris: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UNKNOWN group default qlen 500
    link/none 
    inet 10.111.111.1/24 scope global tun_turris
       valid_lft forever preferred_lft forever
    inet6 fdf8:c69:cc49:baba::1/64 scope global 
       valid_lft forever preferred_lft forever
    inet6 fe80::eca8:c419:8542:2aa7/64 scope link stable-privacy 
       valid_lft forever preferred_lft forever

Running TOS6 alpha3

Ah, I’m on 5.4.2. Maybe that’s the difference. The config on my end seems pretty similar. I’ll wait for 6.0 and see what happens then. Thanks a lot for these hints!!

At the same time I’m still curious on exposing this through the GUI. Does the Turris team have any guide on setting up a development environment to a point where one could run the unit tests of the Python code and possibly run a local copy of (Re)Foris?

Can you help with this, @Pepe?

1 Like

Thanks for summoning me here! :wink:
Well, right now, I am not the right person to ask because I will have this week and the following week only limited time for work, so only what I can do right now is to point @jschwart to our documentation and also ask other guys, who can help him.

You can try to look at GitLab CI, which we have there and try to follow the steps there, but I think @mmtj would be the right guy to ask about it!

Yes, this is possible, but only on the router. This should help you:

If you have any questions regarding running a local copy of reForis or you run into some issues, @Aleksan4eg will help you with this one.

1 Like

Hi @jschwart,

thanks for your interest and willingness to provide helping hand with improving the Turris OS! Contributions are always welcome :wink:

Well, there is not single comprehensive guide covering develepement setup & deploy of all components, but you could take a look at following docs:

reForis developement setup
foris controller documentation

Sadly, developement setup (developement, running tests, deploy the code on router) of foris-controller is not completely covered in docs, so please take a look at this draft of docs: README-tests (Draft)

If you intend to make changes to the OpenVPN server config, you would at minimum, need to make changes to foris-controller-openvpn-module (low-level reforis backend).
But depending on the scope of the changes, you might as well want to modify the reForis UI.

We don’t have dedicated TurrisOS container image (LXC, docker), so you will have to try the changes on router.

1 Like

Thanks a lot for all the info!!! I’m going to start reading and trying this out!

Hmm, but there does seem to be an LXC image?

Would this not work for development purposes?

Running the reforis make prepare-dev instruction, I gained a Python virtualenv in which I tried to install the controller. But that controller depends on various things, turris-timezone, turrishw, but also supervisor. That one requires uci.h however, which my Parabola system doesn’t have.

Is there a way to install µCi in that Python venv to let it work? Or could I get supervisor from PyPi? Or should I really do this on another environment?

Hi and sorry for delayed reply.

It might work, at least to certain degree. Perhaps for the hardware independent functionality it could be fine.

But it most likely won’t work for hardware dependent functionality of foris-controller & Turris OS (e.g. network interfaces), as Turris OS is build around certain asumptions about the Turris hardware (NICs, crypto chip, …).
Which would have to be mocked in the container/virtual machine to simulate the Turris hardware.

Besides that, LXC images are currently available only for ARM (aarch64 and armv7l) and PPC architectures, so you would have to run the container on the router anyway.
For development purposes it would be more practical, if there was a way to run Turris OS virtual machine/container on x86 architecture.
For example: In case that you have just one Turris router (deployed as your main router) and then can’t or don’t want to fiddle with the router just for the sake of developement.

Also, unless I am mistaken, there are few pieces missing to make lxc container fully suitable for foris-controller development environment, like passthrough of some hardware (e.g. crypto chip) to the lxc container.

So the way we are developing foris-controller is:

    1. On your computer:
    • 1.1. write the code & tests
    • 2.2 run tests on you computer within heavily mocked test environment
    1. deploy the code to the router and check whether it is really working as expected (i.e. to validate your assumptions in tests and mocks)
1 Like

That is because UCI is used mainly (if not solely) by OpenWrt and not by the regular Linux distros.

Have you installed uci on your system? See the Dockerfile.

Just a quick note: While ubus stands for micro bus, UCI stands for Unified Configuration Interface :wink:

Well, we could publish updater-supervisor to the PyPi, but I doubt that it could be much useful to anyone outside of Turris OS.

So best way to get supervisor, is to have uci installed on your Linux system or docker image and let the pip fetch all dependencies.

Unless the foris-controller is direct dependency of some parts of reforis, then I would use separate virtual envs for reforis and foris-controller. That way you will avoid potential mismatch or collisions of their dependencies.

1 Like