I have an OpenVPN setup working with IPv4. In preparation for IPv6 support, I did the following:
- ens3 interface (can reach Internet) got a /64 address from ISP
- I split the /64 into two /65
- ens3 now has ....::/65
- OpenVPN server is configured to use ....:8000::/65
- hence tun0 (OpenVPN device) has ....:8000::1/65
- when clients connect, they get addresses from the proper range assigned, e.g. ....:8000::1000/65
The problem: IPv6 communication only works in outgoing direction. Inbound traffic does not work, because ISP gateway asks for example ICMP6, neighbor solicitation, who has ....:8000::1000
which arrives on ens3 but my server does not respond to this. I guess I have to tell my server and ens3 to accept packets for the ....:8000::/65 range and forward it to tun0?! But I'm not sure how to do this.
In case this is relevant, I use firewalld on a Fedora machine.
EDIT
After @kasperd pointed me to a good explanation of routed prefixes, I went on reading about this.
I haven't found documentation on how I can request a routed prefix from my hosting provider. So I guess I have to stay with my self-split /65 prefixes. Please tell me how to improve if this is not a clean solution!
In order to answer to the mentioned neighbor solicitations, one needs to enable NDP proxying. sysctl -w net.ipv6.conf.all.proxy_ndp=1
For a fixed number of clients, one could now do ip neigh add proxy ....:8000::1000 dev ens3
. To automate this process with OpenVPN, one can add the following two lines to the OpenVPN server config:
script-security 2
learn-address ./proxy-ndp
With proxy-ndp
script beeing
#!/bin/bash
extif=ens3
op="$1"
addr="$2"
if [[ "$addr" != *":"* ]]; then
# no IPv6
exit 0
fi
case "$op" in
add|update)
/usr/sbin/ip neigh replace proxy "$addr" dev "$extif"
;;
delete)
/usr/sbin/ip neigh del proxy "$addr" dev "$extif"
;;
esac
Additionally, if IPv6 forwarding isn't already present, one should enable this with sysctl -w net.ipv6.conf.all.forwarding=1
. The last step is to allow forwarding between the network interfaces. Since I use firewalld, the command is firewall-cmd --direct --add-rule ipv6 filter FORWARD 0 -i tun0 -o ens3 -j ACCEPT
.