博客/自动化配置

如何在Ubuntu命令行中用cron实现快连订阅节点定时更新?

快连官方团队
定时任务cron命令行订阅更新Ubuntusystemd
快连Ubuntu命令行更新订阅, 如何设置快连定时更新, Ubuntu cron快连订阅节点, 快连自动更新失败怎么办, systemd-timer快连订阅更新, 快连订阅链接定时刷新, Ubuntu命令行配置快连, 快连定时任务最佳实践

功能定位:为什么要在命令行做定时更新

在桌面端点击“刷新订阅”确实简单,但外贸公司或 CI 环境常把 Ubuntu 服务器当出口网关,需要无人值守、可审计、可回滚的节点更新方案。cron 是 Ubuntu 默认内置的定时引擎,无需额外安装,就能把“拉取—校验—重载”三步串成闭环,并把日志留给 systemd-journald 统一收集,方便后续合规抽查。

与桌面客户端相比,命令行方案的核心差异是:无图形依赖、可放进 Docker、可版本化配置。代价是你得自己处理订阅格式转换、异常重试、以及节点可用性探针。下文给出一条最小可复现路径,并标注“经验性观察”带来的取舍点。

功能定位:为什么要在命令行做定时更新
功能定位:为什么要在命令行做定时更新

前置准备:检查系统环境与依赖

1. 确认 Ubuntu 版本与 cron 状态

lsb_release -a          # 查看发行版,20.04 及以上自带 cron
systemctl status cron   # Active: active (running) 即可

若看到 inactive,执行 sudo systemctl enable --now cron 一次性激活。

2. 安装必要工具

快连官方只提供“订阅地址”,返回格式为 base64 编码的 ssr:// 或 https:// 链接。我们需要 curl 拉取、base64 -d 解码,再用 jq 做 JSON 化(可选)。

sudo apt update && sudo apt install -y curl base64 jq

3. 创建低权专用用户

为降低密钥泄露后的影响面,建议新建 kuailian 用户,并禁止登录 shell:

sudo adduser --system --group --shell /usr/sbin/nologin kuailian
sudo mkdir -p /opt/kuailian/{subs,logs,configs}
sudo chown -R kuailian:kuailian /opt/kuailian

获取订阅地址:桌面端最短路径

由于快连并未公开“API 文档”,订阅地址只能在登录后的客户端内提取。下面给出截至当前的最新版本的通用入口,若 UI 调整,请以实际为准。

  • Windows/macOS:主界面右上角「≡」→「订阅设置」→「复制订阅链接」
  • Android:底栏「我的」→「订阅管理」→长按「快连节点」→「复制地址」
  • iOS:由于系统限制,需先开启“开发者模式”才能在同一入口看到地址;若未出现,可临时用桌面端扫码登录后复制。

警告

订阅地址包含 UID 与 token,等同于账号密码,切勿提交到公共代码仓库。

脚本拆解:拉取、解码、校验、重载四步

把四步写成单个 bash 脚本,方便 cron 调用,也方便手动回滚。以下示例保存为 /opt/kuailian/update-sub.sh

#!/usr/bin/env bash
# 更新时间:见日志
set -euo pipefail

SUB_URL="https://sub.quicklink/example/$(cat /opt/kuailian/token.file)"
BACKUP_DIR="/opt/kuailian/configs/$(date +%Y%m%d-%H%M%S)"
LOG_FILE="/opt/kuailian/logs/update.log"

mkdir -p "$BACKUP_DIR"
# 1. 拉取
curl -fsSL "$SUB_URL" -o /tmp/sub.base64
# 2. 解码
base64 -d /tmp/sub.base64 > "$BACKUP_DIR/nodes.txt"
# 3. 基础校验:非空且含 ssr://
if grep -q "ssr://" "$BACKUP_DIR/nodes.txt"; then
    cp "$BACKUP_DIR/nodes.txt" /opt/kuailian/configs/latest.txt
    echo "$(date '+%F %T') 节点更新成功,共 $(wc -l < "$BACKUP_DIR/nodes.txt") 条" >> "$LOG_FILE"
else
    echo "$(date '+%F %T') 订阅内容异常,已放弃" >> "$LOG_FILE"
    exit 1
fi
# 4. 重载(示例:如本地跑了 redsocks2,可 SIGHUP 进程)
pkill -HUP redsocks2 || true

给脚本加可执行权限:

sudo chmod +x /opt/kuailian/update-sub.sh
sudo chown kuailian:kuailian /opt/kuailian/update-sub.sh

cron 入口:三种调度策略对比

策略crontab 写法适用场景风险点
固定间隔0 */6 * * *个人 VPS,节点变化不频繁高峰时段可能撞上官方限速
错峰随机0 3-6 * * *外贸公司,避开国内晚高峰脚本执行时间拉长,需锁机制
守护+失败退避systemd timerCI 网关,失败立即重试配置复杂,需写 service 单元

以下以最常用的“固定间隔”为例,演示如何落地。

落地:添加 cron 并验证日志

1. 编辑 kuailian 用户的 crontab

sudo -u kuailian crontab -e
# 插入下行,每 6 小时执行一次
0 */6 * * * /opt/kuailian/update-sub.sh

2. 观测首次运行

sudo -u kuailian /opt/kuailian/update-sub.sh   # 手动触发
cat /opt/kuailian/logs/update.log

看到“节点更新成功”即表示链路打通;若提示 403,请检查 token 是否过期——桌面端重新复制订阅地址即可。

3. 设置日志留存

Ubuntu 默认使用 systemd-journald,但 cron 任务输出会被截断。建议让脚本自行写文件,再用 logrotate 轮转:

sudo tee /etc/logrotate.d/kuailian <<'EOF'
/opt/kuailian/logs/*.log {
    daily
    rotate 30
    compress
    missingok
    notifempty
}
EOF
3. 设置日志留存
3. 设置日志留存

异常分支: token 失效、节点为空、格式变异

  • token 失效:返回 403,脚本以 exit 1 终止;cron 会发邮件(若系统配置了 MTA)。解决:桌面端重新复制订阅地址,更新 token.file
  • 节点为空:官方偶尔维护,返回 200 但 body 为空。脚本已用 grep -q 兜底,避免覆盖旧配置。
  • 格式变异:经验性观察,官方在 2025 年底曾把 base64 拆成段,中间插入换行。可在解码前加 tr -d '\n' 兼容。

与 systemd 协同:用 timer 替代 cron(可选)

若你对“失败退避”有强需求,可改用 systemd timer,支持 RestartSec=5min 退避。创建单元文件:

sudo tee /etc/systemd/system/kuailian-update.service <<'EOF'
[Unit]
Description=Kuailian sub update
After=network-online.target
Wants=network-online.target

[Service]
Type=oneshot
User=kuailian
ExecStart=/opt/kuailian/update-sub.sh
EOF

sudo tee /etc/systemd/system/kuailian-update.timer <<'EOF'
[Unit]
Description=Run kuailian-update every 6 hours

[Timer]
OnCalendar=*:0/6:00
Persistent=true

[Install]
WantedBy=timers.target
EOF

sudo systemctl daemon-reload
sudo systemctl enable --now kuailian-update.timer

timer 优势:日志统一进 journalctl -u kuailian-update,且支持 AccuracySec=1h 做错峰抖动。

监控与验收:如何证明“自动更新”真的跑了

1. 指标选取

合规场景下,老板最关心“有没有跑”与“节点能不能用”。推荐把 /opt/kuailian/logs/update.log 最后一条时间戳与“当前时间”差值当 KPI,例如:

#!/bin/bash
last=$(tail -1 /opt/kuailian/logs/update.log | awk '{print $1" "$2}')
last_ts=$(date -d "$last" +%s)
now_ts=$(date +%s)
diff=$(( (now_ts - last_ts) / 3600 ))
[[ $diff -le 7 ]] && echo "OK: 上次更新在 ${diff}h 前" || echo "WARN: 已 ${diff}h 未更新"

2. 可用性探针(可选)

若你本地跑了 redsocks2/shadowsocks-libev,可在脚本尾部加 timeout 5 nc -z 127.0.0.1 1080,探测 SOCKS 端口是否仍通;不通则 systemctl restart redsocks2,实现“配置更新+服务自愈”双保险。

不适用场景与边界

  • 节点需二次验证:部分企业订阅要求短信动态码,命令行无法交互,只能回退到桌面端。
  • 网络出口被 DNS 污染:curl 阶段就 443 超时,需先解决连通性,再谈定时更新。
  • 明文法规禁止:在明文要求“境外链路需审批”的区域,自动更新可能被认定为“擅自变更路由”,请事前完成合规备案。

FAQ:脚本、权限与日志

Q1: 能否把 token 直接写进脚本?

可以,但不推荐。单独放在 token.file 方便 logrotate 排除,也降低误提交 Git 的风险。

Q2: 脚本解码报错 “base64: invalid input”?

经验性观察,官方偶尔在返回体里插入换行。可在 base64 -d 前加 tr -d '\n' 清理。

Q3: cron 邮件堆积怎么办?

在 crontab 首行加 MAILTO="" 可关闭邮件;或把输出重定向到日志文件:>> /opt/kuailian/logs/cron.log 2>&1

Q4: 如何回滚到上一版节点?

脚本每次更新前按时间戳新建目录,回滚只需 cp /opt/kuailian/configs/20260419-120001/nodes.txt /opt/kuailian/configs/latest.txt 然后重启代理进程。

Q5: systemd timer 会不会和 cron 重复?

会。两者选其一即可。若已启用 timer,请把对应用户的 crontab 注释掉,避免 6 小时内双次更新。

最佳实践清单(可打印)

  1. 永远用低权用户跑脚本,nologin 防 ssh 误用。
  2. token 单独文件、600 权限、定期轮换。
  3. 脚本内用 set -euo pipefail,出错即退,避免空配置覆盖旧文件。
  4. 每次更新先备份,用日期目录,保留 30 天。
  5. 日志落盘 + logrotate,审计时能用 journalctl 也能用 cat *.log
  6. 监控“最后更新距现在的小时数”而非“是否成功”,可提前发现静默失败。
  7. 若本地代理进程依赖节点,更新后加探针端口,不通即重启,实现自愈。
  8. 在法规要求备案的场景,更新前后各生成一次 ip route 快照,留档备查。

收尾:下一步行动建议

至此,你已在 Ubuntu 服务器上跑通“cron 定时拉取快连订阅节点”的最小闭环,并具备日志审计与回滚能力。建议先用 watch -n 3600 人工观察一天,确认节点可用性探针无误后,再把间隔缩到 4 小时;同时把“最后更新小时数”监控推送到 Prometheus 或自建 Telegram 机器人,实现真正的无人值守。若后续官方推出正式 REST API,可无缝把脚本中的 curl 部分替换为带 OAuth2 的调用,复用同一套日志与回滚框架。

相关关键词:
快连Ubuntu命令行更新订阅如何设置快连定时更新Ubuntu cron快连订阅节点快连自动更新失败怎么办systemd-timer快连订阅更新快连订阅链接定时刷新Ubuntu命令行配置快连快连定时任务最佳实践