Blog

  • 谷歌云GCP设置默认SSH开启ROOT权限 一键脚本

    在 GCP 的 Debian 服务器里,打开浏览器 SSH 后粘贴执行:

    sudo bash -c 'set -e; f=/etc/ssh/sshd_config; cp -a "$f" "$f.bak.$(date +%Y%m%d-%H%M%S)"; mkdir -p /etc/ssh/sshd_config.d; printf "%s\n" "PermitRootLogin yes" "PasswordAuthentication yes" "KbdInteractiveAuthentication yes" "UsePAM yes" > /etc/ssh/sshd_config.d/99-enable-root-password-login.conf; for k in PermitRootLogin PasswordAuthentication KbdInteractiveAuthentication UsePAM; do grep -qiE "^[#[:space:]]*$k[[:space:]]+" "$f" && sed -i -E "s|^[#[:space:]]*$k[[:space:]].*|$k yes|I" "$f" || printf "\n%s yes\n" "$k" >> "$f"; done; passwd root; /usr/sbin/sshd -t; systemctl restart ssh || systemctl restart sshd || service ssh restart; echo "Done. Login with root, port 22."'

    执行过程中会让你输入两次新的 root 密码,输入时不显示字符是正常的。

    以后换电脑也没关系,只要能进 GCP 浏览器 SSH,把这行重新粘贴执行就行,不依赖本地 .sh 文件。

  • 极限榨干 1GB 内存:GCP 免费云主机 + HestiaCP 搭建高性能 WordPress 终极指南

    极限榨干 1GB 内存:GCP 免费云主机 + HestiaCP 搭建高性能 WordPress 终极指南

    对于很多独立站站长和极客来说,Google Cloud Platform (GCP) 提供的 e2-micro 免费实例(1GB 内存 + 30GB 标准硬盘)是一项不可多得的福利。然而,1GB 内存加上速度较慢的标准机械硬盘,如果直接套用传统的宝塔面板或 1Panel,往往会在安装数据库时因为内存耗尽(OOM)而直接死机。

    今天,我们将另辟蹊径,抛弃臃肿的容器化方案,采用轻量级原生面板 HestiaCP,配合 Cloudflare CDN底层 Linux 内核深度优化,把这台 1GB 内存的“小霸王”调校成能秒开 B2B 外贸网站的高性能服务器!

    核心架构思路

    • 弃用 Docker: 采用原生安装的 HestiaCP,省去容器层的内存损耗。
    • 极致做减法: 剔除杀毒软件(ClamAV)和邮件服务器,只保留纯粹的 Nginx + PHP + MariaDB。
    • 物理外援: 强开 2GB Swap 虚拟内存防止死机。
    • 流量剥离: 利用 Cloudflare 承担几乎所有的静态资源分发。

    步骤一:云端前置准备(防火墙与解析)

    在动服务器之前,我们需要先铺好路:

    1. 开放端口: 登录 GCP 控制台,进入 VPC 网络 -> 防火墙。创建一条新规则(入站、允许所有 IP 0.0.0.0/0),放行 TCP 端口:80, 443, 8083(如果你后续想改面板端口,比如改为 8888,请一并在这里放行)。
    2. 域名解析: 前往 Cloudflare,将你的主域名(如 [www.yourdomain.com](https://www.yourdomain.com))和面板专属管理域名(如 hcp.yourdomain.com)的 A 记录都指向 GCP 服务器的外部公网 IP。注意:此时先保持“小灰云”状态(仅 DNS),不要开启代理。

    步骤二:服务器底层“保命”设置 (SSH)

    通过 GCP 控制台的 SSH 连入服务器,获取最高权限并设置规范的主机名(必须设置规范的 FQDN 主机名,否则后续 Let’s Encrypt SSL 证书大概率申请失败):

    Bash

    sudo su
    hostnamectl set-hostname hcp.yourdomain.com
    

    步骤三:借助 AI (Codex) 完成极简自动化部署

    在这一步,我没有选择手动逐行敲击代码,而是使用 Codex 连接 VPS,进行全自动化部署。在让 AI 开始执行之前,我先给它下达了明确的安装要求

    “这台 VPS 仅用于部署 2-3 个轻量级的 WordPress 小站点。由于系统资源极度有限(1GB 内存),请务必采用最精简、最轻量的方案进行安装,彻底剔除所有非必要的吃内存组件,然后再执行安装操作。”

    接收到指令后,AI 便自动接管了面板的搭建。以下是 AI 执行部署时的核心优化思路(供参考):

    1. 环境预检与 Swap 兜底: AI 首先自动排查了服务器的 80、443、8083 端口是否被占用,并紧接着为这台 1GB 内存的机器强制分配了 2GB 的 Swap 虚拟内存。这是极其关键的一步,从物理层面防止了后续数据库安装时可能发生的 OOM(内存耗尽)死机。
    2. 定制极简安装策略(做减法): 在调用 HestiaCP 官方安装脚本时,AI 采用了非常严苛的“断舍离”参数配置:
      • 保留核心: 仅安装维持网站运行必备的 Nginx、PHP-FPM、MariaDB,以及基础安全套件(iptables + Fail2Ban)。
      • 剔除累赘: 坚决砍掉了邮件服务(Exim/Dovecot)、DNS 服务(BIND)、FTP,以及最吃内存的杀毒与反垃圾邮件组件(ClamAV/SpamAssassin)。
    3. 自动化环境收尾: 安装完成后,AI 顺手解决了 Debian 系统下常见的中文语言包缺失问题(自动配置 zh_CN.UTF-8 locale),避免了面板出现乱码,并执行了服务器重启。

    通过 AI 代理执行,不仅避开了容易出错的长串命令,更精准地将服务器资源全部留给了建站本身。重启后,我们即可通过 https://面板域名:8083 顺利登录后台。

    步骤四:面板收尾与建站配置

    配置 PHP 与部署网站:

    1. 浏览器输入你配置好的独立域名(如 [https://hcp.example.com:8083](https://hcp.example.com:8083))登录面板。
    2. 点击右上角齿轮 (Server) -> Web Server 下的 php-fpm -> Edit -> Configure -> Advanced Options。将 upload_max_filesizepost_max_size 修改为 128M(否则 WordPress 无法上传大插件)。
    3. 点击顶部菜单 WEB -> Add Web Domain,填入你的主域名,勾选启用 SSL 和 Let’s Encrypt。
    4. 在 WEB 列表点击该域名的编辑,右上角选择 Quick Install App,一键安装 WordPress。

    步骤五:Cloudflare 完美协同(避坑指南)

    现在去 Cloudflare 把 DNS 记录的“小灰云”点亮为“小黄云”(开启代理),但必须注意一个致命死循环!

    • 避坑法则: 既然源站(HestiaCP)已经有了 SSL 证书并开启了强制 HTTPS 重定向,在 Cloudflare 的 SSL/TLS 加密模式中,必须选择“完全(严格)” (Full – Strict)
    • 如果你选了“灵活(Flexible)”,会导致无限的 ERR_TOO_MANY_REDIRECTS 重定向死循环!

    步骤六:Linux 内核终极“超频”优化

    HestiaCP 优化了 Web 层,我们要亲自优化 Linux 内核,弥补 1GB 内存和慢速硬盘的物理缺陷。在 SSH 中一次性执行以下代码:

    Bash

    cat >> /etc/sysctl.conf << EOF
    
    # 1. 开启 BBR 算法,榨干网络带宽,大幅提升跨国访问速度
    net.core.default_qdisc = fq
    net.ipv4.tcp_congestion_control = bbr
    
    # 2. 压制 Swap 倾向 (默认60,改设10)。保护 GCP 极慢的标准硬盘不被频繁读写拖死
    vm.swappiness = 10
    
    # 3. 激进回收 TCP 连接。防止僵尸访客占用宝贵的内存资源
    net.ipv4.tcp_fin_timeout = 15
    net.ipv4.tcp_keepalive_time = 300
    net.ipv4.tcp_max_tw_buckets = 5000
    net.ipv4.tcp_tw_reuse = 1
    EOF
    
    # 使配置立即生效
    sysctl -p
    

    ✅ 验证优化是否成功:

    执行完上述命令后,单独运行下面这条命令来检查 BBR 算法是否已被成功激活:

    Bash

    lsmod | grep bbr
    

    如果屏幕输出结果中包含了类似 tcp_bbr 20480 1 的字样,恭喜你,这说明 BBR 已经成功在内核中全速运行接管网络流量了!

    结语

    经过上述六个步骤的手术级改造,你的 GCP 1GB 免费实例已经脱胎换骨。双层缓存体系(Cloudflare 静态拦截 + Nginx FastCGI 动态缓存)加上坚实的内核底层(BBR + 内存防崩策略),足以支撑起一个访问速度极快、极具专业感的 B2B 独立站。建站,有时候比拼的不是财力,而是将资源运用到极致的极客精神!

  • 软路由极致折腾手册:从底层存储到全能网关

    软路由极致折腾手册:从底层存储到全能网关

    第一阶段:网络环境初始化

    刷机后的 R2S 是“白纸”一张,无法下载插件。我们需要利用电脑作为“奶妈”提供初始流量。

    1. 利用 Clash Verge 局域网共享(详细步骤)

    如果你电脑上有 Clash Verge 且有节点,可以让 R2S “借道”翻墙。

    • 电脑端设置
      1. 打开 Clash Verge,进入 设置 (Settings) -> 系统设置
      2. 找到 允许局域网 (Allow LAN) 开关,将其打开。
      3. 记录下电脑的 局域网 IP 地址(例如 192.168.10.10)和 混合端口 (Mixed Port)(通常是 78907897)。
      4. 注意:如果连接失败,请暂时关闭 Windows 防火墙或允许 Clash 通过防火墙。
    • R2S 端设置 (HomeProxy)
      1. 安装并进入 HomeProxy
      2. 添加一个节点,类型选 手动 (Manual)
      3. 地址 (Address):填写你电脑的 IP(如 192.168.10.10)。
      4. 端口 (Port):填写 Clash 的端口(如 7897)。
      5. 保存并启用,此时 R2S 即可正常下载后续插件。

    2. Nikki安装与配置

    • 核心步骤:HomeProxy 稳定后安装 Nikki 并导入配置文件。
    • 【避坑重点】:配置文件中 UI 控制面板相关的几行代码严禁注释,否则初次使用无法打开UI面板!
    • 配置文件 删除QUIC模块: ports: [443, 8443],原因,保留这个模块后,国内淘宝APP卡顿。
    • 保持状态:全程保持翻墙状态,否则 UI 面板数据无法下载,会导致插件空壳运行。

    第二阶段:安装Docker 防坑与硬盘锁

    R2S 系统闪存极其有限,必须通过“物理手段”防止系统盘爆满。

    1. 磁盘分区与逻辑

    • 软件包常规安装 DiskMan
    • 使用 DiskMan 进行分区:
      • Docker 分区:划分 10GB 空间。
      • 剩余存储区:剩余空间格式化为 ext4,并挂载为 /mnt/tf-disk

    2. 【核心】chattr +i 系统盘防爆锁

    必须在挂载硬盘前,于 SSH 执行:

    Bash

    # 1. 创建入口文件夹
    mkdir -p /opt/docker
    
    # 2. 安装锁定工具
    opkg update && opkg install chattr
    
    # 3. 锁定系统盘坑位(防止数据“掉入”系统闪存)
    chattr +i /opt/docker
    

    3. 精准挂载与 Docker 安装

    • 路径:系统 -> 挂载点 -> 添加。
    • 设置:将 10GB 分区 挂载到 /opt/docker
    • 自动挂载策略
      • 自动挂载未配置分区取消勾选 (OFF)(防止路径偏移)。
      • 自动挂载已配置分区保持勾选 (ON)(确保重启后硬盘自动就位)。

    4.在 SSH 终端中重启路由器:

    Bash

    reboot

    验证锁定与挂载: 重启回来后,请务必执行以下命令验证你的 10G 硬盘 是否已经成功“盖住”了那个锁死的坑位:

    Bash

    df -h | grep /opt/docker
    
    • 预期结果:你应该能看到类似 /dev/sda1(你的分区名)挂载在 /opt/docker 下,且容量显示为 10G
    • 如果看到了 10G:恭喜,你可以立即执行 opkg install luci-app-dockerman 开始安装 Docker 了!

    5.安装 Docker

    重启路由器后,在 SSH 执行:

    # 更新并安装 Docker 管理插件及中文语言包
    opkg update
    opkg install luci-app-dockerman
    opkg install luci-i18n-dockerman-zh-cn
    • 由于 /opt/docker 被锁且已被 10G 硬盘覆盖,镜像将直接进入硬盘。

    6.核心避坑:解决 Docker 端口打不开的问题

    问题描述:

    你安装了 Docker 插件(如 Jellyfin 8096 或 Navidrome 4533),且在 Docker 管理界面看到端口映射 0.0.0.0:xxxx 已经生效,但使用浏览器访问 路由器IP:端口 却提示“连接超时”或“无法访问”。

    原因分析:

    ImmortalWrt 默认的防火墙规则出于安全考虑,将**“默认转发(Forward)”**设置为了“拒绝(Reject)”。由于 Docker 容器运行在虚拟网桥(docker0)上,访问容器属于跨区域流量,会被防火墙直接拦截。

    解决方案:

    1. 登录 Web 管理后台。
    2. 进入 网络 -> 防火墙 -> 常规设置
    3. 找到 “默认转发” 选项,将其从 “拒绝” 修改为 “接受 (Accept)”
    4. 点击底部的 “保存并应用”

    第三阶段:安装文件分享Samba

    针对 Win11 访问需要用户名密码的情况,手动创建 xxx 用户。

    1.软件包常规安装Samba

    2. SSH 创建用户

    Bash

    # 1. 安装工具
    opkg update && opkg install shadow-useradd
    # 2. 创建用户(不创建家目录,禁止 shell 登录)
    useradd -M -s /bin/false sirenyan
    # 3. 设置 Samba 密码(输入 sirenyan)
    smbpasswd -a sirenyan

    3.创建剩余磁盘空间

    在磁盘管理中,把当前系统存储卡的剩余空间创建并格式化为ext4

    并在挂载点中创建一个挂载点:/mnt/tf-disk

    4. 网页端配置 (Samba)

    进入:服务 -> 网络共享 (Samba) -> 共享目录 (针对 tf-disk)。

    • 允许用户 (Allowed users):填入 sirenyan
    • 允许访客:可以取消勾选或保留。
    • 强制 Root:取消勾选(使用 sirenyan权限)。

    4. 权限修正

    若无权限读写,勾选强制 Root即可,但不推荐,推荐以下方案,执行:

    Bash

    # 将文件夹及其内部所有文件的“所有者”改为 sirenyan
    chown -R sirenyan:sirenyan /mnt/tf-disk
    chmod -R 755 /mnt/tf-disk

    第四阶段:安装iStore 和首页

    1. iStoreOS 商店核心安装方案

    在原生 ImmortalWrt 终端中执行以下脚本。该方案利用 /tmp 内存目录作为中转,安全且高效。

    Bash

    opkg update || exit 1
    cd /tmp
    wget https://github.com/linkease/openwrt-app-actions/raw/main/applications/luci-app-systools/root/usr/share/systools/istore-reinstall.run
    chmod 755 istore-reinstall.run && ./istore-reinstall.run

    关键点解析:

    • opkg update || exit 1:这是脚本的“保险开关”。opkg update 负责更新软件列表,如果更新失败(例如网络不通),exit 1 会立即停止后续操作,防止在错误的环境下继续安装。
    • /tmp 目录:在内存中运行安装包,保护路由器的闪存(Flash)寿命。

    2.安装网络向导与首页 (ARM64 & x86-64 通用)

    安装完商店核心后,为了获得更好的交互体验和类似 iStoreOS 的首页外观,需要手动安装中文语言包和快速启动插件:

    执行指令:

    is-opkg install luci-i18n-quickstart-zh-cn

    作用说明:

    • is-opkg:这是 iStore 专用的包管理命令。
    • 首页功能:安装后,你的路由器后台会多出一个“首页”菜单,提供直观的设备状态监控、网络状态展示以及应用快捷入口。

    第五部分:安装Tailscale

    1. 准备工作

    访问 asvow/luci-app-tailscale 下载以下适用于 R2S 的特定版本文件:

    • 主程序:luci-app-tailscale_1.2.6_all.ipk
    • 简体中文包:luci-i18n-tailscale-zh-cn_250509.33792_all.ipk

    2. 安装核心依赖

    首先,我们需要安装 Tailscale 程序本身和 SSL 证书支持。

    opkg update
    opkg install tailscale ca-bundle

    3. 上传并覆盖安装插件

    将下载好的两个 .ipk 文件通过 WinSCP 上传到路由器的 /tmp 目录。

    注意:由于该插件会替换系统原有的启动脚本,必须使用 --force-overwrite 参数,否则会提示文件冲突。

    cd /tmp
    opkg install --force-overwrite luci-app-tailscale_1.2.6_all.ipk luci-i18n-tailscale-zh-cn_250509.33792_all.ipk

    4. 清理缓存与启动

    执行以下命令清理界面缓存并启动服务:

    rm -rf /tmp/luci-indexcache
    /etc/init.d/tailscale enable
    /etc/init.d/tailscale start

    5. 账号绑定与初始化

    • 进入后台:刷新路由器网页,在 “服务” -> “Tailscale” 即可看到控制界面。

    第六部分:Tailscale直连优化与避坑

    如果你希望手机在外面能通过 Tailscale 使用家里的 R2S 旁路由代理上网,并能像在家里一样管理主路由和 Docker 服务,以下设置是成功的关键。

    1. 联动 Nikki/Clash 翻墙与 MTU 优化

    在旁路由环境下,让代理插件感知并处理来自 Tailscale 的流量是第一步。由于 Tailscale 的流量经过加密封装,如果不将其接口告知代理插件,流量会绕过代理直接流出。

    在 Nikki 插件中进行如下设置:

    • Nikki 设置:进入“代理配置” -> “局域网代理”中,将 tailscale0 添加到入站接口(Inbound Interfaces)。这确保了手机传回 R2S 的流量在解密后能立即进入代理分流逻辑。

    为了防止因 MTU 大小不匹配导致的数据包分片丢失,建议在防火墙规则中添加以下 MSS 钳制命令。这能显著提升网页加载的顺滑度,防止因 5G 或公共 WiFi 环境导致的卡顿(可选):

    nft add rule inet fw4 forward oifname "eth0" tcp flags syn tcp option maxseg size set rt mtu
    

    2. 禁止Tailscale接管系统DNS(必做)

    Tailscale 默认接管了系统的 DNS 设置。 当它启动时,会尝试将系统的 DNS 修改为它自己的服务器(通常是 100.100.100.100),或者强制推送到 /etc/resolv.conf。在旁路由模式下,这往往会破坏原本指向主路由或 SmartDNS 的解析路径,导致系统无法解析外部域名,因此必须执行禁用。

    请在 SSH 终端执行以下命令:

    tailscale up --accept-dns=false --reset 

    --accept-dns=false:拒绝接受官方 DNS 设置。这是旁路由环境的“救命参数”,防止 Tailscale 修改系统 DNS 导致与 Nikki/Clash 产生死锁,确保 DNS 解析权掌握在 R2S 代理手上。

    下面的完整命令,包括:DNS 处理方式、路由宣告、出口节点能力,可在插件界面设置中设置路由宣告、出口节点(下面第3步在插件界面的操作等同于这一步的命令):

    tailscale up --reset --advertise-exit-node --advertise-routes=192.168.10.0/24 --accept-dns=false

    上述命令中参数的详细设置要点如下:

    • --advertise-exit-node:宣称自己为“出口节点”。它是实现“异地借线翻墙”的核心,允许其他设备将全局流量发给 R2S 转发。
    • --advertise-routes=192.168.10.0/24:宣称内网网段路由。让手机在外网也能像在家里一样,通过 192.168.10.x 访问 NAS 或管理主路由。

    3. 插件界面设置与官网后台“放行”

    在完成 SSH 命令后,还需要通过图形界面确认状态,并去 Tailscale 云端控制台手动授予转发权限。

    在 R2S 的 Tailscale 插件高级设置中确认以下项:

    • 启用路由:勾选(允许接受其他节点广播的子网)。
    • 允许 DNS取消勾选(如果允许DNS,会造成软路由系统联网错误,不能下载istore应用等)。
    • 出口节点:勾选(确认为 Tailscale 广域网出口)。
    • 公开网段:确保列表中已添加 192.168.10.0/24

    随后登录 Tailscale 官网后台进行 Edit route settings 操作:

    • 登录 Tailscale Admin Console
    • 找到 R2S 设备,点击右侧三个点,选择 Edit route settings
    • 必须勾选 Use as exit node:确认该设备可以作为全网出口。
    • 必须勾选 192.168.10.0/24:确认允许该设备转发此内网网段的流量。

    4. 解决“无法管理主路由 (10.1)”:NAT 规则配置

    即便开启了子网路由,由于主路由(如高恪)默认不认识 Tailscale 的 100.x 网段,回程包会发往 WAN 口导致丢失。我们需要在 R2S 的防火墙中配置 MASQUERADE(IP 伪装),让主路由以为是 R2S 本身在访问它,才可以在外网打开192.168.10.1主路由地址(最新测试,可选,没做也可以访问)。

    在“网络” -> “防火墙” -> “NAT 规则”中新建如下参数:

    • 名称Tailscale-MASQ
    • 地址族限制:选择 仅 IPv4
    • 协议:选择 任意
    • 出站区域:选择 lan (对应 R2S 连接主路由的物理接口 br-lan)。
    • 源地址:选择 任意
    • 目标地址:选择 任意
    • 操作 (Action):选择 MASQUERADE - 自动重写源地址为出站接口 IP

    5. 解决“打不开 Google.com”:DNS 覆盖(必做)

    这是最容易被忽视的坑:手机开启出口节点后,如果解析不到真实国外 IP,翻墙就会失败。

    操作路径:Tailscale 官网后台 -> DNS -> Nameservers -> Add nameserver。

    添加 Nameservers

    • 添加 1.1.1.1 (Cloudflare):点击设置,开启 Use with exit node。确保手机拿到真实国际 IP 以触发代理。
    • 添加 223.5.5.5 (阿里):点击设置,开启 Use with exit node。保证国内 App 访问速度。
    • 开启覆盖:确保 Override local DNS 开关为 开启 (蓝色)

    6. Docker 访问配置:打通虚拟网卡权限(必做)

    如果你在 Docker 中运行了服务(如 Navidrome 音乐服务器、Jellyfin 等),默认情况下 Tailscale 流量无法进入 Docker 虚拟网络。

    请在 R2S 后台的“Docker” -> “配置”中执行以下操作:

    • 找到 “允许的访问接口” 选项。
    • 在列表中手动勾选或填入 tailscale0
    • 点击“保存并应用”。这一步能确保来自 Tailscale 隧道的流量可以穿透 Docker 的虚拟防火墙。

    7. 解决 Tailscale 节点显示 relay,无法直连问题

    有时候 Tailscale 节点虽然网络正常,但状态会显示:

    active; relay "sfo"

    表示当前通过 DERP 中继服务器通信,没有建立设备之间的 P2P 直连。

    例如:

    R2S → 手机:direct
    R2S → Windows:relay "sfo"

    这种情况不一定是网络问题,可能只是 Tailscale 节点连接状态没有及时刷新。

    排查网络

    分别执行:

    tailscale netcheck

    确认:

    UDP: true
    MappingVariesByDestIP: false

    说明 UDP 正常,NAT 类型正常,具备直连条件。

    解决方法

    在 Windows 端管理员 PowerShell 执行:

    Restart-Service Tailscale

    等待几十秒后重新查看:

    tailscale status

    如果显示:

    direct xxx.xxx.xxx.xxx:41641

    说明已经恢复 P2P 直连。

    常用检查命令

    查看节点状态:

    tailscale status

    检测网络:

    tailscale netcheck

    测试连接:

    tailscale ping 节点名称

    如果网络条件正常,但仍显示 relay,可以优先尝试重启 Tailscale 服务,让节点重新进行 NAT 穿透协商。

    8. 高恪 (GoCloud) 主路由映射与状态验证

    最后,需要在高恪主路由上为 Tailscale 开启“直连快车道”,以确保异地组网的低延迟体验。

    在高恪主路由中按以下路径和参数进行配置:

    • 路径:网络设置 -> 端口映射 -> 端口映射。点击“新建”:
    • 名称Tailscale-Direct
    • 协议UDP
    • 外部端口41641
    • 内部 IP 地址:填写 R2S 的内网 IP(如 192.168.10.3
    • 内部端口41641
    • 端口回流:禁用(保持默认即可)。
    • 关闭 UPnP:建议在高恪中关闭 UPnP 功能,避免随机端口抢占导致手动映射失效。

    为了保证打洞成功率,请在 R2S 的防火墙常规设置中,将 入站数据、出站数据、转发 全部改为 “接受 (Accept)”。最后在 SSH 中输入以下命令验证是否成功直连:

    tailscale status --active
    

    判定标准:若显示 active; direct,说明 UDP 打洞成功,延迟最低。若显示 relay,则说明正在走服务器中转,请检查高恪端口映射是否生效。

    第六阶段:安装Cloudflare Tunnel

    • 软件安装:iStore 中常规安装 Cloudflare。
    • 令牌 (Token):直接粘贴以 ey... 开头的超长令牌。
    • 证书上传:在 Cloudflare 官网选择域名后,系统会自动下载 cert.pem,需在路由器插件界面对应的“源站证书”位置上传。

    第七阶段:媒体中心——Navidrome 防火墙神坑

    • 安装:Docker 部署 Navidrome 镜像。
    • 故障现象:服务正常但 http://192.168.10.3:4533 无法打开。
    • 解决方案:进入 网络 -> 防火墙 -> 常规设置,将 转发 (Forward) 设为 接受 (ACCEPT)
    • 原理:这是为了打通 LAN 区域到 Docker 区域(172.17.x.x)的“跨区”传送门。

    其它操作

    GoWebDav:将剩余空间映射到 /mnt/tf-disk 后,在此插件中开启共享,方便网页端文件存取。

  • 利用 Nikki 节点为 Cloudflare Tunnel 与 FRP 开启“降维打击”级加速

    利用 Nikki 节点为 Cloudflare Tunnel 与 FRP 开启“降维打击”级加速

    对于很多玩 R2S(NanoPi R2S)的小伙伴来说,搭建好 Emby 或音乐服务器后的“最后 1 公里”往往最让人头疼:明明家里有百兆上行,但在外面用手机流量访问时,无论是 Cloudflare Tunnel 还是直连 VPS 的 FRP,速度经常只有几百 KB/s。

    今天我们要分享的是一套“降维打击”级的方案:利用 R2S 本地的 Nikki 插件,配合高速代理节点(如 IEPL 专线),为这些穿透隧道进行二次加速。

    一、 为什么你的隧道需要“二次加速”?

    无论是 Cloudflare Tunnel 还是 FRP,它们本质上都是在你的 R2S 和远程服务器之间建立了一条“加密管道”。

    • Cloudflare Tunnel:数据要绕道 Cloudflare 的全球边缘节点,而在国内直连这些节点的路由通常非常糟糕,且容易受到运营商的 QOS 限制。
    • FRP:虽然是直连你的 VPS,但如果 VPS 线路不是 CN2 GIA 等高端线路,国际出口的丢包率足以让你的视频流频繁缓冲。

    Nikki 的作用:它像是一个聪明的“交通警察”。通过配置规则,它能识别出这些隧道进程,并将原本要走公网“堵车路段”的数据包,强行塞进你购买的高速代理专线中。

    二、 实战篇:Cloudflare Tunnel 的调优艺术

    Cloudflare Tunnel 默认使用 QUIC (UDP) 协议,这在经过代理节点转发时效率极低。

    1. 修改启动协议

    首先,必须将 cloudflared 的传输协议改为 HTTP2TCP。在 R2S 的 /etc/init.d/cloudflared 启动脚本中,加入以下参数:

    Bash

    procd_append_param command "--protocol" "http2" 
    

    改用 HTTP2 后,数据会封装在稳定的 TCP 流中,极大提升了在代理环境下的稳定性。

    2. Nikki 规则配置

    在 Nikki 的 YAML 配置文件中,我们需要开启“双重保险”规则:

    • 进程匹配:强制拦截 cloudflared 进程的所有流量。
    • 域名匹配:拦截所有指向 argotunnel.com 的请求(这是隧道的握手域名)。

    配置示例

    YAML

    find-process-mode: always # 必须开启进程识别
    rules:
      - PROCESS-NAME,cloudflared,☁️ Cloudflare # 进程规则
      - DOMAIN-SUFFIX,argotunnel.com,☁️ Cloudflare # 域名补漏
    

    通过这种方式,你的 Cloudflare 隧道将不再直连,而是通过你的高速节点中转,实测下载速度能从几百 KB 稳定提升至 2MB/s 以上。

    三、 实战篇:FRP 配合 Nikki 的暴力提速

    相比 Cloudflare Tunnel,FRP 的协议更精简,配合 Nikki 加速后的效果往往更加惊人。

    1. 加速逻辑:处理“出站上传”

    很多用户误以为 Nikki 只能加速“下载”,其实它处理的是双向流量。当你通过 FRP 远程看片时,R2S 的 frpc 进程正在向 VPS “上传”数据。Nikki 会拦截这个出站连接,并通过全双工的高速节点进行推送。

    2. 配置技巧

    针对 FRP,由于其 IP 通常是固定的,建议直接使用 IP-CIDR 规则或 进程规则

    YAML

    rules:
      - PROCESS-NAME,frpc,🚀 高速节点
      - IP-CIDR,你的VPS_IP/32,🚀 高速节点
    

    3. 性能榨取

    为了降低 R2S 那颗弱小 CPU 的负担,建议在 frpc.toml 中关闭 FRP 自身的加密(因为代理节点已经带了加密),并开启 tcpMux(多路复用),这样能显著降低视频拖动时的延迟。

    四、 深度对比:谁才是外网影音的最强方案?

    特性Cloudflare Tunnel + NikkiFRP + Nikki 加速
    配置难度较高(需修改协议脚本)简单(直接针对 IP 设规则)
    协议效率一般(HTTP2 有额外开销)极高(原生 TCP 转发)
    稳定性容易出现 stream closed 报错非常稳定
    安全性极高(隐藏真实 IP)一般(暴露 VPS IP)

    实测结论:如果你追求极致的视频播放体验,FRP + Nikki 加速 是目前 R2S 环境下的最优解。它不仅能提供更稳定的 2MB/s 以上上传带宽,还能有效避免 Cloudflare 常见的握手超时问题。

    五、 避坑指南:为什么你的加速没效果?

    1. 硬盘是基础:无论网络多快,如果你的 R2S 硬盘处于“只读 (Read-Only)”或文件系统损坏状态,I/O 阻塞会直接导致播放器缓冲。务必确保磁盘挂载状态为 rw
    2. 转码是杀手:R2S 硬件性能有限,播放时请确保 Emby 显示为“直接播放”。如果触发转码,CPU 满载会导致网络协议栈处理变慢,产生 http2: stream closed 报错。
    3. 节点质量:加速的效果上限取决于你的代理节点。建议选择支持 HTTP2/gRPC 且带有中转专线的节点,以获得最低的丢包率。

    结语

    通过 Nikki 为内网穿透隧道“修路”,本质上是利用了现代代理工具强大的分流能力。对于 R2S 这种内存敏感型设备,这种“以空间换时间”的方案能让你在世界的任何角落,都能丝滑地享受家里的海量影音库。

  • Protected: 构建基于 Hysteria 2 隧道加速的 FRP 内网穿透全攻略

    Protected: 构建基于 Hysteria 2 隧道加速的 FRP 内网穿透全攻略

    This content is password-protected. To view it, please enter the password below.

  • 玩转 R2S 家庭服务器:Cloudflare Tunnel + 优选 IP 全家桶提速终极实操指南(自动化进阶版)

    玩转 R2S 家庭服务器:Cloudflare Tunnel + 优选 IP 全家桶提速终极实操指南(自动化进阶版)

    前言:为什么你的内网穿透那么慢?

    对于很多像我一样使用 NanoPi R2S 这种轻量级网关,且身处**移动宽带(无公网 IP)**环境的用户来说,Cloudflare Tunnel(Argo Tunnel)几乎是低成本实现内网穿透的唯一真神。它不需要公网 IP,也不需要去路由器做复杂的端口转发,就能通过安全隧道把内网服务发布到公网。

    但理想很丰满,现实很骨感。默认模式下,Cloudflare 的 Anycast(任播)网络会将你的流量随机分配到全球边缘节点。对于国内移动线路,流量经常绕道美国、欧洲或新加坡,导致延迟高达 300ms 以上,Jellyfin 看个海报墙都要转半天圈。

    本博文将记录如何通过“优选 IP”技术,将平均延迟降低至 60ms 以内,并实现“一次配置,终身受益”的子域名全自动化加速方案。


    一、 核心武器:CloudflareSpeedTest 与提速原理

    1. 什么是 CloudflareSpeedTest (CFST)?

    CloudflareSpeedTest 是一款开源的、专为寻找 Cloudflare 优质节点而设计的测速工具。它不仅测试 Ping 延迟(ICMP),更支持 TCPing(端口延迟)和 HTTPing(下载测速),能真实反映出节点对网页访问和流媒体传输的实际贡献。

    2. 加速原理:绕过“糟糕”的路由

    Cloudflare 全球有成千上万个节点,但并非所有节点都对中国移动宽带友好。

    • Anycast 的局限:运营商默认的 DNS 解析往往会将你带向拥堵的骨干网出口。
    • Hosts 劫持与 Dnsmasq 泛解析:通过优选工具筛选出物理距离最近、带宽最充裕的直连 IP(如移动专线的香港/新加坡节点),并强行在 R2S 本地将你的域名指向该 IP。
    • 原理:流量不再走“公海路由”,而是直接由 R2S 的 DNS 引擎导向最快节点,实现“直线超车”。

    二、 进阶策略:从手动硬编码到“泛域名自动化”

    在之前的版本中,我们通过脚本往 /etc/hosts 里写死域名。但这有一个巨大的短板:不支持通配符。每当你新增一个服务,就要改一次脚本。

    终极方案:我们利用 OpenWrt 自带的 Dnsmasq 功能。在 Dnsmasq 配置文件中,一行 address=/.sirenyan.cn/IP 即可实现泛域名劫持。这样,除了根域名 sirenyan.cn 外,所有现有的和未来新增的子域名(如 *.sirenyan.cn)都会自动享受加速。


    三、 第一阶段:环境准备与工具安装

    1. 硬件与系统

    • 硬件:NanoPi R2S。
    • 系统:ImmortalWrt 24.10.4。
    • 分区:Docker 分区已扩充至 20GB,足以应对后续各服务的缓存需求。

    2. 工具安装

    通过 SSH 连接到 R2S,创建目录并下载最新版 CloudflareST

    Bash

    mkdir -p /opt/cf_speedtest && cd /opt/cf_speedtest
    # 下载 arm64 架构版
    wget -O CloudflareST_linux_arm64.tar.gz https://github.com/XIU2/CloudflareSpeedTest/releases/download/v2.2.5/CloudflareST_linux_arm64.tar.gz
    tar -zxf CloudflareST_linux_arm64.tar.gz
    chmod +x CloudflareST
    

    四、 第二阶段:编写“未来就绪”自动化脚本 (cfst_hosts.sh)

    请全选并替换你的脚本内容。此版本使用了 Dnsmasq 配置文件路径,确保全自动泛解析。

    Bash

    #!/bin/bash
    # =========================================================
    # 脚本名称:Cloudflare Tunnel 全自动泛域名加速脚本
    # 适用环境:R2S (ImmortalWrt) + 移动宽带
    # 特点:支持通配符,未来新增子域无需改动脚本
    # =========================================================
    
    WORK_DIR="/opt/cf_speedtest"
    # Dnsmasq 额外配置文件路径 (OpenWrt 标准路径)
    DNSMASQ_CONF="/etc/dnsmasq.d/cloudflare_speedtest.conf"
    DOMAIN="sirenyan.cn"
    
    cd $WORK_DIR
    
    # 1. 清理旧缓存
    rm -f result.csv
    
    # 2. 运行优选 (针对 R2S 性能调优)
    # -n 50: 降低线程保护 CPU;-tp 443: 必须测 HTTPS 端口;-ip: 移动宽带专用段
    echo "正在为移动线路探测最快节点..."
    ./CloudflareST -n 50 -t 4 -tp 443 -tl 200 -dn 1 -ip 104.16.0.0/16
    
    # 3. 提取最优 IP
    best_ip=$(sed -n '2p' result.csv | cut -d',' -f1)
    
    # 4. 判断并写入 Dnsmasq 泛域名配置
    if [ -n "$best_ip" ] && [ "$best_ip" != "IP 地址" ]; then
        echo "探测成功!最优节点 IP 为: $best_ip"
        
        # 使用 address 语法实现泛域名劫持:*.sirenyan.cn 全部生效
        # 这里加一个点表示包含子域,且不影响你可能在 hosts 里对主域名的特殊定义
        echo "address=/.$DOMAIN/$best_ip" > $DNSMASQ_CONF
        
        # 5. 重启 DNS 服务与隧道服务
        /etc/init.d/dnsmasq restart
        /etc/init.d/cloudflared restart 2>/dev/null
        echo "全自动加速已生效,所有 $DOMAIN 的子域名已指向最优节点。"
    else
        echo "优选失败,保持现有配置。"
    fi
    

    赋予权限并初次运行

    Bash

    chmod +x /opt/cf_speedtest/cfst_hosts.sh
    /opt/cf_speedtest/cfst_hosts.sh
    

    五、 第三阶段:解决代理与防火墙的“深度碰撞”

    很多用户提速后发现网络崩溃,通常是因为 R2S 内部的“交通管制”冲突。

    1. 解决 Nikki (Clash) 劫持问题

    现象:隧道连不上,报错 dial tcp 198.18.0.x:7844: i/o timeout原因:Nikki 尝试代理隧道自己的流量,导致死循环。 解决:在 Nikki 插件的“直连名单”中添加 sirenyan.cnargotunnel.com

    2. 开启防火墙“通行证”

    操作:进入 网络 -> 防火墙 -> 区域设置 -> lan

    • 勾选“IP 动态伪装” (Masquerading)
    • 勾选“MSS 钳制”
    • 意义:这是保证内网电脑能通过 R2S 转发访问优选 IP 的关键。

    六、 最终验证:不仅是快,更是稳

    优化完成后,你可以尝试 Ping 任意一个你从未在脚本里写过的子域名,比如: ping whatever.sirenyan.cn -c 4

    数据分析:

    • 延迟:平均延迟由原来的 300ms 降至 60ms 左右。
    • 丢包率:从 10% 以上降至 0 丢包
    • 下载带宽:测速可达 14.94 MB/s,足以让 Jellyfin 里的 4K 电影像本地一样播放。

    七、 总结与自动化运维

    通过 Dnsmasq 泛域名映射,我们不仅解决了当前服务的卡顿问题,更一劳永逸地处理了未来扩容服务的加速需求。

    自动化定时任务

    进入 系统 -> 计划任务,添加:

    代码段

    0 4 * * * /opt/cf_speedtest/cfst_hosts.sh > /dev/null 2>&1
    

    每天凌晨 4 点,R2S 会自动帮你找一次最快的节点,让你的内网穿透永远保持在“头等舱”速度。

  • 玩转 Steam:解决 R2S 旁路由 + Nikki 丢包抖动的终极指南

    玩转 Steam:解决 R2S 旁路由 + Nikki 丢包抖动的终极指南

    前言:代理与游戏的“天生不合”

    在 OpenWrt 或软路由环境下,Nikki 是我们管理流量的神器。然而,当你满心欢喜地打开 CS2 或其他竞技游戏时,现实往往是残酷的:进不去服务器、VAC 掉线、或者高达 100ms 的网络抖动

    很多玩家选择在游戏时手动关掉代理,但这不仅繁琐,还会让你失去对其他后台流量(如 FRP 穿透、Discord 语音)的加速。本文将带你彻底攻克这一难题,实现“鱼和熊掌兼得”,在保持内网穿透加速的同时,享受裸连般的竞技体验。

    第一章:解开谜团 —— 到底有几个 TUN 开关?

    在 R2S 等设备的配置过程中,你会发现至少有三个地方可以开启 TUN。这种“多重人格”的设计是导致很多新手配置冲突、规则失效的根源。

    1.1 三个设置的身份界定

    根据你的配置环境,这三个开关的职责分工如下:

    开关位置角色定位技术本质
    Nikki 插件页 (LuCI)“总指挥” (Master)决定是否生成包含 TUN 指令的配置文件。插件启动时会根据此处的勾选强制覆盖手动修改的 .yaml
    配置文件 (Config.yaml)“执行手册” (The Plan)核心进程读取的静态指令,标记为 tun: enable: true
    UI 面板 (Zashboard)“临时遥控器” (Remote)通过 API 实时修改核心状态。你在面板上点的开关会立即生效,但通常重启插件后就会重置。

    1.2 三个 TUN 设置到底有什么区别?

    在 R2S 系统中,这三者其实是 “上级命令”“执行状态” 的关系:

    • Nikki 插件页中的 TUN (LuCI 界面):这是 “配置文件生成器”。你在这里点击“启用”,插件会重新编写磁盘上的 Config.yaml 文件,并重启整个 Nikki 进程。这是最根本的设置。
    • 配置文件中的 tun: enable: true:这是 “核心大脑的指令”。当 Nikki 核心启动时,它只认这个文件里的指令。如果这里是 false,核心就不会创建虚拟网卡。
    • UI 面板中的 TUN (MetaCubeXD/Zashboard):这是 “临时遥控器”。它通过 API 直接操作正在运行的 Nikki 核心。你在面板上点的开关 会立即生效,但通常不会保存到磁盘。一旦路由器重启或插件重载,它就会被插件页的设置覆盖。

    到底谁才是有用的? 插件页 (LuCI) 的设置才是真正的主人。 它决定了你每次启动时的初始状态。UI 面板仅用于你在不重启服务的情况下进行临时测试。

    第二章:深层溯源 —— 为什么 CS2 在 TUN 模式下会崩溃?

    CS2 (Counter-Strike 2) 采用的是 Valve 的专用网络协议,它对数据包的完整性、时序性以及路径一致性要求近乎苛刻。开启 TUN 模式后,通常会触发以下几颗“地雷”:

    2.1 UDP 状态丢失与 MTU 陷阱

    竞技游戏几乎完全基于 UDP 协议,这种协议不像 TCP 那样会自动重传。在默认的 Mixed 栈 下,Nikki 会在用户态(User Space)模拟一个协议栈。

    • MTU 损耗:数据包进入虚拟网卡需要额外的头部封装(Overhead),导致 MTU(最大传输单元)变小。
    • 分片抖动:如果一个 UDP 包因为 MTU 问题被强制拆分(Fragmentation),延迟就会瞬时飙升。CS2 检测到这种不稳定的包序或丢包,就会判定“网络异常”并强制你掉线。

    2.2 Fake-IP 的“安全警报”

    Nikki 默认开启 enhanced-mode: fake-ip

    • 逻辑冲突:当你查询服务器 IP 时,Nikki 立即返回一个 198.18.x.x 的假地址。
    • 反作弊拦截:游戏客户端(如 Steam)会对比 DNS 返回的 IP 和它内置的服务器列表。如果发现拿到的 IP 是个“本地假地址”,出于安全保护,系统会认为流量遭到了劫持,从而拒绝连接或触发 VAC 反作弊掉线。

    2.3 反作弊 (VAC) 对虚拟网卡的敏感性

    VAC 系统会实时监测本地网卡状态。TUN 模式创建的 nikki 虚拟网卡接管了全局流量,如果反作弊系统发现流量来自代理网段或经过异常封包处理,会为了“公平竞争”强制断开连接。

    2.4 诡异的“路由表冲突 (Routing Loop)”

    当你配置文件设为 false 但 UI 强行开启时,会出现极其严重的抖动:

    • 半开启状态:此时核心处于一种非正常工作状态。由于配置文件里没有正确的 auto-route 指令,系统尝试将流量塞入 TUN 网卡,但底层系统并未准备就绪。
    • 乒乓效应:数据包在 R2S 内部像打乒乓球一样来回弹跳、重试,造成了巨大的延迟波动。只有彻底关掉 UI 开关,流量回到正常物理网卡路径,抖动才会消失。

    第三章:终极方案 —— 四位一体的游戏加速策略

    为了实现 0 损耗直连,我们需要从栈模式、应用层规则、网络层绕过、DNS 过滤四个维度同时下手。

    3.1 栈模式升级:从 Mixed 到 System

    这是延迟从 100ms+ 降至 20ms 的关键。

    • 操作:在插件页将 栈 (Stack) 选为 System
    • 原理Mixed 栈通过用户态进程处理包,就像在马路上加了个检查站;而 System 栈使用 Linux 内核原生转发。流量在进入核心后直接由内核代劳,效率几何倍数提升。

    3.2 应用层:全量 IP-CIDR 置顶规则

    为了覆盖 Steam 全球所有的对战服务器集群(尤其是 CS2),必须确保以下 4 条 IP 段 处于 rules 列表的最顶部,并带上 no-resolve 参数。

    YAML

    rules:
      # 必须置顶:解决游戏 UDP 握手与掉线问题
      - IP-CIDR,155.133.224.0/19,🎯 直连,no-resolve
      - IP-CIDR,162.254.192.0/18,🎯 直连,no-resolve
      - IP-CIDR,185.25.180.0/22,🎯 直连,no-resolve
      - IP-CIDR,205.196.64.0/18,🎯 直连,no-resolve
    
    • no-resolve 的意义:告诉核心直接比对 IP 地址,不要去尝试解析域名。这样可以瞬间判定为直连,避免了 DNS 劫持。

    3.3 网络层:skip-proxy 实现“物理级”绕过

    即使是直连规则,流量依然会进入 Nikki 核心走一遍逻辑。为了消除最后的抖动,我们要让这些 IP 连“虚拟网口”都不进。

    YAML

    tun:
      enable: true
      stack: system
      # 核心:将 4 条游戏 IP 加入物理绕过名单
      skip-proxy:
        - 155.133.224.0/19
        - 162.254.192.0/18
        - 185.25.180.0/22
        - 205.196.64.0/18
    
    • 效果:这些流量会直接由操作系统的路由表处理。这在技术上等同于“关掉整个 TUN 转发”的效果,但仅针对游戏流量。

    3.4 DNS 层:Fake-IP 过滤器代码

    为了防止 Steam 域名被劫持为虚假地址,必须在 DNS 模块中进行排除。

    YAML

    dns:
      enable: true
      enhanced-mode: fake-ip
      # 这里的 filter 确保以下域名返回真实 IP
      fake-ip-filter:
        - "+.steampowered.com"
        - "+.steam-chat.com"
        - "+.steamchina.com"
        - "+.steamcontent.com"
        - "+.steamstatic.com"
        - "+.steamserver.net"
        - "+.st.dl.bscstorage.net"
    
    • 作用:强制这些域名返回真实 IP(Real IP),让游戏客户端能直接探测到服务器,彻底避开发生 VAC 冲突的风险。

    第四章:实测验证与避坑总结

    4.1 成功标志

    在执行配置并进入 CS2 比赛后,请观察 UI 的连接面板:

    1. 连接状态:如果在面板里完全搜索不到 155.133.x.x 等 IP 记录,恭喜你,skip-proxy 成功实现了物理绕过。
    2. 备选状态:如果能搜到连接,但“规则”列显示为 Match,“链路”列显示为 DIRECT,说明 rules 层级的直连已生效。

    4.2 避坑指南

    • 防火墙覆盖:如果你在 skip-proxy 中设置了依然有 20ms 抖动,请检查 Nikki 插件 UI 中是否有“绕过 IP/网段”的输入框,在那里填入这 4 条 IP 的效果会更直接。
    • 混合模式:请务必确保插件页的 “覆盖 DNS 劫持”关闭 状态,否则 Fake-IP 依然会强行介入。

    结语:竞技精神与极致网络

    网络调优没有终点,只有不断逼近物理极限的努力。通过将 Nikki 改为 System 栈、全量置顶 4 条核心 IP 规则、并配合 skip-proxy 物理绕过,我们终于实现了在软路由不关代理的前提下,享受接近裸连的 CS2 竞技体验。那最后的 20ms 抖动往往是运营商线路的物理基础,此时的你已经拥有了目前技术手段下最稳健的防守。

  • OpenWrt Docker 进阶教程:手动分区、扩容与避坑指南

    OpenWrt Docker 进阶教程:手动分区、扩容与避坑指南

    在 OpenWrt 上玩 Docker,最忌讳的就是“一键安装”。默认情况下,Docker 会把所有的镜像和容器数据堆在系统的 /overlay 分区,如果你的系统盘较小,很快就会报错。

    核心要点概括

    • 先分区后安装:手动创建独立挂载点,防止 Docker 挤占系统空间。
    • 关键前置操作:禁用系统自动挂载,确保磁盘路径受控。
    • 文件系统选择:推荐使用 Btrfs 格式以获得更好的兼容性。

    第一步:手动准备 Docker “专属领地”

    在正式安装 Docker 插件之前,我们需要先在磁盘上开辟出一块空间。

    1. 安装磁盘管理工具:在“系统” -> “软件包”中,搜索并安装 luci-app-diskman。安装后刷新页面,在“状态”或“系统”菜单下找到“磁盘管理”。
    2. 创建新分区
      • 在剩余空间较大的磁盘上点击“修改”。
      • 新建一个分区,大小根据需求设定(建议至少 10GB 以上,视频演示为 +10G)。
    3. 格式化(关键点)
      • Btrfs (强烈推荐):如果你计划运行 AdGuard Home 等插件,Btrfs 可以避免镜像拉取时的兼容性报错。
      • Ext4:普通用户也可以选择。
      • 点击“格式化”并确认。

    第二步:配置挂载点与关键细节

    我们需要告诉系统,这块新空间是专门给 Docker 用的。请注意这里有一个非常关键的步骤。

    1. 禁用自动挂载:进入“系统” -> “挂载点”,向下滚动找到“全局设置”。⚠️ 重要细节:取消勾选“自动挂载未配置的磁盘分区”以及“自动挂载已配置的分区”。这一步是为了防止系统在启动时乱序挂载,确保我们的手动配置生效。点击“保存并应用”。
    2. 手动添加挂载点
      • 点击“添加”,在“设备”中选择你刚刚创建的那个分区(如 sdb3sda3)。
      • 挂载点设置:如果下拉菜单有“作为 Docker 根目录使用”的选项,直接选择;如果没有,请选择“自定义”,手动输入:/opt/docker(这是大多数固件默认的 Docker 路径)。
    3. 点击“保存并应用”。此时,/opt/docker 路径就已经拥有了你分配的十几 GB 空间。

    第三步:安装 Docker 插件

    1. 环境检查
      • 确保网络环境正常(建议确保路由器具备流畅拉取海外软件包的能力,否则会失败)。
      • 确保系统可用空间(Root)至少还有 300MB 以上,因为依赖包体积较大。
    2. 执行安装:在软件包中搜索 luci-app-dockerman,点击安装。它会自动下载 Docker 核心组件及界面程序。
    3. 忽略报错与耐心等待:安装过程中如果出现红色的日志报错,通常可以忽略操作建议:安装完成后,不要立即点击菜单。静候 3-5 分钟,让后台程序彻底完成初始化,然后重启路由器

    第四步:Docker 的二次扩容与迁移

    如果你发现现在的 Docker 空间不够用了,想换一块更大的硬盘,流程如下:

    1. 备份数据:将原 Docker 挂载目录(如 /opt/docker)下的文件通过 SSH 临时拷贝到其他存储介质。
    2. 新分区挂载:重复“第一步”和“第二步”,准备一块更大的新分区。
    3. 替换路径:在“挂载点”中将原路径指向新的分区。
    4. 还原数据:将备份的文件粘贴回新分区目录下,重启即可无损复活。

    总结

    通过手动禁用自动挂载并指定 /opt/docker 路径,你已经搭建了一个极具扩展性的 Docker 环境。这种方案最大的好处是:即便你日后重写了系统固件,只要数据盘不格式化,只需简单地重新挂载,你的所有容器和镜像都会毫发无损地找回来。

  • 一劳永逸!OpenWrt 固件刷机前扩容保姆级教程:告别软件包空间不足

    一劳永逸!OpenWrt 固件刷机前扩容保姆级教程:告别软件包空间不足

    很多朋友在刷入 OpenWrt 固件后,发现系统自带的软件包空间(Overlay)只有区区几百 MB。当你想要安装 Docker、各种插件或者搭建小型 NAS 时,空间不足就成了最大的痛点。

    虽然可以在安装后通过挂载新分区来扩容,但那不仅操作复杂,还容易导致配置丢失。最优雅的方案,就是在刷机之前,直接把镜像“撑大”。

    内容要点概括

    • 适用场景:希望刷机后直接拥有大容量软件包空间。
    • 核心逻辑:解压镜像 -> 物理扩容 -> 逻辑扩容 -> 重新压缩。
    • 工具需求:Linux 系统(Ubuntu/Debian 或现成的 OpenWrt 终端)。

    第一步:环境检查与依赖确认

    在开始之前,请确保你的 Linux 环境具备以下三件套。你可以通过以下命令确认:

    Bash

    which gzip   # 压缩/解压
    which dd     # 物理填充
    which parted # 分区表调整
    

    第二步:详细扩容实操全流程

    为了保证操作不影响系统盘,我们将工作目录切换至存储空间较大的 /mnt 下进行。

    1. 切换目录与准备

    将你下载好的镜像(如 immortalwrt.img.gz)通过 SFTP 上传至 /mnt

    Bash

    # 切换到挂载目录
    cd /mnt
    

    2. 解压缩镜像文件

    首先将压缩包还原为原始镜像。

    Bash

    # 执行后,.gz 文件会消失,生成 .img 原始文件
    gzip -d immortalwrt.img.gz
    

    3. 扩展镜像文件的物理大小

    我们需要在镜像文件的末尾“粘”上一块空白区域。

    Bash

    # count=500 表示增加 500MB,如需 1GB 请改为 count=1024
    dd if=/dev/zero bs=1M count=500 >> immortalwrt.img
    

    注意:此时文件体积已经变大,但分区表还没“意识到”这部分新空间。

    4. 使用分区工具进行逻辑调整

    这是最关键的一步,我们需要手动拉伸分区的边界。

    Bash

    # 使用分区工具打开镜像
    parted immortalwrt.img
    

    ⚠️ EFI 固件特殊交互提示:

    如果你的固件支持 EFI 启动,进入后可能会有警告提示,请按照以下选择:

    • 遇到 OK/Cancel:输入 ok
    • 遇到 Fix/Ignore:务必输入 fix

    在交互界面依次执行:

    Bash

    # 1. 查看当前分区布局,确认 rootfs 分区编号(通常为 2)
    print
    
    # 2. 调整分区大小:将第 2 分区扩展至镜像末尾
    resizepart 2 100%
    
    # 3. 再次确认分区大小是否已更新
    print
    
    # 4. 退出工具
    quit
    

    5. 重新压缩镜像(可选但建议)

    为了方便下载回本地刷机,建议重新压缩以减小体积。

    Bash

    gzip immortalwrt.img
    

    为什么要做这一步?(进阶科普)

    1. 官方 vs 镜像定制:官方镜像(OpenWrt 官方或 ImmortalWrt)为了兼容性,默认分区通常极小。直接扩容镜像能保证你安装 Docker 或大型插件时不会报错。
    2. 格式选择
      • Squashfs 格式:扩容后支持“恢复出厂设置”。
      • Ext4 格式:性能略好,但不支持系统重置。
    3. 安全性:在宿主机修改镜像,比在运行中的路由器修改在线分区安全得多,避免了因操作失误导致的“无法启动”死循环。

    总结

    通过上述解耦的命令,每一步都可以实时监控进度。扩容后的固件在第一次启动时,其 overlay 分区(即你的软件包空间)就会显示为你设定的大小。

  • 软路由音乐折腾记:为“音流”打造专属歌词服务器 (LrcApi 部署指南)

    软路由音乐折腾记:为“音流”打造专属歌词服务器 (LrcApi 部署指南)

    如果你和我一样,在软路由(ImmortalWrt/iStoreOS)上搭建了 Navidrome 或 Jellyfin 听歌,那么 LrcApi 绝对是提升体验的“神兵利器”。它能让你的“音流 (MusicFlow)” App 具备自动抓取网易云、QQ 音乐歌词的能力。

    核心要点总结

    • 服务端口28883
    • 部署路径:Docker 根目录设在 /opt/docker
    • 验证方式:API_AUTH 留空(适合家庭内网使用)。
    • 适用客户端:音流 (MusicFlow)。

    一、 环境准备

    为了保证数据在软路由重启或升级后不丢失,我们将配置文件持久化到已经扩容好的物理分区中。

    在 SSH 终端输入以下命令创建目录:

    Bash

    mkdir -p /opt/docker/lrcapi
    

    二、 Docker 部署 (SSH 方式)

    执行以下命令直接拉取镜像并启动容器。这里我们将 API_AUTH 设为空,简化内网连接步骤。

    Bash

    docker run -d \
      --name lrcapi \
      --restart always \
      -p 28883:28883 \
      -v /opt/docker/lrcapi:/app/data \
      -e API_AUTH="" \
      hisatri/lrcapi:latest
    

    参数详解:

    • -p 28883:28883:将容器内的歌词服务端口映射到软路由。
    • -v /opt/docker/lrcapi:/app/data:将配置和缓存映射到 20GB 的 Docker 专用分区。
    • -e API_AUTH="":禁用身份验证,方便 App 端直接连接。

    三、 验证与排错

    安装完成后,建议通过日志观察服务状态:

    Bash

    docker logs -f lrcapi
    

    看到以下信息即代表成功:

    INFO:waitress:Serving on http://0.0.0.0:28883

    INFO:mod.check_update:当前已是最新版本

    四、 客户端对接 (音流 App)

    最后一步,在手机端的“音流” App 中完成“握手”:

    1. 打开设置:进入“歌词设置”选项卡。
    2. 自定义服务器:在“自定义歌词服务器”中输入:
      • 地址http://[你的软路由IP]:28883
      • Token / Auth留空(因为我们在 Docker 中设置了空值)。
    3. 保存测试:播放一首无词歌曲,稍等片刻,歌词便会自动浮现。

    结语

    通过 Docker 部署 LrcApi,我们不仅解决了音乐库歌词缺失的痛点,还充分利用了软路由扩容后的存储空间。