← 行间 技术 / OpenWrt
技术

Raspberry Pi 5 + OpenWrt + OpenClash:可复现的个人透明网关搭建流程

目标:把 Raspberry Pi 5 上的 OpenWrt 做成一个独立 Wi-Fi 网关。设备连上它的热点后无需额外客户端即可分流(国内直连 / 国外走代理)。

本文按“下次还能快速复刻”的方式写:先定拓扑 → 再按步骤做 → 坑点不打断主线(文末速查)


0. 一页速查(下次复现只看这里)

示例:上游主路由 192.168.2.1/24;OpenWrt LAN/Wi-Fi 192.168.3.1/24

  • 定拓扑:两网段(关键,否则透明代理可能“像没生效”)
  • 刷 ext4-root 镜像到 TF 卡(dd
  • 扩容:parted resizepart + resize2fs(必要时修 cmdline.txt 的 root)
  • 默认IP修改:直连使用uci修改,先保证能进 LuCI/SSH
  • 安装 OpenClash:手动 ipk + 替换 dnsmasq-full + 修 LuCI 菜单/404
  • 两网段拆分:LAN=3 段;WAN 从主路由 DHCP;必要时临时放开 WAN input 作“后门”
  • 验收:终端拿到 192.168.3.x、网关 192.168.3.1;OpenClash Running
  • 收尾:把 WAN input 收回 REJECT

1. 先定最终拓扑(决定“透明代理能不能成立”)

最终形态:两个网段

  • 上游主路由(出网):192.168.2.1/24
  • OpenWrt WAN:从主路由 DHCP 获取 192.168.2.x
  • OpenWrt LAN/Wi-Fi:192.168.3.1/24
  • 连热点的设备:拿到 192.168.3.x,默认网关指向 192.168.3.1

为什么一定要两网段:透明代理依赖终端流量必须经过 OpenWrt 三层转发路径。WAN/LAN 混同网段时,终端很容易绕过 OpenWrt 直接找主路由出网,导致“国内能上、国外失败/像没开代理”。


2. 刷机:选 ext4-root 镜像 + dd 写 TF 卡

2.1 镜像选择建议

优先使用 ext4-root 镜像(空间更适合装 OpenClash/核心/规则/依赖)。
ext4-factory 用于第一次写卡;ext4-sysupgrade 用于系统内升级,不要拿来 dd 写卡。

2.2 Ubuntu 下 dd 写卡(示例)

  1. 找到 TF 卡设备名(避免写错盘):
lsblk
  1. 格式化存储卡并写入镜像:
sudo wipefs -a /dev/sdX
gzip -dc openwrt-24.10.4-bcm27xx-bcm2712-rpi-5-ext4-factory.img.gz
sudo dd if=openwrt-24.10.4-bcm27xx-bcm2712-rpi-5-ext4-sysupgrade.img of=/dev/sdX bs=4M status=progress conv=fsync
sync

3. 扩容:让整张卡空间真正可用(ext4-root 标准动作)

3.1 扩分区到整张卡

sudo parted /dev/sdX
(parted) print
(parted) resizepart 2 100%
(parted) quit
sudo partprobe /dev/sdX

3.2 扩 ext4 文件系统

sudo resize2fs /dev/sdX2

3.3 扩容常见问题

问题 A:Bad magic number in super-block / 找不到 superblock

通常是 resize2fs 对错分区了,或刷的并非 ext4-root。先 lsblk -f 确认根分区是 ext4 的哪一分区。

问题 B:扩容后启动卡死 Waiting for root device PARTUUID=...

编辑 boot 分区的 cmdline.txt,把:

  • root=PARTUUID=... 改为:
  • root=/dev/mmcblk0p2

注意:即便lsblk中显示的是/dev/sda,也请务必使用/dev/mmcblk0p2,这个原理暂时还没搞懂,但似乎是文件系统在不同设备中不同的体现


4. 默认IP修改

因为安装的是旁路路由,因此家中可能存在调制解调器和主路由器,这样192.168.1.1和192.168.2.1都被占据了,很可能与OpenWrt发生冲突,就会出现浏览器报 ERR_CONNECTION_REFUSED,或者OpenWrt设备获取的IP为0.0.0.0的情况。

此时不要硬猜配置,需要连接设备,使用uci set network.lan.proto='dhcp',修改设备获取IP的方式,使得可以接入ui来进行修改。

OpenWrt启动后可以通过主路由器的管理页面来查看IP,通过IP进入UI后首先配置WIFI热点,包括名称、密码、加密方式、Country Code。


5. 安装 OpenClash:手动 ipk + 解决“菜单不显示/404”

5.1 为什么 opkg 直接装会失败

OpenClash 通常不在官方 feed:opkg install luci-app-openclash 可能 Unknown package。 做法:下载 release 的 ipk(一般选 *_all.ipk)上传到 /tmp 后手动安装。

5.2 Windows scp 传文件失败:用 -O

Windows scp 默认可能走 SFTP,而 OpenWrt 端缺 sftp-server 会报: /usr/libexec/sftp-server: not found 用旧 scp 协议即可:

scp -O .\luci-app-openclash_0.xx.xxx_all.ipk root@<openwrt-ip>:/tmp

5.3 安装命令(含 LuCI 相关修复)

# 1) OpenClash 需要 dnsmasq-full
opkg remove dnsmasq
opkg install dnsmasq-full

# 2) 安装 OpenClash ipk
opkg install /tmp/luci-app-openclash_0.xx.xxx_all.ipk

# 3) 补齐 LuCI 环境(解决 Services 菜单缺失 / OpenClash 404)
opkg install luci luci-base luci-compat

# 4) 清缓存 + 重载(两种方式二选一)
rm -f /tmp/luci-indexcache
rm -f /tmp/luci-modulecache/*
luci-reload 2>/dev/null || /etc/init.d/uhttpd restart

这一步比较奇怪,个人尝试时之前就已经多次在UI和Terminal上运行了opkg update,但是运行opkg install /tmp/luci-app-openclash_0.xx.xxx_all.ipk依然提示依赖不存在,再次更新后运行,可以开始自动下载依赖,似乎update并不是幂等的,update会更新部分的内容,然后基于本次更新的,再可以进行下一次update(这只是一个猜想,具体原理还没搞清楚)


6. 关键一步:两网段拆分(解决“国内能上、国外像没代理”)

如果 OpenClash 看似安装成功但国外仍打不开,优先怀疑:终端流量没经过 OpenWrt(默认网关还是主路由)。 拆成两网段后,连热点的终端必须拿到 192.168.3.x,默认网关必须是 192.168.3.1

6.1 目标结构(标准旁路由/透明网关)

br-lan
 └── phy0-ap0        ← 只给 Wi-Fi 用

lan (static)
 └── br-lan          ← 192.168.3.1

wan (dhcp)
 └── eth0            ← 从主路由拿 192.168.2.x

6.2 先开一个“救援后门”(强烈建议)

在改网段前,建议先临时把 WAN zone 的 input 放开,避免配错后彻底进不来。

大多数情况下 wan zone 名称就是 wan,直接用下面命令即可;如果系统没有 firewall.wan 这个段,再去 LuCI 里确认 wan zone 对应的是哪个 @zone[x]

uci set firewall.wan.input='ACCEPT'
uci commit firewall
/etc/init.d/firewall restart

6.3 拆网段配置(合并版 uci batch)

注意:network.@device[0].ports='phy0-ap0' 依赖的设备/端口命名。 如果这里不同,先 uci show network | grep device 看看 br-lan 对应哪个 device、ports 是什么,再改成实际值。

# 1) 网络:LAN 改静态 192.168.3.1;WAN 用 eth0 DHCP;br-lan 只保留 Wi-Fi 端口
uci batch <<'EOF'
set network.lan.proto='static'
set network.lan.ipaddr='192.168.3.1'
set network.lan.netmask='255.255.255.0'

set network.wan.proto='dhcp'
set network.wan.device='eth0'

# 让 br-lan 不再包含 eth0(只服务 Wi-Fi)
set network.@device[0].ports='phy0-ap0'
EOF

uci commit network

# 2) DHCP:确保 LAN 发地址(并清掉可能存在的 ignore)
uci set dhcp.lan=dhcp && \
uci set dhcp.lan.interface='lan' && \
uci set dhcp.lan.start='100' && \
uci set dhcp.lan.limit='150' && \
uci set dhcp.lan.leasetime='12h'

uci delete dhcp.lan.ignore
uci commit dhcp

# 3) 重启网络与 DHCP
/etc/init.d/network restart
/etc/init.d/dnsmasq restart

7. 拆分后“SSID 还在但连不上/秒断/进不了 192.168.3.1”:优先查 DHCP

这种现象最常见原因:dhcp.lan.ignore='1' 导致 LAN 不发 DHCP,终端拿不到 IP 就会断。

修复(合并版):

uci batch <<'EOF'
delete dhcp.lan.ignore
set dhcp.lan.interface='lan'
EOF
uci commit dhcp
/etc/init.d/dnsmasq restart

7.1 如果已经改到进不去:怎么救回来

如果在第 6 步提前把 WAN input=ACCEPT 放开了,通常可以从主路由网段(192.168.2.x)侧重新进入 LuCI/SSH 修配置。 (OpenWrt 24.x 默认 fw4/nftables,iptables 不一定存在,尽量用 UCI/防火墙服务重启来改。)

如果无法远程接入,那就只能通过HDMI连接OpenWrt设备来直接修改了。


8. 验收与收尾(长期稳定可用)

8.1 验收清单

连上 OpenWrt 热点后,终端应满足:

  • IP:192.168.3.x
  • 网关:192.168.3.1

OpenWrt 侧建议检查:

ip a
ip r
ping -c 3 1.1.1.1
nslookup google.com 127.0.0.1

OpenClash:

  • 核心已安装
  • 服务 Running
  • 日志能看到终端来源 IP 的转发/规则命中(有流量才有意义)

8.2 收尾:把 WAN 管理口收回去(安全必做)

第 6 步为了救援把 WAN input 改成了 ACCEPT,最终必须改回 REJECT:

uci set firewall.wan.input='REJECT'
uci commit firewall
/etc/init.d/firewall restart

附录 A:问题速查索引(不打断主线,但能快速定位)

  • 扩容报 superblock / magic number 错:多半分区选错或不是 ext4-root;先 lsblk -f 对齐再扩
  • 扩容后卡死 Waiting for root device:修 cmdline.txtroot=/dev/mmcblk0p2
  • Unknown package luci-app-openclash:OpenClash 不在官方 feed,改用 release ipk 手动安装
  • Windows scp 报 sftp-server not found:用 scp -O 强制旧 scp 协议
  • LuCI 没有 Services / OpenClash 404:补齐 luci/luci-base/luci-compat + 清缓存 + 重启 uhttpd
  • 国内能上国外不行:终端绕过 OpenWrt;用“两网段拆分”保证终端默认网关为 192.168.3.1
  • 拆分后连不上 Wi-Fi/进不了 3.1:优先查 dhcp.lan.ignore=1(LAN 不发 DHCP)