家庭服务器全家桶折腾笔记:OpenWrt + OpenList + qBittorrent
🧭 家庭服务器全家桶折腾笔记:OpenWrt + OpenList + qBittorrent
💡 这套系统不是为了跑分,而是为了解决三个具体问题:网盘太分散、下载不可控、公网暴露太多。最终用三台机器拼出一条从「找资源」到「躺在沙发上看片」的完整链路。
0. 为什么折腾
事情的起因很普通:网盘会员到期,资源散在阿里、夸克、百度、蓝奏四个地方;NAS 上那块 2T 盘大部分时间只是躺着;而每次想看点东西,都要经历「找资源 → 下载 → 解压 → 改名 → 找字幕」的完整折磨。
于是给自己定了三个目标:
- 一个入口:所有网盘在一个页面里浏览、搜索、转存
- 自动下载:磁力/种子丢进去,剩下的交给系统
- 安全第一:管理后台只在内网,公网只留一条 Cloudflare Tunnel
同时也给自己画了三条红线:
- 不把路由器当全能机,路由只做路由
- 不让下载目录和媒体库重复占空间
- 不为了「看起来高级」而堆服务
1. 最终架构
先看全貌:
ProcessOn 原始拓扑图(重绘清晰版)

保留 ProcessOn 原图的浅色版式和信息结构,修复了文字溢出、节点过窄和箭头穿越的问题。原始 PNG 备份:processon-topology-original.png
说明:ProcessOn 原图的信息很全,但节点较窄、中文有溢出,所以正文主图用重绘版;原图保留在这里作对照。
整套系统分成五层:
| 层级 | 角色 | 关键组件 |
|---|---|---|
| 公网与入口 | 宽带、光猫、主路由 | Internet / 光猫 / 192.168.31.1 |
| 旁路由与局域网 | 分流、内网主机 | OpenClash .50 / Mac .101 / fnOS .51 / Debian .55 |
| 服务层 | 聚合、下载、媒体、建站 | OpenList、qBittorrent、MoviePilot、Jellyfin、1Panel |
| 存储与备份 | 数据盘、对象存储、异地备份 | 2T 数据盘、Garage、Cloudflare R2、GitHub Images |
| 管理面 | 远程维护、健康监控 | Tailscale、Uptime Kuma、两个自制看板 |
1.1 机器分工
| 机器 | 地址 | 配置 | 角色 |
|---|---|---|---|
| iStoreOS 软路由 | 192.168.31.50 | 2C / 1G | 旁路由、OpenClash、规则分流 |
| fnOS NAS | 192.168.31.51 | 2C / 5G + 2T | OpenList、qBittorrent、MoviePilot、Jellyfin |
| Debian 建站机 | 192.168.31.55 | 1C / 3G | 1Panel、OpenResty、Lsky、Garage、cloudflared |
| 主路由 | 192.168.31.1 | 家用路由 | DHCP、默认网关、局域网交换 |
这套分工和之前的 J4125 All-in-One 思路不太一样。All-in-One 很酷,但一台机器挂了,网络、存储、建站一起挂。现在把故障域拆开:
- 路由挂了,至少 NAS 和建站机还在
- NAS 挂了,博客和图片站还能活
- 建站机挂了,下载和媒体库不受影响
代价是多了几根网线和几个电源适配器,但换来的是排障时不用「一锅端」。
1.2 四条设计原则
原则一:主路由仍然是默认网关。 OpenClash 跑在旁路由上,只接管需要分流的客户端,不把全家人的网络绑在一台虚拟机上。
原则二:管理面不暴露公网。 1Panel、qBittorrent WebUI、OpenList 管理页、Jellyfin 全部只绑内网地址。需要远程时走 Tailscale,不开公网端口。
原则三:公网入口只走 Cloudflare Tunnel。 路由器不做任何端口映射,家庭公网 IP 不暴露。
原则四:下载和媒体库放在同一文件系统。 MoviePilot 用硬链接入库,不重复占空间。
2. 网络底座:iStoreOS + OpenClash
软路由是整套系统的地基。我用的是 iStoreOS 24.10.8,底层是 OpenWrt 24.10 分支,管理地址 192.168.31.50。
2.1 为什么选 iStoreOS
之前用过原版 OpenWrt 和爱快,最后留下 iStoreOS,原因很实际:
- 中文生态完整:应用商店里直接能装 OpenClash、PassWall、Docker 等插件,不用到处找 ipk
- LAN 默认是 DHCP 客户端:不会像原版 OpenWrt 那样首启广播
192.168.1.x的野 DHCP,怼上家里现有网段就是事故 - 底层仍是 OpenWrt:出问题能按 OpenWrt 的思路查,不会被厂商 UI 锁死
- 比爱快更适合折腾:爱快的流控和多拨很强,但插件生态和 OpenWrt 差距明显
2.2 安装 OpenClash
在 iStore 应用中心搜索 OpenClash 一键安装即可,依赖和内核会自动带上。也可以用命令行:
1 | opkg update |
装完在 LuCI 的「服务 → OpenClash」进入配置。
2.3 订阅、分流与 DNS
我的订阅是 Clash 格式,核心配置只有四步:
- 配置订阅:填入订阅链接,更新配置
- 运行模式:选 Fake-IP(增强)模式,兼容性和速度比较均衡
- 规则设置:启用大陆白名单分流,国内直连、国外走代理、局域网不走代理
- 节点选择:在控制面板里测延迟,选一个稳定的节点
DNS 是最容易踩坑的地方。OpenClash 接管 DNS 之后,要注意:
- dnsmasq 的上游要指向 OpenClash 的监听端口,否则会出现「能上 Google 但国内站点变慢」
- 检查 DNS 泄露,避免请求绕过代理直接打到本地运营商
- 局域网设备的 DNS 要么统一走主路由,要么明确指向旁路由,不要一半一半
验证分流是否正常:
1 | # 国内站点应该直连 |
2.4 旁路由模式与回退
旁路由有两种常见玩法:
| 模式 | 做法 | 风险 |
|---|---|---|
| 全局旁路由 | 主路由 DHCP 网关直接指向 .50 | 旁路由一挂,全家断网 |
| 按需旁路由 | 只给需要的客户端手动设网关 .50 | 配置分散,但故障影响小 |
我用的是第二种。Mac 和需要看流媒体的设备走旁路由,手机、电视、智能家居仍然走主路由。
回退也很简单:关掉 OpenClash,把客户端网关改回 192.168.31.1 即可。不要在没想好回退方案之前动主路由的 DHCP。
2.5 安全提醒
iStoreOS 默认的 ttyd 终端(7681 端口)在局域网内是裸奔的。配置完成后建议到「系统 → 管理权」里关掉,或者至少加认证。这个端口一旦被扫到,等于把路由器 root 权限送人。
还有一个反直觉的坑:LuCI 网页密码和 SSH 密码不一定是同一个。iStoreOS 首次安装后,网页可能用默认密码能进,但 SSH 会提示 Authentication failed。正确做法是先在网页「系统 → 管理权 → 路由器密码」里设置密码,SSH 才会生效。
3. 核心主角:fnOS 上的 OpenList
OpenList 是 AList 的社区延续版。我这次装的是 v4.2.9,跑在 fnOS 的 Docker 里,端口 5244。
3.1 为什么选 OpenList
- 多网盘统一挂载:阿里、夸克、百度、蓝奏云在一个文件树里
- WebDAV / API:第三方播放器、下载器、脚本都能接
- 离线下载:磁力、种子、直链可以交给网盘侧执行
- 社区活跃:AList 原项目维护节奏放缓后,OpenList 接过了社区维护
数据流大概是这样:
3.2 Docker 部署
1 | services: |
启动并查看日志:
1 | docker compose up -d |
首次进入需要管理员密码,可以用容器内命令生成:
1 | docker exec -it openlist ./openlist admin random |
3.3 挂载四类网盘
进入后台的「存储 → 添加」,按驱动类型填授权信息。我的挂载表:
| 网盘 | 驱动 | 用途 | 注意事项 |
|---|---|---|---|
| 阿里云盘 | Aliyundrive Open | 主存储、离线下载目录 | token 有有效期,过期单独刷新 |
| 夸克网盘 | Quark | 影视资源、转存 | 高频请求可能触发限流 |
| 百度网盘 | Baidu Netdisk | 老资料、备份 | 大文件下载速度受会员影响 |
| 蓝奏云 | Lanzou | 小文件、工具包 | 适合放安装包和脚本 |
挂载完成后,首页就是一张聚合列表,所有网盘在同一个页面里统一浏览、搜索和转存。
3.4 离线下载是怎么跑的
OpenList 的离线下载不是在本机跑 BT,而是把任务提交给网盘侧执行。流程大致是:
- 在 Web 或 API 提交磁力/种子/直链
- OpenList 创建任务,写入离线下载队列
- 网盘侧开始下载,OpenList 轮询状态
- 下载完成后,文件出现在对应网盘的离线目录
- 你再通过聚合文件树浏览、转存或播放
这样做的好处是:家里的上行带宽和 NAS 性能都不是瓶颈,坏处是依赖网盘侧的可用性和限流策略。
3.5 界面美化
OpenList 后台的「全局 → 自定义头部 / 自定义内容」可以注入 CSS 和 JS。我的方案是:
- 换一张暗色系背景图,正文区域加毛玻璃
- 侧边栏加「媒体库」快捷入口,直链到 Jellyfin
- 顶栏搜索用
Cmd + K唤起,这是 OpenList 前端自带的能力,只要search_index不为none就会出现 - 底部保留「由 OpenList 驱动 | 管理」,低调一点
核心 CSS 大概是这样:
1 | body { |
美化的底线是可读性。背景再好看,正文看不清就是负优化。
4. 两个自制看板
OpenList 自带的离线下载入口藏得比较深,也没有一个统一的地方看各服务健康状态。于是我写了两个单页看板,分别挂在 8788 和 8789。
4.1 一键下载(8788)
原理不复杂:把磁力、种子或直链提交到 OpenList 的离线下载接口,由网盘侧完成下载再转存。
- 前端一个输入框 + 目标云盘下拉框 + 访问令牌
- 令牌存在浏览器本地,不落服务器
- 提交后记录历史任务,画一条「最近提交趋势」折线图
- 失败任务保留错误信息,方便判断是磁力失效还是网盘限流
4.2 状态总览(8789)
这个页面聚合了所有关键服务的健康数据:
- 服务健康数 / 云盘在线数(OpenList 挂载状态探测)
- qBittorrent、MoviePilot、OpenList 各自的可达性
- 用 ECharts 画服务可用性趋势、健康占比环形图、云盘驱动分布柱状图
- 30 秒自动刷新
两个页面都是纯静态 HTML + 原生 JS,部署时丢到一个 nginx 目录,或者直接起个 python -m http.server 容器就行,没有任何后端依赖。数据全部来自 OpenList API 和本地端口探测。
看板里的健康探测一定要带超时,别让一个不在线的服务把整页拖死。看板本身也要加认证,不要因为在内网就裸奔。
5. 下载与媒体流水线
BT/PT 下载交给 qBittorrent,整理和刮削交给 MoviePilot,播放交给 Jellyfin。整条链路是:
5.1 qBittorrent
1 | services: |
几个关键点:
- WebUI 只绑内网,不做任何端口映射或穿透
- 下载目录直接落在 2T 数据盘上
- 内存限制 1G,防止 qB 在做种高峰吃光 NAS 内存
- 首次登录后到「设置 → 下载」里确认默认保存路径是
/downloads
5.2 MoviePilot
MoviePilot v3 在这套流水线里扮演「调度大脑」:
- 下载器接 qBittorrent,自动选择默认下载器
- 媒体服务器接 Jellyfin
- 订阅、整理、硬链接一条龙
- 下载完成后自动刮削、重命名、入库
5.3 Jellyfin
Jellyfin 里建好「电影」和「电视剧」两个媒体库,目录分别指向 /media/Movies 和 /media/TV。
2C5G 的机器不建议开实时转码。能直连播放的客户端尽量直连,电视端优先选支持 HEVC 硬解的设备;实在需要转码,再考虑加显卡或换更强的机器。
5.4 硬链接:省空间的关键
下载目录和媒体库必须在同一个文件系统里,硬链接才有意义。如果两个目录跨了挂载点,硬链接会失败,MoviePilot 只能复制文件,2T 盘很快就会被同一部电影占两份。
检查方法:
1 | df -h /vol00/downloads /media |
两个路径的 %d 设备号一致,才说明在同一个文件系统。
6. 建站与公网入口
最后是 .55 那台 1C3G 的小主机,负责对外建站和图片服务。
6.1 安装 1Panel
1 | curl -sSL https://resource.fit2cloud.com/1panel/package/quick_start.sh -o /tmp/qs.sh |
安装完成后把面板端口固定为 10086,并开启安全入口。面板只监听局域网,不暴露公网。 安全入口忘了可以用 1pctl user-info 查回来。
6.2 建一个测试站点
在 1Panel 里装 OpenResty,创建一个静态站点,比如 test.local,然后用 Host 头验证:
1 | curl -H "Host: test.local" http://192.168.31.55/ |
返回 200 就说明反向代理链路打通了。
6.3 Cloudflare Tunnel
对外出口规划走 Cloudflare Tunnel,路由器不用开任何端口映射:
1 | cloudflared tunnel login |
配置文件大概是这样:
1 | tunnel: <TUNNEL_UUID> |
把 tunnel 配置成 systemd 服务后,只有 Cloudflare 的出站连接能进来,家庭 IP 完全不暴露。
6.4 为什么不用 frp / 端口映射
| 方案 | 优点 | 缺点 |
|---|---|---|
| 端口映射 | 简单直接 | 家庭 IP 暴露,攻击面大 |
| frp | 需要公网 VPS,灵活 | 要维护 VPS,仍有公网入口 |
| Cloudflare Tunnel | 不开端口、自带 TLS/WAF | 域名 NS 必须托管在 Cloudflare |
我选 Tunnel 的核心理由是不需要公网 IP,也不需要开放任何入站端口。对家庭网络来说,少一个入口就少一类风险。
7. 稳定性与备份
服务跑起来只是开始,能不能在出问题时恢复才是关键。
7.1 健康监控
Uptime Kuma 跑在 192.168.31.51:3001,目前监控:
- 博客主页
- 图床域名
- OpenList
- qBittorrent WebUI
- Jellyfin
检测间隔 60 秒,失败重试 2 次。状态总览里目前是 9/9 服务正常、6/6 云盘在线。
7.2 备份策略
| 数据 | 位置 | 频率 | 恢复方式 |
|---|---|---|---|
| 博客源码 | GitHub | 每次提交 | clone + npm ci + hexo generate |
| 博客构建产物 | GitHub / 本地 | 每次部署 | 重新构建 |
| 图片 | GitHub Images + Garage | 每次上传 / 5 分钟同步 | 从仓库或对象存储拉回 |
| 数据库 | 每日备份到 R2 | 每天 03:30 | 还原后重启容器 |
| 配置文件 | 本地 + R2 | 变更时 | 按文档恢复 |
备份不做恢复演练等于没备份。我至少每季度会挑一个服务,从备份里完整重建一次,确认文档和脚本都还能用。
8. 踩坑清单
| # | 坑 | 现象 | 解法 |
|---|---|---|---|
| 1 | ttyd 裸奔 | 7681 端口无需认证就能进终端 | 配置完关掉,或加认证 |
| 2 | OpenClash DNS 泄露 | 国外能上,国内变慢或解析异常 | 检查 dnsmasq 上游,统一 DNS 出口 |
| 3 | LuCI 密码 ≠ SSH 密码 | 网页能进,SSH 提示 Authentication failed | 先在网页设置路由器密码 |
| 4 | OpenList token 过期 | 网盘显示离线,文件打不开 | 后台单独刷新 token,不用重挂 |
| 5 | Docker 目录权限 | 容器启动但无法写入 | 确认 PUID/PGID 与宿主机目录属主一致 |
| 6 | qBittorrent 吃内存 | 做种高峰 NAS 变卡 | mem_limit: 1g,限制连接数 |
| 7 | 2T 盘没挂上 | 下载跑到系统盘,空间瞬间告急 | 启动前 df -h 确认挂载点 |
| 8 | 硬链接失败 | 媒体库和下载目录各占一份 | 确认在同一文件系统,检查 stat -c %d |
| 9 | Jellyfin 转码卡顿 | 2C5G 实时转码直接满载 | 优先直连,关闭不必要的转码 |
| 10 | Tunnel 配了不生效 | 域名打不开 | 确认域名 NS 已托管在 Cloudflare |
| 11 | 1Panel 安全入口丢失 | 面板地址进不去 | 1pctl user-info 查回 |
| 12 | 看板无认证 | 内网任何人可提交下载任务 | 加 Basic Auth 或只走 Tailscale |
9. 成本、功耗与取舍
这套系统用的都是现有硬件,主要成本是硬盘、电费和域名:
- 2T 数据盘:一次性投入
- 三台机器常年开机:功耗比一台台式机低,但也不是零
- Cloudflare R2 / Tunnel:个人用量基本在免费额度内
- 域名:每年固定支出
如果重新来一次,我会做几件事:
- 给 NAS 配一个 UPS,避免断电把文件系统搞坏
- 用 VLAN 把 IoT 设备和 NAS 管理面隔开
- 把配置文件和 compose 全部纳入 Git,换机器时直接拉起来
- 备份加一份离线冷备,不要只依赖云
但有一件事不会变:不会为了折腾而折腾。如果只是想在手机上看 NAS 里的文件,一个 SMB 共享就够了,没必要上这么一套。
10. 总结
现在这套系统的日常是这样的:
- 想存资源 → 丢磁力到一键下载看板,网盘离线完成后自动转存
- 想看电影 → MoviePilot 订阅自动下载、整理、刮削,Jellyfin 直接播
- 想建站 → 1Panel + Cloudflare Tunnel,公网出口不暴露家庭 IP
- 想维护 → Tailscale 进内网,Uptime Kuma 看健康状态
折腾的意义大概就在这里:把散落的硬件和服务,拼成一个真正为自己工作的系统。
后续计划把 Cloudflare Tunnel 正式接入、图片 CDN 优化、Uptime Kuma 告警也补全,到时候再写一篇续集。
本文所有命令都在自己的环境里实际跑过,IP 和端口按家里网段记录。折腾快乐,数据无价——每次改配置之前,先想一遍:重启之后,它还能回来吗?








