You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Linux VPS中/120 IPv6子网路由失败及Neighbor Solicitation源地址选择疑问

Linux VPS中/120 IPv6子网路由失败及Neighbor Solicitation源地址选择疑问

咱们先梳理下你的场景和问题:你在VPS上拿到了2001:db8:X:Y::25:785c/112的IPv6段,想拆成两个/120子网——一个给eth0本地用,另一个通过tuns0路由到远程办公网。但现在远程办公网的ping没法走到公网,抓包发现VPS发的Neighbor Solicitation(NS,邻居请求)报文源地址不对,导致服务商的路由器不响应。

核心疑问

  • Linux内核替远程办公网的流量向eth0发送NS时,是怎么选源地址的?
  • 子网配置时我到底漏了什么?

你的现有配置信息

接口地址

# ip -6 addr list eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 state UP qlen 1000
inet6 2001:db8:X:Y::25:785c/120 scope global
valid_lft forever preferred_lft forever
inet6 fe80::216:3cff:fe2e:4906/64 scope link noprefixroute
valid_lft forever preferred_lft forever

# ip -6 addr list tuns0
85: tuns0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1423 state UNKNOWN qlen 100
inet6 2001:db8:X:Y::25:61/120 scope global
valid_lft forever preferred_lft forever
inet6 fe80::2de4:df93:3c60:d6f6/64 scope link flags 800
valid_lft forever preferred_lft forever

远程办公网子网:2001:db8:X:Y::25:1000/120,办公网主机地址为2001:db8:X:Y::25:1060

路由表

# ip -6 route list
unreachable ::/96 dev lo metric 1024 error -113 pref medium
unreachable ::ffff:0.0.0.0/96 dev lo metric 1024 error -113 pref medium
unreachable 2002:a00::/24 dev lo metric 1024 error -113 pref medium
unreachable 2002:7f00::/24 dev lo metric 1024 error -113 pref medium
unreachable 2002:a9fe::/32 dev lo metric 1024 error -113 pref medium
unreachable 2002:ac10::/28 dev lo metric 1024 error -113 pref medium
unreachable 2002:c0a8::/32 dev lo metric 1024 error -113 pref medium
unreachable 2002:e000::/19 dev lo metric 1024 error -113 pref medium
2001:db8:X:Y::1 dev eth0 proto static metric 100 pref medium
2001:db8:X:Y::25:1000/120 dev tuns0 metric 1024 pref medium
2001:db8:X:Y::25:7800/120 dev eth0 proto kernel metric 256 pref medium
unreachable 3ffe:ffff::/32 dev lo metric 1024 error -113 pref medium
fe80::/64 dev eth0 proto kernel metric 100 pref medium
fe80::/64 dev tuns0 proto kernel metric 256 pref medium
default via 2001:db8:X:Y::1 dev eth0 proto static metric 100 pref medium

内核转发与防火墙

# sysctl net.ipv6.conf.{eth0,tuns0}.forwarding
net.ipv6.conf.eth0.forwarding = 1
net.ipv6.conf.tuns0.forwarding = 1
# ip6tables -nvL FORWARD
Chain FORWARD (policy DROP 0 packets, 0 bytes)
pkts bytes target     prot opt in     out     source               destination
0     0 ACCEPT     all      *      tuns0   ::/0                 ::/0
3307  344K ACCEPT     all      tuns0  *       ::/0                 ::/0
0     0 ACCEPT     all      *      *       ::/0                 ::/0                 state RELATED,ESTABLISHED
3   216 ACCEPT     icmpv6    eth0   *       ::/0                 ::/0                 ipv6-icmp !type 128 code 0

症状细节

远程办公网ping公网地址(比如2606:4700::6810:85e5)全丢包,抓包eth0看到两种异常NS:

  1. 用eth0的链路本地地址fe80::216:3cff:fe2e:4906做源,向组播地址ff02::1:ff00:1发送对网关2001:db8:X:Y::1的NS请求,但服务商路由器完全没响应;
  2. 用eth0的全局地址2001:db8:X:Y::25:785c做源,向组播地址ff02::1:ff25:1060发送对远程办公网主机的NS请求,同样没响应。

但VPS本地ping公网时,NS请求的源地址是2001:db8:X:Y::25:785c,路由器立刻回复了Neighbor Advertisement(NA,邻居通告),ping也成功了。

问题分析及解决方法

1. NS源地址选择的逻辑

Linux内核选NS源地址遵循IPv6源地址选择策略(可以用ip -6 rule查看),核心规则是:

  • 当要给某个目的地址发NS时,优先选和目的地址同子网的本地地址当源;
  • 如果找不到同子网的地址,就会 fallback到出口接口的链路本地地址。

你这里的问题出在:eth0的子网前缀配置成了/120,但网关2001:db8:X:Y::1属于/112前缀,不在eth0的/120子网范围内。

当远程流量过来要转发到公网时,内核需要向网关2001:db8:X:Y::1发NS,但发现eth0上的全局地址和网关不在同一个子网,就只能用链路本地地址发NS。而很多ISP的路由器会忽略来自链路本地地址的NS请求——因为它们只认属于同一个分配前缀(也就是你拿到的/112)的全局地址发来的NS。

而VPS本地ping时,内核会用eth0的全局地址作为ping的源地址,此时发NS时会复用这个源地址(它和网关同属/112前缀),所以路由器愿意响应。

2. 你遗漏的配置点

方案一:修正eth0的子网前缀(推荐)

既然服务商给你的是/112的段,你应该把eth0的地址配置在/112前缀下,而不是/120。这样网关就和eth0的地址在同一个子网里,内核发NS时会自动用eth0的全局地址当源:

# 修改eth0的地址前缀为/112
ip -6 addr change 2001:db8:X:Y::25:785c/112 dev eth0

之后远程流量转发时,内核发NS的源地址就会是eth0的全局地址,路由器会正常响应。

方案二:添加源地址策略路由(如果不想改eth0前缀)

如果因为某种原因不能修改eth0的子网前缀,可以添加一条策略路由,强制让来自远程子网的流量在转发时,用eth0的全局地址作为源:

# 添加规则:来自远程子网的流量用表100路由
ip -6 rule add from 2001:db8:X:Y::25:1000/120 lookup 100
# 在表100里添加默认路由,指定源地址为eth0的全局地址
ip -6 route add default via 2001:db8:X:Y::1 dev eth0 src 2001:db8:X:Y::25:785c table 100

这样远程子网的流量转发时,会强制使用eth0的全局地址作为源,发NS时也会用这个地址,路由器就能响应了。

3. 验证步骤

修改配置后,从远程办公网再次ping公网地址,同时在VPS上抓eth0的包:

  • 查看NS请求的源地址是否变成2001:db8:X:Y::25:785c;
  • 检查是否能收到服务商路由器的NA响应;
  • 确认ping是否能收到回复。

备注:内容来源于stack exchange,提问作者Jaredo Mills

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.21 13:59:29