通过 openvpn 隧道路由公共 ipv6 流量

Ikk*_*kke 13 routing ipv6 openvpn

我想要做的是通过 vpn 隧道路由 IPv6 流量。这样,我应该能够在不支持 IPv6 的网络中使用 IPv6。

我有一个分配了 IPv6 块的 VPS。这个块的一部分我想用于 openvpn 客户端。我想到的范围是2001:db8::111:800:0/112(前缀是匿名的),因为 openvpn 只支持 /64 和 /112 作为子网。

通过隧道的 IPv6 已经在工作,从客户端,我可以 ping 服务器 ( 2001:db8::111:800:1),也可以连接服务器上的接口 (2001:db8::111:100:1002001:db8:216:3dfa:f1d4:81c0)。

但是,当尝试从客户端 ping google.com 时,我没有收到任何响应(ping 超时)。为了调试这个问题,我使用 tcpdump 来捕获服务器上的流量,我可以看到 ping 数据包出去,但没有回复回来。向 ip6tables 添加日志规则显示相同,数据包出去,但没有进入。

我使用了一个在线跟踪路由工具,它从我的服务器获取超时。我也试过直接在接口上设置ip,确实导致ip( 2001:db8::111:800:1001)可达,所以我认为这是路由问题。

我已经通过/proc/sys/net/ipv6/conf/all/forwarding. ip6tables 对所有链都有策略允许。

我的问题是,Linux 到底需要什么才能接受未分配给接口的 ip 的数据包并进一步路由它?仅仅存在一条路线似乎还不够。

这是我的客户端和服务器的设置。如果需要更多信息,请告知。

客户

# ip -6 addresses
10: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qlen 100
    inet6 2001:db8::111:800:1001/112 scope global 
       valid_lft forever preferred_lft forever

# ip -6 routes
2001:db8::111:800:0/112 dev tun0  proto kernel  metric 256 
2000::/3 dev tun0  metric 1024 
Run Code Online (Sandbox Code Playgroud)

服务器

# ip -6 address
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qlen 1000
    inet6 2001:db8:216:3dfa:f1d4:81c0/64 scope global dynamic 
       valid_lft 86254sec preferred_lft 14254sec
    inet6 2001:db8::111:100:100/128 scope global 
       valid_lft forever preferred_lft forever
12: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qlen 100
    inet6 2001:db8::111:800:1/112 scope global 
       valid_lft forever preferred_lft forever

# ip -6 route
2001:db8::111:100:100 dev eth0  proto kernel  metric 256 
2001:db8::111:800:0/112 dev tun0  proto kernel  metric 256 
2001:db8::/64 dev eth0  proto kernel  metric 256  expires 86194sec
default via fe80::230:48ff:fe94:d6c5 dev eth0  proto ra  metric 1024  expires 1594sec
Run Code Online (Sandbox Code Playgroud)

ysd*_*sdx 12

您需要告诉您的路由器将您的服务器用于此 VPN 子网:问题的正确解决方案是在路由器上为 OpenVPN 子网添加路由。

如果由于无法触摸路由器而无法执行此操作,另一种解决方案是为eth0链路上的客户端设置 NDP 代理。

当您使用 VPS 时,您可能无法向路由器添加路由:您可能必须使用第二种解决方案。

为子网添加路由

您的问题的正确解决方案是告诉路由器必须通过 OpenVPN 服务器路由 VPN 子网(这适用于 Linux):

ip route add 001:db8::111:800::/112 via 2001:db8::111:100:100
Run Code Online (Sandbox Code Playgroud)

您必须在服务器上启用 IPv6 转发:

sysctl sys.net.ipv6.conf.all.forwarding=1
Run Code Online (Sandbox Code Playgroud)

新民主党代理

路由器似乎配置为在eth0链接上发送整个 IPv6 范围:您可以设置 NDP 代理。

eth0尝试从客户端访问 Internet 的其余部分时,您应该在OpenVPN 子网的服务器接口上看到 NDP 请求。

您还需要在服务器和 NDP 代理上启用 IPv6 转发:

sysctl -w net.ipv6.conf.all.proxy_ndp=1

子网 NDP 代理

Linux 内核不允许为子网添加 NDP 代理,而只能为单个 IP 添加。您可以使用守护进程(例如 ndppd为整个子网设置 NDP 代理(从未使用过)。

每个 IP NDP 代理

另一种解决方案是可以为 VPN 子网的每个 IPv6 添加一个 NDP 代理:

for i in $(seq 0 65535) ; do
  ip neigh add proxy 2001:db8::111:800:$(printf %x $i) dev tun0
done
Run Code Online (Sandbox Code Playgroud)

这应该可以工作,因为您在 OpenVPN 子网中有少量的 IP。

带有 OpenVPN 挂钩的动态 NDP 代理

您应该能够使用 OpenVPN 挂钩动态添加 NDP 代理。

在 OpenVPN 服务器配置中添加钩子:

learn-address /etc/openvpn/learn-address
Run Code Online (Sandbox Code Playgroud)

使用以下learn-address脚本:

#!/bin/sh

action="$1"
addr="$2"

case "$action" in
    add | update)
        ip neigh replace proxy "$addr" dev tun0
        ;;
    delete)
        ip neigh del proxy "$addr" dev tun0
        ;;
esac
Run Code Online (Sandbox Code Playgroud)

看到这个线程

简答

for i in $(seq 0 65535) ; do
  ip neigh add proxy 2001:db8::111:800:$(printf %x $i) dev tun0
done
Run Code Online (Sandbox Code Playgroud)