Timothy Baldwins answer put me on the right track, although the answer was rather cryptic. IPv6 neighbor advertisements/solicitation is like ARP for IPv6. It's used to "see" other machines on the network. The router send a neighbor solicitation on which the machine (server or client) should reply on with a neighbor advertisement.
Even with net.ipv6.conf.all.forwarding
set to 1
, neighbor advertisements and solicitations are not forwarded. To make eth0 forward neighbor advertisements and solicitations, eth0 should be set as proxy for the IPv6 address of the client behind tap0, and proxying for neighbor stuff should be enabled for eth0:
echo 1 > /proc/sys/net/ipv6/conf/eth0/proxy_ndp
/sbin/ip -6 neigh add proxy 2001:db8::100:abc:2 dev eth0
Unfortunately, it's not possible to retrieve the list of proxies added, nor does ip -6
show error messages on repeatedly executing the command. Neither am I sure if "neigh del proxy" works, it does not give an error message and the C source is not really meaningful to me.
As I do not want to do everything manually, I've created a script which does the work for me.
Server configuration
IPv6 addresses are based on the IPv4 part (the 1 in 10.8.0.1). The prefix and netmask are stored in /etc/openvpn/variables
.
The next steps are made for setting up OpenVPN with encrypted IPv4/IPv6 connectivity to the Internet over a native IPv4 connection. RSA keys and tls-auth are used for authentication and MITM prevention.
/etc/openvpn/variables
contains variables which are used for the up script (run on startup, after creation of tap0 device) and client-connect script (run after the client has authenticated).
# this prefix is handled out by the provider, replace it with your own prefix
prefix=2001:db8::abc
# netmask, 2001:db9::abc:0000 - 2001:db9::abc:FFFF
prefixlen=112
/etc/openvpn/server-clientconnect.sh
is executed as root and makes sure that IPv6 is routed properly by adding the IPv6 address to the eth0 proxy. Because client-connect
is called after OpenVPN switched to the user specified by the User
setting, sudo
is needed to give the script sufficient permissions to run as root. Of course, variables should be checked before using, the number should be between and including 2 ad 254. (1 is the gateway, 255 the broadcast address).
#!/bin/sh
. /etc/openvpn/variables
if [ -z "$ifconfig_pool_remote_ip" ]; then
echo "Missing environment variable."
exit 1
fi
ipp=$(echo "$ifconfig_pool_remote_ip" | cut -d. -f4)
if ! [ "$ipp" -ge 2 -a "$ipp" -le 254 ] 2>/dev/null; then
echo "Invalid IP part."
exit 1
fi
hexipp=$(printf '%x' $ipp)
/sbin/ip -6 neigh add proxy $pfx:$hexipp dev eth0
To make this work, the user vpn
should be allowed to run the script while preserving $ifconfig_pool_remote_ip
which contains the remote network IPv4 address. Add the next lines to the sudoers file by executing sudo visudo
and appending:
Defaults:vpn env_keep=ifconfig_pool_remote_ip
vpn ALL=NOPASSWD: /etc/openvpn/server-clientconnect.sh
/etc/openvpn/server-up.sh
enables IPv4, IPv6 forwarding (eth0+tap0 did not work, it really had to be all
) and neighbor proxy on eth0. It adds the gateway address to servers tap0
too.
#!/bin/sh
. /etc/openvpn/variables
/sbin/ip -6 addr add $pfx:1/$pfxlen dev $dev
echo 1 > /proc/sys/net/ipv4/ip_forward
echo 1 > /proc/sys/net/ipv6/conf/all/forwarding
echo 1 > /proc/sys/net/ipv6/conf/eth0/proxy_ndp
Finally, the OpenVPN configuration file at /etc/openvpn/internet.conf
:
proto udp
dev tap
ca ca.crt
cert server.crt
key server.key
dh dh1024.pem
server 10.8.0.0 255.255.255.0
script-security 2
up /etc/openvpn/server-up.sh
client-connect "/usr/bin/sudo -u root /etc/openvpn/server-clientconnect.sh"
# encrypt all traffic
push "redirect-gateway def1"
# keep the same IP addresses each time
ifconfig-pool-persist ipp.txt
keepalive 10 120
tls-auth ta.key 0
cipher BF-CBC
comp-lzo
# OpenVPN will switch to this user, it is also used for sudo
user vpn
group vpn
persist-key
persist-tun
For completeness, permissions and ownerships of files in /etc/openvpn
:
drwx------ root root .
-rw------- root root ca.crt
-rw------- root root dh1024.pem
drwx------ root root easy-rsa <-- left from creation of keys
-rw------- root root ipp.txt
-rwx------ root root server-clientconnect.sh
-rw------- root root internet.conf
-rw------- root root variables
-rwx------ root root server-up.sh
-rw------- root root server.crt
-rw------- root root server.key
-rw------- root root ta.key
-rwx------ root root update-resolv-conf <-- this was installed by default
Firewall settings:
itpables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -s 10.8.0.0/24 -i tap0 -o eth0 -j ACCEPT
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
ip6tables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
ip6tables -A FORWARD -s 2001::db8::abc:0/112 -i tap0 -o eth0 -j ACCEPT
Configuration on client
/etc/openvpn/client.conf
:
client
dev tap
proto udp
remote 178.21.112.251 1194
script-security 2
up /etc/openvpn/client-up.sh
resolv-retry infinite
nobind
user nobody
group nogroup
persist-key
persist-tun
ca ca.crt
cert home.crt
key home.key
ns-cert-type server
tls-auth ta.key 1
cipher BF-CBC
comp-lzo
ta.key
and ca.key
are the same files from the server. home.key
and home.crt
are files, created on the server.
client-up.sh
adds the IPv6 address and route (based on IPv4 address):
#!/bin/sh
pfx='2001:db8::abc'
pfxlen=112
hexippart=`printf '%x' "$(echo $ifconfig_local | cut -d. -f4)"`
/sbin/ip -6 addr add $pfx:$hexippart/$pfxlen dev $dev
/sbin/ip -6 route add default via $pfx:1 dev $dev
The guide at http://www.ipsidixit.net/2010/03/24/239/ was very helpful and OpenVPN manual page is useful for information about various settings.
Best Answer
A tunnel is not a solution to the problem you are facing.
You have a direct physical connection between the two machines you would connect by a tunnel, so there is no need for the tunnel in the first place. Any addressing you wanted to perform on the tunnel can be done directly on the Ethernet connection between the two endpoints. And doing it on Ethernet rather than on a tunnel takes away the additional complexity in the configuration as well as the encapsulation overhead.
You do have another problem, which is that you don't have any address to assign to that connection. But using IPv6 over Ethernet or IPv6 over a tunnel doesn't change that. They both need the same number of addresses (except that doing it over Ethernet would allow that prefix to be used by the entire LAN).
If you want to do this correctly, you need a prefix for the LAN, which must be routed to your router. From your description you currently only have a link prefix for the WAN. That is not enough, since you need another link prefix for the LAN, which must be taken from a prefix routed to your router.
I know of one standardized protocol for setting up this routed prefix, that is DHCPv6. The router should be sending a DHCPv6 request on its WAN interface and request a routed prefix. A routed /64 is sufficient for what you want to do now, but you may as well go for a /48, /56, or /60 right away, since you'll probably soon find uses for more than a single /64 on your LAN. The alternative to DHCPv6 with prefix delegation is for your ISP to configure a static route for the prefix routed to your router.
If you find that your ISP does not have any DHCPv6 server, or that it won't even delegate a /60 or a /64, then you should contact your ISP to ask how to get a prefix routed to your router.
If they refuse to route a prefix to your once you have asked for it, then it is time to look for workarounds. The two workarounds I know of are bridging and neighbor discovery proxying. From the ISPs point of view, they will both behave the same, and they will cause memory consumption in their router to go up. They could have avoided that extra memory usage by routing a prefix to you instead.
You say neither workaround is supported by your router firmware. I think that means you will need to upgrade to a firmware that supports it.
You are also asking about 6to4 which is unrelated. I'd rate 6to4 as mostly irrelevant to your setup. Though if you can do so on your router firmware, I'd enable a 6to4 relay on the router, because that will give you more reliable communication when communicating with somebody who is using 6to4. I'd enable a Teredo relay for the exact same reason, that is very convenient if you ever need to connect back home from a laptop on some IPv4-only network.