V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
raysonx
V2EX  ›  宽带症候群

写给 Geek 们的 IPv6 组网最佳实践系列:处理动态前缀造成的种种问题

  •  7
     
  •   raysonx · 2023-07-10 22:06:58 +08:00 · 7539 次点击
    这是一个创建于 531 天前的主题,其中的信息可能已经有所发展或是发生改变。

    本文属于《写给 Geek 们的 IPv6 组网最佳实践》系列,旨在为需要小范围 IPv6 组网(如家庭组网)的爱好者们提供最佳实践方案和常见问题解答,部分概念性内容为方便理解可能会过度简化,部分方案可能不适用企业宽带接入、大规模组网等场景。首发于 V2EX ,转载请注明出处。关于此系列的介绍,见 https://v2ex.com/t/955078#reply36 。 勘误等内容将更新在附言区。

    问题描述

    IPv6 下 LAN 侧每一台机器都会获得独立的公网 IPv6 地址。

    目前国内绝大多数地区的家庭带宽是通过 PPPoE 虚拟拨号接入的,下发的 IPv6 前缀会在每次重新拨号后发生变化。这就需要我们重新给 LAN 侧的设备分配 IPv6 地址,以及处理前缀变化造成的种种问题,如服务发现及防火墙配置。

    前缀前化导致的断网问题

    举例说明

    假设光猫运行在桥接模式,路由器拨号获得 IPv6 PD 前缀 2001:db8:beef:1200::/56。路由器下联一个 LAN ,指定 PD 前缀的 SLA ID 为1(也就是从2001:db8:beef:1200::/56 挑选第 1 个(从 0 开始数)/64子网),路由器会将2001:db8:beef:1201::/64 这个子前缀划为给 LAN 。正确配置的情况下所有 LAN 下的设备都将获得2001:db8:beef:1201:xxxx:xxxx:xxxx:xxxx/64 格式的地址。

    此时路由器上的 PPPoE 断开后重拨,ISP 下发新的 PD 前缀 2001:db8:dead:ab00::/56。此时路由器应该向 LAN 下的所有设备宣告原前缀2001:db8:beef:1201::/64失效,并重新下发 2001:db8:dead:ab01::/64 前缀,否则 LAN 下的设备可能会因为继续使用老前缀而导网络中断。

    解决方法

    • 最佳实践:关闭 DHCPv6 服务,改用 SLAAC 无状态分配。DHCPv6 分配的地址存在一个租期,除非租期快到了,用户设备不会重新请求一个新的地址。而 SLAAC 可以由服务器主动通知用户设备前缀失效。如果无特殊理由,可以禁用 DHCPv6 。此外,现在无状态分配也可以通过 RDNSS 选项配置 DNS ,现代操作系统都支持。DHCPv6 已经没有必要使用了,尤其是 Android 不支持 DHCPv6 。
    • 次佳方案:将 DHCPv6 租期调短,比如 5 分钟。这样如果前缀变更,最长 5 分钟老前缀就会失效。

    已经使用纯无状态分配了,但重新拨号后老前缀没有失效?

    前面说了,SLAAC 可以由服务器主动通知用户设备前缀失效。但这只是协议支持。如果重新拨号后老前缀没有失效或者新前缀没有下发,说明你的路由器固件存在问题。在条件允许的情况下,换一个其他的的固件吧。

    新版 OpenWRT 是没有问题的。

    如果使用 VyOS 1.4 ,可以设置 set service router-advert interface eth0 prefix ::/64 deprecate-prefix,其中 eth0 是 LAN 口网卡名。

    如果是在 Linux 上跑 radvd ,修改radvd.conf,端号配置中加上 DeprecatePrefix on; ,并配置脚本使 pppoe 重拨后重启 radvd 。

    服务发现问题

    前缀变化后,所有 LAN 侧的 IPv6 地址都会变化。如何设定 DNS 以及避免服务中断?

    • 如果你的服务仅仅在 LAN 侧使用,或者多个服务内部通信不涉及外网,你可以给你的 LAN 侧分配一个内网地址( ULA 地址)。IPv6 完美支持一张网卡多个 IPv6 地址,所以你的设备可以同时拥有固定的内网地址以及动态的公网地址。关于 ULA 地址,见我的另一篇文章:为你的 IPv6 局域网配置 ULA 吧.
    • 如果你的服务需要从外网访问,建议设置 DDNS (动态 DNS )。DDNS 软件可以运行在提供服务的主机上,也可以由单台设备一次为所有服务更新 DNS 记录,不过后者可能需要你保证这些服务的 IPv6 后缀不会变化。关于如何设定固定的 IPv6 后缀,下面会进行讨论。

    防火墙设定问题

    如果你想在网关路由器上为每台终端设备配置防火墙规则,但又无从下手(因为终端设备没有固定的 IPv6 地址),可以使用下面的方法。

    • 首先确保这台终端设备的 IPv6 后缀是固定的,比如不管前缀如何变化,这台设备的后缀总是::1234 。
    • 如果网关的防火墙基于 Linux nftables/ip6tables ,可以用负掩码匹配设备的后缀。即可以用 ::1234/::ffff:ffff:ffff:ffff 来匹配后 64 位地址( OpenWRT 支持::1234/-64 这种写法)。

    如何给我的设备设定一个固定后缀?

    首先需要明确的是,在使用 SLAAC 无状态地址分配时,路由器只宣告子网的前缀,而 64 位的后缀完全由终端设备自己决定。

    目前大多数新的操作系统下,一个前缀会生成两个 IPv6 地址:永久地址和临时地址。

    临时地址的后缀完全是随机生成的,用于发起访问,每隔一段时间会自动变化,在一定程度保护你的隐私(防追踪)。Linux 下使用ip a命令或者 mac 系统下 ifconfig 命令,如果一个地址后面有 temporary 标记,则表明这是个临时地址。iOS 系统下,第二个无状态地址是临时地址。中文 Windows 系统下 ipconfig 命令会直接标明哪个地址是临时地址。

    永久地址的后缀是由特定的哈希算法生成的。这个哈希由网卡的 mac 地址和一个随机数共同决定。只要你的前缀不变并且 mac 地址不变,后缀就不会变。因此适合对外提供服务。但是如果前缀变了,则后缀也会跟着变化。(当你配置了 ULA 时,因为 ULA 的前缀是不变的,所以这个 ULA 地址是静态的)。iOS 系统连接 Wi-Fi 时,默认会使用随机 mac 地址,因此后缀会经常变化,这个功能可以在 Wi-Fi 设置中关闭。

    部分老系统、老的网络管理软件的永久地址仅仅是 mac 地址的变形,这种生成方式叫做 Modified EUI-64 。判断方法为,如果永久地址的后 64 位形如:xxxx:xxff:fexx:xxxx ,即中间 16 位是 ff:fe ,则该地址是使用 Modified EUI-64 生成的。在这种配置下,只要 mac 地址不变,后缀就不会变,因此可以视作固定后缀。这种生成方式会对外暴露你的 mac 地址,看你介意不介意了。

    SLAAC 下的后缀可以手动指定。

    比如 Linux 下可以用 ip token set ::1234 dev eth0指定后缀固定为 1234 (其中 eth0 是网卡名)。这个命令是运行时命令,无法在系统重启后保持,实际使用时需要配置到网络管理软件(如 Network Manager, systemd-networkd, ifupdown 等)中,例如:

    Network Manager

    nmcli c mod eth0 ipv6.token ::1234
    nmcli c mod eth0 ipv6.addr-gen-mode stable-privacy
    

    ifupdown:

    iface eth0 inet6 static
            autoconf 1
            accept_ra 2
            privext 1
            post-up /sbin/ip token set ::11 dev $IFACE
    

    systemd-networkd

    [Match]
    Name=eth0
    
    [Network]
    IPv6AcceptRA=true
    
    [IPv6AcceptRA]
    Token=static:::1234
    

    本文到此结束,如果各位有各种系统下的具体兼容情况和配置命令,可以在评论中补充,我会定期更新到附言中或者放到新帖中。

    第 1 条附言  ·  2023-07-10 22:42:03 +08:00
    补充:
    1. systemd-networkd .network 配置文件中,可以在[Network] 下设置 IPv6PrivacyExtensions=true 来启用临时地址生成。
    2. 此外还可以像 IPv4 一样给 IPv6 开启 NAT ,在 LAN 侧只使用内网地址,不过这对大多数人可能不是个好方法。
    51 条回复    2024-09-24 23:17:42 +08:00
    jsq2627
        1
    jsq2627  
       2023-07-10 22:31:16 +08:00   ❤️ 1
    原来可以用负掩码匹配后缀,学到了!之前总是对着防火墙束手无策,最后干脆全放通了。。
    basncy
        2
    basncy  
       2023-07-10 22:40:13 +08:00
    如果需要出站"相对"固定 ip, echo '0' > /proc/sys/net/ipv6/conf/wlan0/use_tempaddr
    隐私换方便, 适量使用.
    Jirajine
        3
    Jirajine  
       2023-07-10 22:42:22 +08:00   ❤️ 1
    还是无法解决实际的问题,比如 docker 容器必须使用固定前缀,使用 ula 要能访问 ipv6 网络必须用 nat ,要想容器同时可以公网可达(如 p2p 应用)只能用无状态 NAPT 或者端口转发,这就会涉及地址发现问题:应用不知道自己能通过哪个地址被访问。并且因为动态前缀这个地址还没法手动配置。

    固定后缀只能客户端设备自己控制,有些系统( Android )还不好设置。再者使用隐私扩展的临时地址建立出站连接本身也是最佳实践,这时地址还是完全无法管理:前缀后缀全是动态的。
    虽然可以通过 mac 地址在 4 层识别,但有些情况应用层防火墙、各种基于规则路由的应用层代理工具等,就不是那么容易访问到 4 层信息了。
    1423
        4
    1423  
       2023-07-10 22:48:23 +08:00
    很实用!
    不知道 Mac 能不能固定 SLAAC 下的后缀
    raysonx
        5
    raysonx  
    OP
       2023-07-10 22:54:03 +08:00
    @Jirajine 本系列文章只讨论大多数家庭使用场景下的方案。至于某些情况下(比如 Docker ),可能 NPTv6 比较适合。
    另外如果你必须要直接把公网地址分给 docker 容器,还可以有以下选择:
    1. 专门开一台虚拟机或者 lxc 给 docker ,这台虚拟机直接从 LAN 上用 SLAAC 拿地址,docker 容器指定--network=host 使用宿主网络栈。
    2. docker 容器的网络桥接到 LAN 上,然后跑 SLAAC 。
    如果你非要用物理机做路由,下联一个公网的 docker 网络,这可能需要 PD propagation 。 然而现有的软件很少有支持这个的。
    raysonx
        6
    raysonx  
    OP
       2023-07-10 22:57:53 +08:00
    @1423 其实对我来说,我所有的服务都跑在 Linux 上,所以实际上我只为 Linux 设定了固定后缀。其他系统不一定支持手动指定。
    实在没办法那就只能用上面说的次选方案了:DHCPv6+短租期。
    Jirajine
        7
    Jirajine  
       2023-07-10 23:23:39 +08:00
    @raysonx 其实这都是正常家庭使用场景下的需求,用 docker 容器跑个 qbittorrent ,挺常见吧。至于第二点“基于规则路由的应用层代理工具” 你知道我指什么,也是非常常见的需求。

    第一点写脚本通过 ssh 或 api 从网关拿到前缀并手动配置 ipv6 地址,然后定期重启服务勉强也能用。第二点暂时无解,只能不用 ipv6 。
    neroxps
        8
    neroxps  
       2023-07-10 23:45:19 +08:00 via iPhone
    非常棒的教学。
    raysonx
        9
    raysonx  
    OP
       2023-07-11 00:00:27 +08:00
    @Jirajine 我只能说环境是死的,人是活的。如果你发现你要解决这问题很麻烦时,可能意味着你这种方案不合适,也许换一种方案问题就迎刃而解。你说的这些问题产生的本质原因是因为你采用的方案引起的,比如我不用你的方案,所以我不会遇到你的问题。

    关于 docker 获取动态前缀的问题,我已经提过可以用 host 网络模式解决,而第二问题,其他方案很多,因为不知道你具体的配置方式,无法作答。
    Jirajine
        10
    Jirajine  
       2023-07-11 00:30:40 +08:00
    @raysonx 因为这已经是最容易的方案了,家庭内网下面不同设备通过不同策略路由、有些设备屏蔽互联网访问、有些设备限速等,实现这些基于 ip 地址比基于 mac 地址或 vlan 方便的多。
    最基本的,内网设备能够互通,且通过设备向 dhcp 发送的主机名自动生成的域名直接访问。


    至于 docker host 模式,很多文章这么写,实际上是 docker 正常配置 ipv6 太过困难的无奈之举。bt 下载要和其他服务走不同的路由出口,所以还是需要独立的 ip 地址以在网关上区分;如果用单独的虚拟机,那硬盘挂载到哪个设备上、存储如何共享,又会产生新的问题。

    归根结底还是 ipv6 当前软件支持不完善,最基本的上网使用场景能跑,但 corner case 太多。最近有遇到一个桥接 wifi 和以太网接口的问题,通常情况下很难做到,VMware/VirtualBox 通过 spoof 源 mac 地址的 trick 来实现,需要软件自己干预地址管理/arp ,只支持 ipv4 。
    docker 的 ipv6 支持也被骂了很多年了,没啥提升,官方根本不觉得动态前缀是设计中的使用场景。
    neroxps
        11
    neroxps  
       2023-07-11 05:48:10 +08:00 via iPhone
    @Jirajine 现在 docker 已经支持 ipv6 nat 了。直接和 ipv4 一样 port 映射到本机的 :: 地址监听。解决了动态 ipv6 前缀问题,其实一早有 github 方案第三方解决。
    yuchenr
        12
    yuchenr  
       2023-07-11 10:56:00 +08:00   ❤️ 1
    我现在用的这个脚本
    #!/bin/bash

    PREVIOUS_IPV6_ADDRESS="YOUR_PREVIOUS_IPV6_ADDRESS" # 替换为之前记录的 IPv6 地址

    while true; do
    # 获取当前 IPv6 地址
    CURRENT_IPV6_ADDRESS=$(ip -6 addr show dev pppoe0 | awk '/inet6/ {print $2}')

    # 比较当前 IPv6 地址与之前记录的地址
    if [ "$CURRENT_IPV6_ADDRESS" != "$PREVIOUS_IPV6_ADDRESS" ]; then
    echo "IPv6 Changed : $CURRENT_IPV6_ADDRESS"
    # 执行相应的操作或触发事件
    echo "Restart radvd"
    /etc/init.d/radvd restart
    # 更新记录的 IPv6 地址
    PREVIOUS_IPV6_ADDRESS=$CURRENT_IPV6_ADDRESS
    fi

    sleep 60 # 每隔 60 秒检测一次 IPv6 地址的变化
    done
    JoeSmith
        13
    JoeSmith  
       2023-07-11 13:26:37 +08:00
    有一个疑问,本地机器同时有几个 IPv6 地址,访问 internet 的时候主机会选哪个作为源地址呢?只有一个公网 IP 的时候容易选,要是有多个公网 IP 呢?比如我 Lan 上接了俩运营商的路由器,就会广播两个公网前缀。
    其实只有一个公网 IP 的时候我也不十分确定,因为我记得好像抓包看到过 internet 访问源 IP 用的 FE 开头的内网地址。
    zent00
        14
    zent00  
       2023-07-11 13:46:03 +08:00   ❤️ 1
    贴一个 VyOS v1.4 的 IPv6 防火墙范例

    假设我的 Home Server 地址后缀为 ::1234 ,这台服务器上有一个 WireGuard 监听在 UDP 65000 端口,我想要从公网通过 IPv6 连接家里的 WireGuard ,可以这样添加防火墙规则:

    set firewall ipv6-name WAN-LAN-v6 rule 30 action accept
    set firewall ipv6-name WAN-LAN-v6 rule 30 destination address ::1234
    set firewall ipv6-name WAN-LAN-v6 rule 30 destination address-mask ::ffff:ffff:ffff:ffff
    set firewall ipv6-name WAN-LAN-v6 rule 30 destination port 65000
    set firewall ipv6-name WAN-LAN-v6 rule 30 protocol udp
    raysonx
        15
    raysonx  
    OP
       2023-07-11 14:28:38 +08:00
    @JoeSmith 地址选择是个很复杂的问题。RFC6724 中定义了源地址选择的流程 https://datatracker.ietf.org/doc/html/rfc6724#section-5

    简单来说,如果你同时有联通和电信两家的公网地址,访问电信的站点时会优先选用电信的源地址,访问联通的站点时优先用联通的源地址(按照最长公共前缀匹配)。只有没有公网地址时才会选用内网地址。
    LnTrx
        16
    LnTrx  
       2023-07-11 14:36:34 +08:00
    @Jirajine 没太看懂,Docker 用 macvlan 配 IPv6 公网访问能满足你的需求么?
    LodonBoy10086
        17
    LodonBoy10086  
       2023-07-11 17:06:30 +08:00
    光猫里,路由配置项目怎么设置呢。有三项:动态路由配置、静态路由配置、IPv6 静态路由配置
    使用 ULA 后还需要配置 IPv6 静态路由配置?
    动态路由配置:RIP V1 V2 这些,家庭用户需要开启么? UPNP 关掉后影响 LOL 这些网游延迟么?
    raysonx
        18
    raysonx  
    OP
       2023-07-11 17:13:25 +08:00
    @LodonBoy10086
    除非你有多台设备运行在路由模式下,否则不需要手动配置路由表。

    > UPNP 关掉后影响 LOL 这些网游延迟么?
    不影响。
    qwvy2g
        19
    qwvy2g  
       2023-07-11 17:42:37 +08:00
    其实如果 ipv6 能像有些防火墙那样直接对 mac 地址做策略就好了。
    raysonx
        20
    raysonx  
    OP
       2023-07-11 17:49:29 +08:00
    @qwvy2g 这是不可能的,根本不是一个层级的事。mac 地址不能跨路由器,而且二层甚至不一定是以太网。
    LodonBoy10086
        21
    LodonBoy10086  
       2023-07-11 18:13:53 +08:00
    #20 光猫里可以对 mac 做策略啊 如果这条算防火墙的话:2.MAC 过滤在 IPv4 和 IPv6 下同时生效。
    raysonx
        22
    raysonx  
    OP
       2023-07-11 18:17:06 +08:00
    @LodonBoy10086 感觉你说的是交换机的 acl 。
    网络是分层的,二层的事网络层不管。
    LodonBoy10086
        23
    LodonBoy10086  
       2023-07-11 18:39:17 +08:00
    #22 原来如此
    tediorelee
        24
    tediorelee  
       2023-07-11 21:33:42 +08:00
    大佬关于文章里说到的“最佳实践:关闭 DHCPv6 服务,改用 SLAAC 无状态分配”,我现在是 LAN 口的设置是这样,是不是把 DHCPv6 关掉就可以了?


    还有个问题就是关于之前您的帖子 ipv6 速度过慢 PMTU 的问题,我这里在防火墙区域里看到是已经勾选了 MSS 钳制,是不是就不用管这个问题了?好像平时使用也没遇到过啥访问慢的问题
    raysonx
        25
    raysonx  
    OP
       2023-07-11 21:49:08 +08:00
    @tediorelee 是的,DHCPv6 可以关闭。通常来讲勾选 MSS 钳制后一般就不必管 PMTU 的事了,如果还不行再尝试手动指定 MSS 。
    tediorelee
        26
    tediorelee  
       2023-07-11 22:30:16 +08:00
    @raysonx #25 关了直接没 ipv6 了。。这是咋回事
    raysonx
        27
    raysonx  
    OP
       2023-07-12 12:53:18 +08:00
    @tediorelee 前缀长度是多少?用 SLAAC 的时候前缀最长只能到 64.
    hongyichao
        28
    hongyichao  
       2023-07-12 15:24:36 +08:00
    小白提问下,IPV6 不能像 V4 一样,直接给客户端指定静态 IP 地址吗。因为 IPV6 是公网,所以不能手动指定,要指定只能手动指定本地链路 IPV6 地址?
    jakes
        29
    jakes  
       2023-07-12 16:12:10 +08:00
    你们的 mac fe80 本地链接地址是不是每次重启都会变?
    raysonx
        30
    raysonx  
    OP
       2023-07-12 20:13:11 +08:00
    @jakes Wi-Fi ?如果开启了随机 mac 地址,本地链路地址会随 mac 地址变化而变化。
    raysonx
        31
    raysonx  
    OP
       2023-07-12 20:14:48 +08:00
    @hongyichao 运营商不给你公网前缀的情况下没法使用静态的公网地址。本地链路地址和 ula 地址和运营商无关,可以自己随便指定。
    hongyichao
        32
    hongyichao  
       2023-07-13 01:21:03 +08:00
    @raysonx 就是说因为 ipv6 都是公网,所以自己设可能会冲突,故由 ISP 分发前缀就可以避免冲突,保证地址唯一,毕竟前缀有 56-64bits ,足够区分了,然后就是剩下的 bits 由路由器自动给下面的主机配置吧。
    LodonBoy10086
        33
    LodonBoy10086  
       2023-07-13 02:01:37 +08:00
    systemd-networkd.service 没开启,但 networking.service 开启。networking 也能用 IPv6PrivacyExtensions=true 吗
    LodonBoy10086
        34
    LodonBoy10086  
       2023-07-13 02:02:04 +08:00
    >用 SLAAC 的时候前缀最长只能到 64.

    60 是长还是短?
    LodonBoy10086
        35
    LodonBoy10086  
       2023-07-13 02:27:37 +08:00
    像下面配置的 vps ,怎么设置 IPv6PrivacyExtensions ?
    auto lo
    iface lo inet loopback

    auto ens2
    iface ens2 inet dhcp

    # control-alias ens2
    iface ens2 inet6 static
    LodonBoy10086
        36
    LodonBoy10086  
       2023-07-13 02:28:33 +08:00
    还想请教,配置 4in6 需要一个公网 ipv4 ,对么?
    LodonBoy10086
        37
    LodonBoy10086  
       2023-07-13 02:32:05 +08:00
    又比如 vps 有一块 v6 。我想让::1 和我的电脑连;让::6666 对外访问。应该怎么设置呢
    raysonx
        38
    raysonx  
    OP
       2023-07-13 06:28:01 +08:00 via iPhone
    @hongyichao 运营商只分配前缀,后缀是由你的设备自己决定的。
    raysonx
        39
    raysonx  
    OP
       2023-07-13 06:30:36 +08:00 via iPhone
    @LodonBoy10086 参考 ifupdown 的配置。
    短。
    你说的是 6in4 吧?隧道两边都需要公网 ipv4 。
    没看明白,建议仔细描述使用场景。
    jakes
        40
    jakes  
       2023-07-13 08:09:34 +08:00 via iPhone
    @raysonx 不是 WiFi ,是 USB 有线网卡,我关掉限制 ip 追踪还是会变
    lovelylain
        41
    lovelylain  
       2023-07-14 08:46:30 +08:00 via Android
    固定 ipv6 地址后缀很难确保,所以换个思路:
    只通过路由器 wan 口对外提供 ipv6 服务,同时在路由器上部署 nginx ,将 ipv6 请求以 ipv4 转发到内网实际提供服务的机器,防火墙规则在 input 链里放行端口不写 ip ,完事。
    JiangkaaiShenng
        42
    JiangkaaiShenng  
       2023-07-14 17:36:29 +08:00
    都说 SLAAC 好,可是分配要等半天
    huamiao
        43
    huamiao  
       2023-07-14 22:50:11 +08:00
    @raysonx 我有个场景已经搞了 2 天了还是无法完美。不知是否能给点建议。
    我使用的是 OPNSense ,2 根线做主备,都有公网 IP 。现在应用 IPv6 ,OPNSense 提供的 GUI 无法在一个接口上绑定 2 个 IPv6 配置(我不清楚其它 OS 是否也是这样,目前也还没了解过是否可以通过修改配置文件实现),所以当 WAN0 挂了之后,IPv6 流量无法走 WAN1 。
    因此,目前我使用了 ULA+NPTv6 ,这样可以正常的使用 multiwan 。但这样带来一个问题,我无法从外面访问 WAN 接口(上面跑了 VPN 接入服务),ping 也无法 ping 通。
    OPNSense 论坛里聊了下,应该是 NPT 在 PF (防火墙)之前生效,直接把 WAN 的地址前缀替换成 ULA 前缀了,即使这个地址实际上是不存在的。我也不清楚这算是 OPNSense 特有的问题还是其它 OS 也是这样。最终我从内网可以正常的访问互联网,但外面不能访问内网的服务。
    想请教下有没有更好的方案?
    cnbatch
        44
    cnbatch  
       2023-07-15 21:55:58 +08:00   ❤️ 2
    @huamiao 我一样在用这个系统,对于这个问题也关注了很久。

    准确来说,这主要是 OpenBSD 的锅,其次是 pfSense 的锅,随后被 OPNSense 继承。

    OPNSense 用的是 PF 防火墙——源自于 OpenBSD ,然后被移植到 FreeBSD ,接着由 OPNSense 作为默认防火墙使用。

    OpenBSD 那边不太喜欢 IPv6 ,或者说不太喜欢 IPv6 的某些特性:IPv4 映射地址,还有 NPTv6 。
    PF 原本是支持 IPv4 映射地址的,突然从某个版本开始,他们去掉了这个支持,理由是为了“安全”。
    而 NPTv6 ,更是从一开始就没打算支持,OpenBSD 那群人甚至给 IPv6 弄了个内置 NAT ,就像 IPv4 那样。
    但 OPNSense 等系统需要用,那怎么办?(也就是 GUI“内置”的 NPTv6 )只好搞个半自动支持,用脚本更新防火墙设置,因为 PF 本身并没有 NPT 的功能。只不过目前比较死板,只能认一个,搞成了半成品的模样。

    这个 NPTv6 ,对于 BSD 系列而言,恰恰就是解决多 WAN 前缀+策略路由的关键。
    PF 不支持,导致 OPNSense 也无法启用,拖了好几年都解决不了这个问题:
    https://github.com/opnsense/core/issues/5284
    https://github.com/opnsense/core/issues/6158
    OPNSense 开发者们只能采取折衷的办法(目前正在做),那就是持续监控前缀地址,一旦发生变化了就用脚本更新设置。很可能 2024 版都没法没好。

    如果不更换系统,目前唯一做法就只能等。


    既然写了这么多字了,那就顺便再写一点。

    其实 FreeBSD 自家的 ipfw 防火墙原本已经引入了 NPTv6 ,并且能够正常使用。可惜在最近的几个大版本当中,这个功能出了问题,用都用不了。

    我在 FreeBSD 的论坛里的提问:
    https://forums.freebsd.org/threads/how-to-properly-configure-nptv6.88971/
    没人知道怎么解决,也没人找出是谁的代码出了 bug 。
    后来我在邮件列表里问了下,同样也没人知道问题出在哪里。
    我还顺带发现 ipfw 的邮件列表的“催 bug 机器人”发的提醒邮件比人类邮件还要多。

    如果 ipfw 的 NPTv6 功能恢复正常,那倒是可以尝试手动启用 ipfw 单独配置 NPTv6 的部分。
    huamiao
        45
    huamiao  
       2023-07-15 23:07:43 +08:00 via iPhone
    @cnbatch 感谢这么详细的回答。按现在的情形,也只能等着了。
    dream2cast
        46
    dream2cast  
       2023-07-18 14:54:03 +08:00
    @Jirajine 我目前用的 qBittorrent Docker 容器,是用 macvlan 建立一个 network 直接桥接至路由器 LAN ,docker 建立这个网络时,不用配置 IPv6 的部分(如:docker network create -d macvlan --subnet=192.168.10.0/24 --gateway=192.168.10.1 -o parent=br0 ),建立容器时,加一个参数--sysctl net.ipv6.conf.all.disable_ipv6=0 ,容器就可以通过 SLAAC 的方式直接从路由获取到 v6 地址了
    xiaooloong
        47
    xiaooloong  
       2023-08-08 11:28:15 +08:00
    等一个楼主的 opnsense ipv6 最佳实践,想跟着做一遍。
    xiaooloong
        48
    xiaooloong  
       2023-08-09 09:31:47 +08:00
    找到问题了: /t/880857
    运营商只分配 /64 的网络,导致 wan 拿了 /64 后不能给 lan 继续分了
    z5e56
        49
    z5e56  
       2023-09-12 00:15:50 +08:00
    请问有没有仅 systemd-networkd 的配置示例?使用 Debian 作为软路由拨号,最新版的 systemd (version 252) 配置方式与以前版本的并不一样,目前还没成功
    phx13ye
        50
    phx13ye  
       89 天前
    Network Manager 的命令是不是要改成`nmcli c show`显示的 name ,不是用 eth0 网卡名啊
    sleepm
        51
    sleepm  
       89 天前
    @xiaooloong lan 设置跟踪接口 wan
    重新连接 wan 后,lan 能获得一个 /60
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1055 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 18:14 · PVG 02:14 · LAX 10:14 · JFK 13:14
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.