我正在设置隧道ssh -w
,我想通过它路由 IPv6 流量。远程计算机是 Internet 上的服务器,分配了多个 IPv6 地址
我正在做的是:
local# ssh -w 0:0 remote.example.com
remote.example.com
是一个 IPv4 地址,并且 ssh 连接通过 IPv4 进行。
然后我tun0
在两台主机上分配 IPv6 地址
remote# ip a add fd00::ffff:1 dev tun0
local# ip a add fd00::ffff:2 dev tun0
此时他们都可以 ping 对方的 fd00::/48 地址。
我通过设置来在远程服务器上启用 IPv6 转发:
net.ipv6.conf.default.forwarding = 1
net.ipv6.conf.all.forwarding = 1
现在我希望能够local
通过 tun0 路由的 IPv6 流量。local
可以通过 IPv4 连接到remote
,因此它需要的唯一 IPv6 路由是默认的,tun0
这是我到目前为止尝试过的:
local# ip -6 r add default via fd00::ffff:1 dev tun0
local# ip -6 r del default via gw dev wls0 # delete old default v6 route
然而此时我还没有获得 IPv6 连接local
,数据包没有通过以下方式路由remote
:
local# ping 2001:4860:4860::8888
PING 2001:4860:4860::8888(2001:4860:4860::8888) 56 data bytes
From fd00::ffff:1 icmp_seq=1 Destination unreachable: Address unreachable
我需要在服务器上设置什么remote
以便它能够传递数据包?
答案1
出现该消息的原因可能有多种:
主机
remote
具有到该目的地的可用路由(您说它有多个 IPv6 地址,但没有说它具有默认路由);没有到该目的地的可用路线匹配此来源(它可能只有与特定源前缀匹配的路由,或者它可能在
ip rule
不同的路由表之间进行选择时具有策略规则);其防火墙“转发”链拒绝来自该来源的数据包。
用于ip -6 route get 2001:4860:4860::8888 from fd00::ffff:2
检查将做出什么路由决策。
然而,总的来说,您需要为local
系统分配一个全局地址。首先,它不能真正收到如果没有网关,系统后面的网关很可能remote
会拒绝让其通过发送从“错误”地址向互联网发送数据包(它可能正在进行 BCP38 欺骗地址过滤)。
(如果remote
有全局 IPv6 前缀路由到它,你可以将该前缀用于隧道本身,或者通过 fd00::ffff:2 将其路由到隧道,以便local
可以决定如何处理它。如果路由前缀不可用,那么通常至少一些“在线”地址将可用,您仍然可以通过使用ndpresponder
远程主机上的守护进程启用 NDP 代理来进一步路由。)
万一不可以分配给系统的全局地址local
,最终的解决方法与 IPv4 完全相同:您的remote
系统需要执行 NAT。(也就是说,您需要在 ip6tables 中添加“MASQUERADE”规则,或在 nftables 中添加其等效规则。)
答案2
感谢@user1686的建议,我决定在IPv6接口上使用源NAT。结果发现remote
只有几个单数已为其分配 IPv6 地址。不幸的是,这种情况很常见。
在remote
机器上我添加了源 IPv6 nat
nft add table ip6 nat
nft 'add chain ip6 nat postrouting { type nat hook postrouting priority 100; }'
nft add rule ip6 nat postrouting ip6 saddr fd00::ffff:0/48 oif \"eth0\" snat to [remote's IPv6 address]
最后一行向来自 fd00::/48 的数据包添加源 nat,eth0
以更改源地址的方式发送这些数据包
现在执行ping6 -I tun0 2001:4860:4860::8888
工作正常,因为数据包通过隧道路由并在其上进行 SNAT remote
。
请注意,这是一种 hack,并且IPv6 并非如此运行。这样做只是因为remote
服务器提供商没有分配 IPv6 块,而只分配了单个地址。