在 Selfnet 宿舍网下把红米 AX6(OpenWrt)改成桥接 AP:保留 IPv6 与 ZeroTier 的实践记录

2025年9月12日 | Ruichen Zhou
OpenWrtIPv6SelfnetZeroTier路由器

在 Selfnet 宿舍网下把红米 AX6 改成桥接 AP

这篇文章记录的是我在德国斯图加特大学宿舍使用 Selfnet 网络时,对一台刷入 AE86Wrt(基于 OpenWrt)的红米 AX6 路由器所做的一次网络结构调整:把它从传统的”路由器模式(NAT + DHCP)“改成 Dumb AP / 桥接模式,让终端直接获取公网 IPv6,同时保留 ZeroTier 远程管理。

中间包含一些典型的误区,比如:在运营商已经做了 CGNAT 的前提下,还在自己这边叠加 NAT、到处找端口转发入口,以及在嵌入式设备上过度折腾配置、装太多软件导致闪存打满。这里把过程梳理出来,方便后面自己查,也给遇到类似场景的人做个参考。


一、背景与目标

1.1 网络环境与设备

设备清单(与系列其他文章保持一致):

  • 上游网络:Selfnet(德国学生宿舍校园网)
    • IPv4:分配 100.78.x.x 段地址,属于 CGNAT(运营商级 NAT)
    • IPv6:原生公网地址(2001:2a00: 等前缀)
  • 主路由器:红米 AX6(刷了 AE86Wrt 固件,基于 OpenWrt)
  • Linux 工作站:位于中国大陆,Linuxmint 系统,主要开发环境(本文不涉及)
  • MacBook Air:便携开发设备,在宿舍和工位之间通勤使用
  • Windows 电脑:长期位于德国学生宿舍
  • 其他终端:手机、平板等移动设备

Selfnet 的 IPv4 本身就处在 CGNAT 之后,再在路由器上做一次 NAT,等于叠加了两层 NAT;而 IPv6 本来就是原生公网,如果处理不当,反而会把优势”浪费”掉。

1.2 想解决的问题

我希望达到的目标是:

  1. 路由器只做 AP / 交换机

    • 不再做 IPv4 NAT / DHCP / 防火墙
    • 让终端设备尽量”像直接插墙口那样”工作
  2. 终端直接拿公网 IPv6

    • 每个终端拿到 2a00:(或 2001:)开头的全球单播地址
    • 方便做一些 IPv6 实验或直接暴露服务
  3. 保留远程管理通道

    • 路由器上已经跑了 ZeroTier,用来远程管理
    • 切换到 Dumb AP 后仍希望其保持在线
  4. 避免把自己锁在路由器外面

    • 完全交给上游 DHCP 后,如果上游改配置或我手滑弄坏 LAN,仍需要一个”后门 IP”能进去救机

1.2 想解决的问题

我希望达到的目标是:

  1. 路由器只做 AP / 交换机

    • 不再做 IPv4 NAT / DHCP / 防火墙
    • 让终端设备尽量“像直接插墙口那样”工作
  2. 终端直接拿公网 IPv6

    • 每个终端拿到 2a00:(或 2001:)开头的全球单播地址
    • 方便做一些 IPv6 实验或直接暴露服务
  3. 保留远程管理通道

    • 路由器上已经跑了 ZeroTier,用来远程管理
    • 切换到 Dumb AP 后仍希望其保持在线
  4. 避免把自己锁在路由器外面

    • 完全交给上游 DHCP 后,如果上游改配置或我手滑弄坏 LAN,仍需要一个“后门 IP”能进去救机

1.3 适用前提

这套做法适用于以下条件:

  • 上游网络能对终端直接下发 IPv6 地址和默认路由(比如 Selfnet 这种)
  • 不需要在自己这台路由器上再划分新的子网(例如家长控制、多 VLAN 等)
  • 接受“终端暴露在上游网络里”(无本地防火墙保护)这一点,或者打算在终端自身、或额外防火墙设备上做安全控制

如果你需要强隔离、自管子网或者复杂的策略,这篇文章里的方案就不合适,可以考虑继续用路由模式、单独做 IPv6 relay 或再加一台防火墙。


二、最终网络状态概览

先把调整完成后的整体状态总结一下,方便对照。

项目当前结果
路由器角色Dumb AP / 二层桥接
上游 IPv4 网关100.78.32.174(Selfnet 内部 NAT)
终端 IPv6直接获得 2a00: 开头的全球单播地址
路由器本地管理192.168.7.2/24(仅作管理后门,不对外广播)
ZeroTier正常上线,虚拟网段 192.168.192.0/24
DHCP / NAT / 防火墙在路由器上全部关闭
交换机桥设置启用 STP,关闭 IGMP Snooping

整体可以理解为:红米 AX6 路由器和宿舍墙口之间只是一座二层桥,真正的三层网关、DHCP、IPv6 RA 都在 Selfnet 一侧完成;路由器只负责把这些广播转到自己无线和 LAN 端口,同时维持一个不受影响的本地管理通道。


三、操作步骤与配置说明

下面的命令都在路由器的 SSH 终端下执行,环境基于 OpenWrt / AE86Wrt。每一步后都有简短说明,防止“只抄命令不理解”。

3.1 添加本地管理别名(后门 IP)

uci set network.lan_alias='interface'
uci set network.lan_alias.device='br-lan'
uci set network.lan_alias.proto='static'
uci set network.lan_alias.ipaddr='192.168.7.2'
uci set network.lan_alias.netmask='255.255.255.0'
uci commit network
/etc/init.d/network reload

为什么要这一步?

桥接模式下,LAN 接口本身会从上游 DHCP 拿到 IP。 一旦上游 DHCP 改了网段、或者你在 LAN 上误操作,很容易出现“找不到路由器”的情况。

br-lan 多绑一个完全独立的管理地址 192.168.7.2/24,可以让你在出现问题时:

  1. 把电脑网卡手动设为 192.168.7.10/24(不需要网关)
  2. 直接访问 http://192.168.7.2 打开 LuCI 管理界面

这是一个纯本地的“后门”,不会影响上游网络,也不会被上游 DHCP 覆盖。


3.2 把 LAN 改为 DHCP 客户端(路由器自己能上网)

uci set network.lan.proto='dhcp'
uci -q del network.lan.ipaddr
uci -q del network.lan.netmask
uci -q del network.lan.gateway
uci -q del network.lan.dns
uci commit network
/etc/init.d/network restart

思路:

  • 传统路由模式下,LAN 一般是 192.168.x.1/24 之类的静态地址,用来给内网发号

  • 在桥接模式里,我们希望 LAN 直接接在上游二层网络里,自己也当一台普通客户端

  • 所以把 lan.proto 改为 dhcp,让它向 Selfnet 请求 IPv4 地址和网关

  • 结合前面的 lan_alias,路由器实际会有两个 IPv4 地址:

    • 一个是 Selfnet 分配的 100.78.x.x(用于出网、ZeroTier)
    • 一个是本地管理用的 192.168.7.2

验证示例:

ip -4 addr show br-lan | sed -n '1,5p'
ip route

典型输出类似:

inet 192.168.7.2/24 scope global br-lan
default via 100.78.32.174 dev eth0 proto static src 100.78.32.161

可以看到:br-lan 上既有 192.168.7.2/24,也从 Selfnet 拿到了 100.78.32.161 以及默认路由。


3.3 关闭 DHCP / RA / IPv6 发号功能

风险提示:这一步会让路由器不再对内网设备提供任何 IP / IPv6 配置。请确认上游网络(这里是 Selfnet)本身能正常下发 IPv4/IPv6 地址,再执行。

uci set dhcp.lan.ignore='1'
uci set dhcp.lan.ra='disabled'
uci set dhcp.lan.dhcpv6='disabled'
uci set dhcp.lan.ndp='disabled'
uci commit dhcp
/etc/init.d/dnsmasq restart
/etc/init.d/odhcpd restart 2>/dev/null || true

这一步的目的:

  • 避免和 Selfnet 的 DHCP / IPv6 RA 产生冲突
  • 终端设备只从 Selfnet 收到一个统一的地址和网关配置
  • 路由器自己只是透明转发这些广播,不再参与地址规划

3.4 调整无线为 AP 模式并挂到 LAN

wifi_index=0
for i in $(seq 0 3); do
  uci -q get wireless.@wifi-iface[$i] || break
  uci set wireless.@wifi-iface[$i].mode='ap'
  uci set wireless.@wifi-iface[$i].network='lan'
  uci set wireless.@wifi-iface[$i].isolate='0'
done
uci commit wireless
wifi reload

关键点说明:

  • 所有无线接口统一绑到 lan 网络,这样无线客户端和有线 LAN 端口处在同一个二层广播域
  • isolate=0 关闭 AP 隔离,方便局域网内互访(如 AirDrop、局域网打印、多设备传输)
  • 如果你想把访客 Wi-Fi 隔离开,可以单独为那个 SSID 配一个 VLAN / 接口,而不是全局开启隔离

3.5 桥接参数优化(STP / IGMP)

uci set network.device='device'
uci set network.device.name='br-lan'
uci set network.device.type='bridge'
uci set network.device.stp='1'
uci set network.device.igmp_snooping='0'
uci commit network
/etc/init.d/network restart

STP 开启的意义:

  • 如果你的网络拓扑里存在多个交换机 / AP,有可能形成环路
  • 打开 STP 能够在二层上自动探测并阻断环路,避免广播风暴

为什么关 IGMP Snooping:

  • 在某些环境里,开启 IGMP Snooping 反而容易出现多播丢包
  • Selfnet 自己对多播的处理策略比较固定,路由器在中间再加一层“聪明”的组播管理,风险反而更大
  • 出于稳妥,先关掉;如果你有明确的多播需求(IPTV 等),再根据实际测试考虑开启

3.6 验证终端上的公网 IPv6

在终端(例如 Windows、Linux 或 macOS)上执行:

curl -6 ifconfig.co

预期输出类似:

2a00:20:32d6:b60e:1886:ba2c:c78a:2838

这表示终端已经拿到了公网 IPv6 地址,且能通过 IPv6 访问外网。

如果你在 Selfnet 的自助门户里为某个 IPv6 地址配置了开放端口规则,那么从外部(例如手机 4G)就可以直接访问这个设备提供的服务,无需再经过本地端口转发。


四、如何从桥接模式恢复到原来的路由模式

有时候需要暂时恢复到 “NAT + DHCP” 的传统路由模式,比如:想自己划分子网,或者在家用环境复用这台路由器。可以用下面的命令回滚。

风险提示:这一步会重置 LAN 的网段和 DHCP 行为,执行前最好用 LuCI 做一个配置备份。

# 恢复 LAN 为静态管理网段
uci set network.lan.proto='static'
uci set network.lan.ipaddr='192.168.6.1'
uci set network.lan.netmask='255.255.255.0'
uci del network.lan_alias     # 如无需后门管理,可删除
uci commit network

# 重新启用 DHCPv4/v6 服务
uci set dhcp.lan.ignore='0'
uci set dhcp.lan.ra='server'
uci set dhcp.lan.dhcpv6='server'
uci set dhcp.lan.ndp='relay'
uci commit dhcp

/etc/init.d/dnsmasq enable
/etc/init.d/odhcpd enable 2>/dev/null || true
/etc/init.d/firewall enable
/etc/init.d/network restart

# WAN/WAN6 接口通过 LuCI 重新启用
# LuCI → 网络 → 接口 → 勾选并启动 WAN / WAN6

恢复后,路由器重新成为一个标准的 NAT 网关;终端重新拿到 192.168.6.x 这种私网地址。


五、Selfnet 环境下的优缺点分析

5.1 优点

  1. 充分利用原生 IPv6

Selfnet 原本就给每台设备分配全球可路由的 IPv6 地址。桥接后,终端直接获得这些地址,避免在自己设备上再做 NAT66 或额外的隧道配置。

  1. 减少一层 NAT,降低延迟

IPv4 侧虽然仍然在 Selfnet 的 CGNAT 后面,但至少去掉了本地路由器的 NAT,一部分 UDP 应用能更“直白地”看到上游对称 / 全锥型 NAT 的行为,排除一些本地 NAT 造成的问题。

  1. 局域网通信更加自然

由于 AP 只是桥接,所有终端等价于在同一个二层广播域下,与直接插在墙上的行为一致。像 LocalSend、AirDrop、局域打印这类依赖广播 / 组播的服务更容易工作。

  1. ZeroTier 远程管理保留

路由器本身作为 Selfnet 的一个客户端,仍然能通过其 100.78.x.x 地址访问 ZeroTier 网络,从而保持远程管理能力。它的角色更像“管理上的跳板机”,而不是数据面上的 NAT 网关。

  1. 本地管理后门避免锁死

192.168.7.2/24 这个 alias 让你在误配 LAN / DHCP 时,总能通过手工设 IP 的方式回到管理界面,而不需要拆机刷机。

5.2 缺点和风险

  1. 失去本地防火墙保护

在 Selfnet 这种环境下,桥接意味着终端直接暴露在上游二层网络中。虽然对方通常有基础的隔离策略,但你等于放弃了本地路由器作为“家庭防火墙”的角色。终端自身的系统防火墙就显得更重要。

  1. 无法做子网划分和策略控制

所有终端都被视为一个子网中的“平等公民”。你很难在本地对不同设备做分网段、访问控制、家长控制等细粒度管理。

  1. 依赖上游 DHCP/RA

本地不再提供 DHCP 和 IPv6 RA,一旦 Selfnet 那边做了调整,终端就直接受影响,本地没有机会做兜底配置。

  1. 无法做传统 port forwarding

由于 IPv4 在 Selfnet 侧本就处于 CGNAT 后面,本地 NAT 即使存在也很难向外开放 IPv4 服务。IPv6 可以通过 Selfnet 门户来做端口开放,但那是针对终端的 IPv6,而不是本地再做一次 IPv4→IPv6 转换。


六、当前地址与拓扑示意

最终状态可以用下表描述:

项目说明
IPv4 地址100.78.32.161Selfnet 分配的 CGNAT 内部地址
IPv4 网关100.78.32.174Selfnet 上游 NAT 网关
终端 IPv6 地址2a00:20:32d6:b60e:1886:ba2c:c78a:2838真正的公网 IPv6,可被外部访问
ZeroTier 网段192.168.192.0/24用于远程管理的虚拟私有网络
本地管理192.168.7.2/24仅用于进入路由器管理界面

从上到下的逻辑是:

  • Selfnet 使用 CGNAT IPv4,但为每台设备提供原生 IPv6。
  • 路由器当作一台普通客户端,拿到自己的 IPv4/IPv6 后通过 ZeroTier 加入虚拟网络。
  • 局域网终端通过桥接直接与 Selfnet 交互,同时又有路由器这一层方便的 Wi-Fi 和管理通道。

七、常见错误与排查思路

这里单列一节,整理我在过程中遇到或看到别人在类似场景下容易踩的坑。

7.1 把 WAN 和 LAN 接反

现象:

  • 路由器管理界面可以访问,但终端总是拿不到 Selfnet 的地址,或者拿到了 192.168.x.x 而不是 100.78.x.x
  • IPv6 测试网站得分为 0/10

原因:

  • 桥接模式下,应该把 Selfnet 墙口接到原来“LAN” 所在的桥上,而不是继续走传统的 WAN→LAN NAT 拓扑
  • 如果固件已经对端口做过重映射,要确认物理端口和逻辑 br-lan 是怎么对应的

排查:

  • 在路由器上 ip -4 addr show br-lan 看看是否出现 100.78.x.x
  • 在终端上 ipconfig / ip addr 检查,确认默认网关是不是 100.78.32.174 这一类上游地址

7.2 忘记关 DHCP / RA,导致“两个 DHCP”

现象:

  • 终端有时候拿 Selfnet 的 IP,有时候拿到路由器发的 192.168.x.x
  • IPv6 地址里既有 fe80::2001: 又多出一些奇怪的前缀
  • 局域网内访问偶尔异常,mDNS/组播服务不稳定

原因:

  • 路由器上的 dnsmasq / odhcpd 没关,和 Selfnet 的 DHCP/RA 同时在一个二层广播域里抢客户端

排查与修复:

  • /etc/config/dhcp 里确认 dhcp.lan.ignore='1'、RA/DHCPv6/ndp 都是 disabled
  • 重启 dnsmasq / odhcpd,然后重连终端,看是否只剩 Selfnet 提供的地址

7.3 没有保留本地管理地址,导致“锁死”

现象:

  • 改完 LAN/DHCP 后,再也找不到路由器在哪个 IP 上
  • 由于 Selfnet 不允许随便扫网段,直接“失联”

解决思路:

  • 预先在 br-lan 上加一个固定 alias(例如 192.168.7.2/24)
  • 以后只要把电脑手动设在同一网段,就能直接访问管理界面
  • 这一点在做任何改变 LAN 行为的操作前,都值得优先考虑

7.4 在嵌入式设备上过度折腾,导致闪存打满

这个问题主要是在我尝试“路由模式 + IPv6 relay + AdGuard Home”等复杂方案时暴露出来的:路由器上装了太多软件包(代理内核、地理库、主题、各种 LuCI 插件),最终 /overlay 空间完全用尽,导致:

  • uci commitI/O error
  • opkg install/removeNo space left on device
  • 配置文件写不进去,服务启不动

在这次实践里我最后退回了更简单的桥接方案,顺便意识到一个事实:在 128MB / 256MB 这类闪存空间的设备上,尽量减少“不必要的软件和图形主题”,优先保障核心网络功能有足够的余地,比什么都往里装更重要。


八、总结与反思:流程层面的几个改进

这次把红米 AX6 改成桥接 AP 的过程,其实技术上并不算复杂,真正在调试上花时间的部分,更多是“概念没有捋清就直接上手改配置”带来的返工。

下面这几点是我从这次折腾里总结出来、以后会刻意改进的习惯:

  1. 先画清楚“责任边界”,再选方案

    在 Selfnet 这种环境里,上游已经负责了绝大部分“路由器应该做的事情”:IPv4 NAT、DHCP、IPv6 RA 和前端认证。再在自己设备上重复做一遍,不仅带来复杂度,还会引入额外的 NAT、冲突和性能损失。

    以后遇到类似情况,先把“谁负责三层、谁负责二层”画清楚,再决定是用路由模式还是桥接模式。

  2. 在动 LAN 和 DHCP 之前,先留好“逃生通道”

    像这次设置 192.168.7.2 这样的管理 alias,看上去只是一个小细节,实际上在出现失误时是唯一的自救入口。如果一开始就预留好,就不至于出现“改完 LAN 才发现路由器不在任何已知网段”的尴尬。

  3. 对于受限设备,先评估闪存 / 内存,再决定要不要“上大工程”

    我在调试 IPv6 relay 和 AdGuard Home 的时候,照着聊天记录一通安装、配置,最后才发现闪存已经打满,很多操作都是无效的。今后在嵌入式设备上,应该在一开始就用 df -h 看看剩余空间,再决定要不要安装体积较大的服务。

  4. 减少对“脚本一键配置”的依赖,多看当前系统状态

    uci 的批量脚本确实方便,但如果不了解当前 /etc/config/network/etc/config/dhcp 的结构,很容易在已有配置上叠加出一个复杂、难以 debug 的状态。更稳妥的流程是:先用 cat 看清现状,再小步修改,并在每一步后做验证,而不是指望一段脚本一次性把所有东西改好。

  5. 接受“简单但够用”的方案

    对这个场景而言,桥接 + 本地管理 alias + ZeroTier 已经满足了所有需求:终端有原生 IPv6,路由器有远程管理通道,局域网通信正常。相比之下,用路由模式引入各种 IPv6 转发、去广告、深度策略控制,虽然“更酷”,但在这台路由器和这个宿舍网环境里并不一定划算。


这篇文章只覆盖了把红米 AX6 改成 Selfnet 下桥接 AP 的部分。围绕这个环境,我还尝试过用 Selfnet 门户做 IPv4/IPv6 端口转发、在 Windows 端折腾 OpenSSH/RDP、在路由器上做去广告等,后面会考虑拆成单独的几篇,把那些排查过程也整理出来。