rs-short 3.3.1 配置参数详解

rs-short 3.3.1 双配置文件全量详解:config.toml 16 参数语义与启动红线(panic 级校验)、lists.toml 名单语法与 _category 陷阱、names 黑名单 Missing translation 缺陷、可疑监测按去重 IP 计数纠偏,theme/verbose_console/名单四项改参→重启→验证闭环实录。

rs-shortrs-short短链接自托管PostgreSQL2026/11/02

rs-short 3.3.1 配置参数详解

覆盖 rs-short 3.3.1 的全部两个配置文件:config.toml(16 个参数)与 lists.toml(策略名单)。所有参数语义取自源码(src/init.rs、src/structs.rs、src/spam.rs)与样例文件注释,关键行为均经"改参→重启→验证"闭环实测(取证:/opt/data/quzuo/tmp/rs-short/evidence.md)。

一、配置文件总览

文件作用生效方式镜像内位置
config.toml主配置(监听、数据库、站点身份、验证码、反钓鱼)启动时一次性读取,改后必须重启不含,必须挂载到 /run_dir/config.toml
lists.toml名单策略(names/urls 的 allow/blocklist)同上,无热加载内置默认版,建议挂载覆盖
lang.json界面文案(en/fr/hr/oc)编译期嵌入模板逻辑,一般不改内置
assets/themes/*light/dark/custom 主题 CSS 与背景重启生效内置

启动红线(源码 check() 实测):以下任一情况进程直接 panic 退出,容器表现为重启循环——

  1. config_version ≠ 3(提示 "Your configuration file is obsolete!");
  2. instance_hostname / cookie_key / phishing_password 仍是样例默认值(前两者中 instance_hostname 为阻断级);
  3. cookie_key 长度 < 88;
  4. lists.toml 解析失败(含 §3 的 _category 陷阱)。

二、config.toml 参数详解

2.1 [general] 站点与网络(10 项)

参数默认(样例)语义与实测要点
listening_address0.0.0.0:8080监听地址:端口。容器内保持 8080,宿主映射自选(本部署 8164)
database_path./db/db.sqlite三形态:SQLite 相对/绝对路径;postgres://user:pass@host:port/db;mysql://...。必须与二进制编译 feature 匹配:官方 Dockerfile 产物只认 postgres://(PG 实测 ✅);SQLite 官方注明有库锁风险(有缓存层兜底)
instance_hostnames.example.com对外 (子)域名含协议、无尾斜杠。用于生成管理链接/钓鱼标记链接展示与自链接防护比对。⚠️ 实测:填 http://127.0.0.1:8164 这类带端口值时,自链接防护失效(比对用 uri.host() 不含端口);生产填无端口域名即正常
hoster_nameExampleSoft站点名,出现在 <title>(实测 "Link shortener – QuzuoLab")、页脚与政策文案
hoster_hostnameexample.com提供方主站链接(展示用,非默认值不阻断)
hoster_toshttps://example.com/ToS服务条款链接(展示用)
contactmailto:...举报联系通道(反钓鱼必需入口,支持任意 scheme)
themelightlight / dark / custom(custom 需自建 assets/themes/custom/base.css)。实测闭环:light→dark 重启后首页资源路径即变 themes/dark ✅
cookie_keyCHANGE ME会话 Cookie 加密密钥(存验证码答案)。生成:openssl rand -base64 64 | tr -d '\n';长度 <88 panic。改动会使所有未完成创建的会话失效(无害)
captcha_difficulty3验证码强度 0–5,逐级叠加 Noise/Wave/Grid 滤镜。0–5 均强制启用,无法关闭(README 把"可关开关"列为待办)。实测难度 3 下 6 字符图像人工/视觉识别均可稳定通过

2.2 [phishing] 反钓鱼与日志(6 项)

参数默认(样例)语义与实测要点
verbose_consolefalsetrue 时每次建链向 stdout 打印 NOTE: New link created: … / Redirects to / Admin link / Flag as phishing。便于治理但牺牲建链者隐私(样例注释原话)。实测闭环:false→true 重启后新建 verbose-test 即见四行打印 ✅
verbose_suspicioustrue启用 RAM 内可疑访问监视器(临时存 IP+时间戳,重启即清,不落库)
verbose_levelnotice日志级别 info|notice|warn|crit
suspicious_click_count25告警阈值。⚠️ 源码实测语义是时间窗内去重 IP 数(spam.rs 对相同 IP 不重复计数),与样例注释"how many clicks"不符——单机刷点击不会触发,分布式访问才会。这正是"活跃钓鱼需立即处置"的设计本意
suspicious_click_timeframe12窗口小时数;达到阈值打印 WARN: suspicious activity detected. 并清空该链接计数
phishing_passwordCHANGE ME服务端管理密码,构成标记 URL /<short>/phishing/<此值>。要求 URL 安全字符、>16 字符。⚠️ 该密码出现在 URL 中,反代日志会留痕——生产建议反代层屏蔽该路径日志并定期轮换

三、lists.toml 策略名单详解

结构:[names] 与 [urls] 两个域,各含 allowlist / blocklist。

3.1 语义

  • allowlist(仅 { expr = '<regex>' }):命中项永不进入 verbose_console / verbose_suspicious 的日志与监视(治理豁免,如自家活动链接);
  • blocklist:建链时命中即 403 拒绝。[urls] 条目 { expr, category, matching },category ∈ shortener | freehost | spam(决定用户端提示文案),matching ∈ host(默认) | full-uri | port | authority | path | query(基于 http::Uri 组件匹配,大小写不敏感);
  • 默认版内置 100+ 条短链域名黑名单(bit.ly/t.co/tinyurl/linkvertise/iplogger 等)——实测缩短 https://bit.ly/fake 返回 403「Please do not chain shortened links with another link shortener.」✅

3.2 ⚠️ 实测最大的坑:names 的 _category

文件头注释写条目格式是 { expr, category },但源码 BlockEntryName 结构体字段为 _category(serde 按字段原名解析):

[names]
allowlist = []
blocklist = [
    { expr = '^blocked-name$', _category = 'spam' },   # ✅ 正确(注意下划线)
]

写成 category 的实测后果——启动即 panic,容器重启循环:

thread 'main' panicked at src/spam.rs:89:34:
called `Result::unwrap()` on an `Err` value: Error { message: "missing field `_category`", ... }

[urls] blocklist 则正常用 category(无下划线),两域不一致,属上游文档/代码缺陷。

3.3 命中 names 黑名单的已知显示缺陷

_category='spam' 命中后用户端提示区显示 「Missing translation」(HTTP 403 正常返回)。源码定位:spam.rs 抛 ErrorKind::WarnBlockedName,而 lang.json 只有 WarnBlockedNameSpam 键,键名不匹配,日志伴随 FATAL: Missing translation for key WarnBlockedName。功能不受影响(仍拦截),文案待上游修复;急需可读提示可自行给 lang.json 补键(需重建镜像)。

四、改参→重启→验证闭环实录

以本部署(compose 挂载两个文件,docker compose restart rs-short 约 2 秒)为例:

#改动验证命令实测结果
1theme = "light"→"dark"curl -s http://127.0.0.1:8164/ | grep -o 'themes/[a-z]*'themes/dark ✅
2verbose_console = false→true创建任一链接后 docker logs rs-short-3.3.1-app出现 NOTE: New link created: http://127.0.0.1:8164/verbose-test … 四行 ✅
3lists.toml 增 blocked-name 规则(先误写 category)restart 后 curl http://127.0.0.1:8164/连接空响应;docker ps 见 Restarting (101);日志 panic missing field '_category' ❌→改 _category 后 ✅
4修正后创建 blocked-namePOST /(表单)403 拦截生效(文案 "Missing translation",见 §3.3)✅
5cookie_key 改新值restart正常启动;旧会话 Cookie 解析失败 → 建链需重新 GET 首页拿验证码(400 NoticeCookieParseFail 路径)✅

对照实验(负向):把 config_version 改 2 → panic "configuration file is obsolete";phishing_password 留 CHANGE ME → panic "You must change it in order to proceed"。校验前置、宁崩不裸奔,是该项目值得称道的安全默认。

五、生产配置建议清单

  1. instance_hostname 用真实 HTTPS 域名(不带端口、不带尾斜杠);
  2. 两个密钥按 §2.1 命令现场生成,纳入备份(cookie_key 丢失仅影响进行中会话;phishing_password 泄露=治理权旁落);
  3. 公开实例建议 verbose_console = true + 反代日志 + fail2ban(README 官方推荐组合);captcha_difficulty 保持 ≥3;
  4. 用 allowlist 豁免自家高频链接,避免日志噪音;
  5. 名单变更纳入发布流程(无热加载,重启秒级但会清空 RAM 监视器);
  6. 反代层对 /phishing/ 路径加访问日志脱敏或来源限制。

六、下一步与互链

rs-short 3.3.1 配置参数详解 - Quzuo