我有来自同一提供商的多个互联网路由器(我将互联网路由器称为“盒子”),它们都链接到同一个硬件网络交换机,形成一个物理网络(我将这个物理网络命名为“NML”,代表“无人区”),上面连接了两个路由器(我将它们命名为“路由器”),为私有局域网执行路由和防火墙任务:
_____________________________________________ WAN (Internet)
| | | |
| | | |
___|___ ___|___ ___|___ ___|___
[ ] [ ] [ ] [ ]
[ Box 1 ] [ Box 2 ] [ Box 3 ] [ Box 4 ]
[ 0:A:1 ] [ 0:B:1 ] [ 0:C:1 ] [ 0:D:1 ]
[_______] [_______] [_______] [_______]
| | | |
| | | |
____|___________|___________|___________|____ NML (A physical network
| | for boxes and routers)
| |
____|____ ____|____
[ ] [ ]
[ Router1 ] [ Router2 ]
[ 0:A:2 ] [ 0:A:3 ]
[ 0:B:2 ] [ 0:B:3 ]
[ 0:C:2 ] [ 0:C:3 ]
[ 0:D:2 ] [ 0:D:3 ]
[_________] [_________]
| |
| |
__________|_______________________|__________ LAN (Where people are working)
在 ipv4 方面,NML 是一个使用 ipv4 私有类的本地网络,它可以工作。
在 ipv6 方面,每个盒子共享相同的 /64 前缀,并且每个路由器从每个盒子获取一个自动配置的 ipv6 地址(每个路由器获得四个 ipv6,每个盒子一个)。
为了简单起见,你可以想象有 3 个字符的 ipv6 地址:
0:A:1
:0
前缀来自提供商网络前缀,A
前缀来自第一个盒子网络前缀,1
后缀来自第一个盒子地址;0:A:2
:0
前缀来自提供商网络前缀,A
前缀来自第一个盒子网络前缀,1
后缀来自从第一个盒子获取地址的第一个路由器;0:C:1
:0
前缀来自提供商网络前缀,C
前缀来自第三个盒子网络前缀,1
后缀来自第三个盒子地址;0:C:3
:0
前缀来自提供商网络前缀,C
前缀来自第三个盒子网络前缀,3
后缀来自第二个路由器从第三个盒子获取地址。
因此每个路由器获得四个 IPv6 地址,每个盒子一个。
- 从路由器 1 我可以使用每个盒子的ipv6
ping6
地址(0:A:1
、、、);0:B:1
0:C:1
0:D:1
- 从路由器 2 我可以获得
ping6
路由器 2 的每个 ipv6 地址(0:A:3
,0:B:3
,0:C:3
,0:D:3
),反之亦然; - 从路由器 1 和路由器 2 我都无法获得
ping6
ipv6 地址,即使我为该 ipv6 地址向一个盒子添加了一条显式路由(ip -6 route add something via 0:A:1
),无论是使用来自提供商前缀的盒子的 ipv6 地址,还是使用盒子的链路本地地址。
起初只有一个盒子激活了 ipv6,此时我能够使用 ipv6 查询互联网,但由于我在所有盒子上都激活了 ipv6,因此我无法再使用 ipv6 查询互联网。如果我traceroute6
从路由器对互联网地址执行 a,它永远不会超出盒子的范围。
请注意,此时我不需要通过路由器从 LAN 执行 ipv6 操作,我只需要路由器能够使用 ipv6 执行 Internet 操作(主要是在 ipv6 上构建一些 VPN)。
互联网路由器(称为“盒子”)是 ISP 的财产,我唯一的选择是客户页面上的“启用 IPv6”复选框,我无法访问路由器配置本身,除了启用或禁用 ipv6 之外没有其他选择。LAN 和 NML 之间的路由器(称为“路由器”)是运行在某些基于 x86 的网络硬件上的标准 Debian 系统。从 Debian 的角度来看,你可以想象它就像一台 PC:我可以做任何标准 Debian 能做的事情。
因此,有两个问题:
- 设置是否正确并且预期可以工作?如果是,我应该在哪里查找问题?
- 设置是否不正确,并且根本不会起作用?如果是,我该怎么做才能修复它?
我删除了一些“过期”信息和类似的东西以消除一些冗长,另外我有时添加了一些引导0
以对齐地址以便于阅读,然后替换了一些位以使用 ipv6 示例类。
# my boxes' ipv6 addresses
box0 2001:db8:ee84:2180::1
box1 2001:db8:ee84:21c0::1
box2 2001:db8:2f13:1ea0::1
box3 2001:db8:399a:08f0::1
box4 2001:db8:399a:39e0::1
# my router1's ipv6 addresses
# ip -6 addr show dev eth2
4: eth2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 state UP qlen 1000
inet6 2001:db8:ee84:2180:200:24ff:fed1:3d9e/64 scope global mngtmpaddr dynamic
inet6 2001:db8:ee84:21c0:200:24ff:fed1:3d9e/64 scope global mngtmpaddr dynamic
inet6 2001:db8:2f13:1ea0:200:24ff:fed1:3d9e/64 scope global mngtmpaddr dynamic
inet6 2001:db8:399a:08f0:200:24ff:fed1:3d9e/64 scope global mngtmpaddr dynamic
inet6 2001:db8:399a:39e0:200:24ff:fed1:3d9e/64 scope global mngtmpaddr dynamic
inet6 fe80::200:24ff:fed1:3d9e/64 scope link
# my router2's ipv6 addresses
ip -6 addr show dev eth2
4: eth2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 state UP qlen 1000
inet6 2001:db8:ee84:2180:200:24ff:fed1:6336/64 scope global mngtmpaddr dynamic
inet6 2001:db8:ee84:21c0:200:24ff:fed1:6336/64 scope global mngtmpaddr dynamic
inet6 2001:db8:2f13:1ea0:200:24ff:fed1:6336/64 scope global mngtmpaddr dynamic
inet6 2001:db8:399a:08f0:200:24ff:fed1:6336/64 scope global mngtmpaddr dynamic
inet6 2001:db8:399a:39e0:200:24ff:fed1:6336/64 scope global mngtmpaddr dynamic
inet6 fe80::200:24ff:fed1:6336/64 scope link
# default ipv6 routes on router1
# ip -6 route
2001:db8:ee84:2180::/64 dev eth2 proto kernel metric 256
2001:db8:ee84:21c0::/64 dev eth2 proto kernel metric 256
2001:db8:2f13:1ea0::/64 dev eth2 proto kernel metric 256
2001:db8:399a:08f0::/64 dev eth2 proto kernel metric 256
2001:db8:399a:39e0::/64 dev eth2 proto kernel metric 256
fe80::/64 dev eth2 proto kernel metric 256
default via fe80::e69e:12ff:fe04:286f dev eth2 proto ra metric 1024 hoplimit 64
default via fe80::e69e:12ff:fe03:8b35 dev eth2 proto ra metric 1024 hoplimit 64
default via fe80::e69e:12ff:fe02:10de dev eth2 proto ra metric 1024 hoplimit 64
default via fe80::0224:d4ff:fea7:f258 dev eth2 proto ra metric 1024 hoplimit 64
default via fe80::0224:d4ff:febb:af9e dev eth2 proto ra metric 1024 hoplimit 64
# default ipv6 routes on router2
# ip -6 route
2001:db8:ee84:2180::/64 dev eth2 proto kernel metric 256
2001:db8:ee84:21c0::/64 dev eth2 proto kernel metric 256
2001:db8:2f13:1ea0::/64 dev eth2 proto kernel metric 256
2001:db8:399a:08f0::/64 dev eth2 proto kernel metric 256
2001:db8:399a:39e0::/64 dev eth2 proto kernel metric 256
fe80::/64 dev eth2 proto kernel metric 256
default via fe80::e69e:12ff:fe03:8b35 dev eth2 proto ra metric 1024 mtu 1480 hoplimit 64
default via fe80::0224:d4ff:febb:af9e dev eth2 proto ra metric 1024 hoplimit 64
default via fe80::e69e:12ff:fe02:10de dev eth2 proto ra metric 1024 hoplimit 64
default via fe80::e69e:12ff:fe04:286f dev eth2 proto ra metric 1024 hoplimit 64
default via fe80::0224:d4ff:fea7:f258 dev eth2 proto ra metric 1024 hoplimit 64
# neigh from router1
# ip -6 neigh | grep eth2
fe80::224:d4ff:febb:af9e dev eth2 lladdr 00:24:d4:bb:af:9e router STALE
fe80::200:24ff:fed1:6336 dev eth2 lladdr 00:00:24:d1:63:36 STALE
fe80::e69e:12ff:fe04:286f dev eth2 lladdr e4:9e:12:04:28:6f router REACHABLE
2001:db8:2f13:1ea0::1 dev eth2 lladdr 00:24:d4:bb:af:9e router STALE
fe80::e69e:12ff:fe02:10de dev eth2 lladdr e4:9e:12:02:10:de router STALE
2001:db8:399a:39e0:200:24ff:fed1:6336 dev eth2 lladdr 00:00:24:d1:63:36 STALE
2001:db8:399a:8f0:200:24ff:fed1:6336 dev eth2 lladdr 00:00:24:d1:63:36 STALE
2001:db8:399a:39e0::1 dev eth2 lladdr 00:24:d4:a7:f2:58 router STALE
2001:db8:399a:8f0::1 dev eth2 lladdr e4:9e:12:02:10:de router STALE
2001:db8:399a:39e0:: dev eth2 FAILED
fe80::213:46ff:fe8f:1e4a dev eth2 lladdr 00:13:46:8f:1e:4a STALE
2001:db8:399a:8f0:: dev eth2 FAILED
fe80::e69e:12ff:fe03:8b35 dev eth2 lladdr e4:9e:12:03:8b:35 router STALE
fe80::224:d4ff:fea7:f258 dev eth2 lladdr 00:24:d4:a7:f2:58 router STALE
fe80::8226:89ff:fe2d:b3d3 dev eth2 lladdr 80:26:89:2d:b3:d3 STALE
fe80::20a:f7ff:fe12:e77 dev eth2 lladdr 00:0a:f7:12:0e:77 STALE
2001:db8:ee84:2180::1 dev eth2 lladdr e4:9e:12:03:8b:35 router STALE
fe80::21d:9ff:fe2c:628d dev eth2 lladdr 00:1d:09:2c:62:8d STALE
# get from router1
# ip -6 route get 2001:4860:4860::8888
2001:4860:4860::8888 from :: via fe80::e69e:12ff:fe04:286f dev eth2 proto ra src 2001:db8:399a:39e0:200:24ff:fed1:3d9e metric 1024 hoplimit 64
# neigh from router2
# ip -6 neigh | grep eth2
2001:db8:399a:8f0:200:24ff:fed1:3d9e dev eth2 lladdr 00:00:24:d1:3d:9e STALE
2001:db8:399a:8f0::1 dev eth2 lladdr e4:9e:12:02:10:de router STALE
fe80::e69e:12ff:fe04:286f dev eth2 lladdr e4:9e:12:04:28:6f router STALE
fe80::224:d4ff:fea7:f258 dev eth2 lladdr 00:24:d4:a7:f2:58 router DELAY
fe80::e69e:12ff:fe02:10de dev eth2 lladdr e4:9e:12:02:10:de router REACHABLE
fe80::200:24ff:fed1:3d9e dev eth2 lladdr 00:00:24:d1:3d:9e STALE
fe80::224:d4ff:febb:af9e dev eth2 lladdr 00:24:d4:bb:af:9e router STALE
2001:db8:399a:39e0:200:24ff:fed1:3d9e dev eth2 lladdr 00:00:24:d1:3d:9e STALE
fe80::e69e:12ff:fe03:8b35 dev eth2 lladdr e4:9e:12:03:8b:35 router REACHABLE
# get from router2
ip -6 route get 2001:4860:4860::8888
2001:4860:4860::8888 from :: via 2001:db8:399a:8f0::1 dev eth2 src 2001:db8:399a:39e0:200:24ff:fed1:6336 metric 1024
一些跟踪路由示例:
# traceroute from router1
# traceroute 2001:4860:4860::8888
traceroute to 2001:4860:4860::8888 (2001:4860:4860::8888), 30 hops max, 80 byte packets
1 2001:db8:ee84:21c0::1 (2001:db8:ee84:21c0::1) 26.146 ms 27.728 ms 28.507 ms
答案1
我正在转调此 ipv4 示例至 ipv6。
问题在于,除非您主动使用正确的源 ping 每个盒子的 IP,否则很难(使用 MAC 地址)将正确的公共 IP 与正确的链接本地 IP 进行匹配。这是我从两个路由器的邻居表以及链接本地端是 MAC 端这一事实中推断出来的:
box0 2001:db8:ee84:2180::1 <=> fe80::e69e:12ff:fe03:8b35
box2 2001:db8:2f13:1ea0::1 <=> fe80::0224:d4ff:febb:af9e
box3 2001:db8:399a:08f0::1 <=> fe80::e69e:12ff:fe02:10de
box4 2001:db8:399a:39e0::1 <=> fe80::0224:d4ff:fea7:f258
而数据无法找到的剩余部分必须是:
box1 2001:db8:ee84:21c0::1 <=> fe80::e69e:12ff:fe04:286f
由此可以清楚地看出,ip -6 route get
问题中的两个示例都表明所选路由器使用了错误的源。在这种情况下,这似乎是 Linux 的限制(多个 LAN 覆盖在单个物理 LAN 上)。
因此,以下是路由器 1 需要执行的操作。此外,通过反复试验,仍需在表中为默认路由指定“src”,否则仍可能选择其他源。请注意,公共 IP 或链接本地 IP 可以(应该)交替用作网关,因此最好使用公共 IP,即使 RA 似乎更喜欢链接 IP,在脚本中使用公共 IP 也更容易,并且不再需要像上面那样查找两种 IP 之间的对应关系。
# ip -6 路由添加 2001:db8:ee84:2180::/64 dev eth2 src 2001:db8:ee84:2180:200:24ff:fed1:3d9e 表 100 # ip -6 路由通过 2001:db8:ee84:2180::1 dev eth2 src 2001:db8:ee84:2180:200:24ff:fed1:3d9e 表 100 添加默认路由 # ip -6 路由添加 2001:db8:ee84:21c0::/64 dev eth2 src 2001:db8:ee84:21c0:200:24ff:fed1:3d9e 表 101 # ip -6 路由通过 2001:db8:ee84:21c0::1 dev eth2 src 2001:db8:ee84:21c0:200:24ff:fed1:3d9e 表 101 添加默认路由 # ip -6 路由添加 2001:db8:2f13:1ea0::/64 dev eth2 src 2001:db8:2f13:1ea0:200:24ff:fed1:3d9e 表 102 # ip -6 路由通过 2001:db8:2f13:1ea0::1 dev eth2 src 2001:db8:2f13:1ea0:200:24ff:fed1:3d9e 表 102 添加默认路由 # ip -6 路由添加 2001:db8:399a:08f0::/64 dev eth2 src 2001:db8:399a:08f0:200:24ff:fed1:3d9e 表 103 # ip -6 路由通过 2001:db8:399a:08f0::1 dev eth2 src 2001:db8:399a:08f0:200:24ff:fed1:3d9e 表 103 添加默认路由 # ip -6 路由添加 2001:db8:399a:39e0::/64 dev eth2 src 2001:db8:399a:39e0:200:24ff:fed1:3d9e 表 104 # ip -6 路由通过 2001:db8:399a:39e0::1 dev eth2 src 2001:db8:399a:39e0:200:24ff:fed1:3d9e 表 104 添加默认路由
至少必须在主(通常)表中放入一个“默认”默认路由,否则无论以后做什么,都会出现错误,例如“没有到主机的路由”或“网络无法访问”。由于您已经从路由器广告中获得了其中 5 个,因此不需要它。
现在让我们添加将每个源 IP 绑定到其匹配表的规则,从而为任何(盒式)路由器选择正确的源:
# ip -6 规则从 2001:db8:ee84:2180:200:24ff:fed1:3d9e 表 100 添加 # ip -6 规则从 2001:db8:ee84:21c0:200:24ff:fed1:3d9e 表 101 添加 # ip -6 规则从 2001:db8:2f13:1ea0:200:24ff:fed1:3d9e 表 102 添加 # ip -6 规则从 2001:db8:399a:08f0:200:24ff:fed1:3d9e 表 103 添加 # ip -6 规则从 2001:db8:399a:39e0:200:24ff:fed1:3d9e 表 104 添加
也可以强制(甚至通过匹配进行负载平衡statistic --mode nth
)选择,例如ip6tables ... -j MARK ...
使用ip -6 rule add fwmark ... table 10x
现在最好编写脚本...
可能还存在其他问题。如果一个盒子路由器离线,相应的默认路由将在 Linux 系统上快速消失,因为它不再被公布,但 IP 会保留。我不知道这个 IP 是否仍可能被错误地选择用于剩余的默认路由。如果发生这种情况,添加的 IP 规则可能会覆盖默认路由以使用现在离线的盒子路由器,从而破坏将多个盒子作为路由器的故障转移机制。我没有办法测试这一点。