fix(nodes): restore installed Certbot AppArmor profiles on legacy hosts
Some checks are pending
Docker Build and Publish / build (push) Waiting to run

This commit is contained in:
hellcat 2026-10-17 17:49:19 +08:00
parent ac9f249961
commit 44d1c79bef
5 changed files with 51 additions and 0 deletions

View File

@ -28,6 +28,8 @@ python3 scripts/node-onboarding/bundle-ops.py --source FULL_SOURCE_COMMIT --base
适配器在stage前检查本地依赖、远端Git版本及工具、正式组和账号、节点既有配置、独立端口、原服务、证书归属与钩子。既有证书无本任务owner、全局证书钩子或目标证书的额外pre/post钩子均停止。缺依赖须在准备阶段解决,不先创建一批面板对象后再临时安装工具。
Certbot准备不能只检查`command -v`:还须实际运行`certbot --version`。2026-10-17后续批次两台Debian10虽有Snap Certbot、renew timer和生成的profiles,但既有AppArmor加载服务缺失,证书命令报`missing profile`。项目提供`load-certbot-apparmor.sh`、`dpl-certbot-apparmor.service`及renew drop-in作为该情形的限定修复:只校验并加载已安装Certbot/core生成的profiles,保留其原有模式;不启用全局AppArmor服务、不关闭安全校验、不重启XrayR。仅在现场确认符合该缺口的主机部署到独立Git目录`/opt/dpl-certbot-security/provision`,先`--check`、再加载并验证工具;原续期命令前重检profiles,启动时也加载。安装前保存原单位/drop-in存在性及已加载profile清单;失败不签发,回退先确认无证书进程,再撤销本任务unit/drop-in并按原清单处理本次新加载项,不卸载其他任务profile。本段修复的实际部署及验收状态见[STATUS](STATUS.md)。
## 本地参数文件
全部放在权限700的任务目录,文件600。基础计划沿用[NODE_BATCH](NODE_BATCH.md#参数格式),包括本批任意数量、任意已支持国家的候选节点;不固定五节点、日本、组1或任务日期。新增站点配置JSON如下,示例路径必须换为实际已核实值:

View File

@ -8,6 +8,8 @@
候选jp06/07/08、us03现场只读核查通过;us02因SSH主机密钥与既有信任不符停止,用户批准备用us04精确首次指纹后核查通过。5台原XrayR均在运行,新接入端口24443空闲;Debian11/10的Git依赖按各自发行版准备,不沿用硬编码bullseye源。本批账本与现场证据在忽略目录`codex/output/node-batch-five-20261017/`。正式开放、动态全量订阅、QA清理、旧资源回归及资源文档同步尚待完成。
现场进展:面板、网关和5台候选的运维目录已Git部署至2547ea25;修复后的本地适配器源码ac9f249已推送。日本3台QA及独立审查通过,尚未开放;美国两台节点程序已安装,但既有Snap Certbot因AppArmor profile未加载而不能签证书。已准备限定Certbot/core profiles的安全加载脚本与启动/续期unit,尚待提交推送、独立运维部署及实际验证;不将准备状态写成修复完成。
## 2026-10-17 批量接入流程优化(本地验证)
已实现正式`ssh-site-v1`适配器及`configure-site.py`入口,去除临时handler中的固定日期、日本、组1和节点数量。正式验收从真实账号授权集合生成快照,完整校验新旧节点、预期出口、严格TLS、原始证据摘要、QA身份/403/禁用/下发排除及时效;集合变化停止。没有有效正式组账号时自动创建100MiB/1小时/1设备非管理员测试用户,journal恢复同一身份,正常成功/失败/等待均清理本任务用户,关闭后不复活;异常中断依靠日志恢复和时限兜底。已批准指纹匹配后才读取凭据,SSH始终经白色机,按线程复用会话、按阶段延迟连接,不自动重放断线命令。

View File

@ -0,0 +1,7 @@
[Unit]
Requires=dpl-certbot-apparmor.service
After=dpl-certbot-apparmor.service
[Service]
# Recheck generated profiles after a snap refresh, before the existing renewal command.
ExecStartPre=/bin/bash /opt/dpl-certbot-security/provision/load-certbot-apparmor.sh --load

View File

@ -0,0 +1,13 @@
[Unit]
Description=Load existing Certbot AppArmor profiles for DPL certificate operations
After=local-fs.target
Before=snap.certbot.renew.service
ConditionPathExists=/var/lib/snapd/apparmor/profiles/snap.certbot.certbot
[Service]
Type=oneshot
ExecStart=/bin/bash /opt/dpl-certbot-security/provision/load-certbot-apparmor.sh --load
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target

View File

@ -0,0 +1,27 @@
#!/bin/bash
set -euo pipefail
# Restore only profiles already generated by the installed Certbot/core snaps.
# This does not enable the global AppArmor service or change profile modes.
[[ $(id -u) == 0 ]] || exit 1
mode=${1:---load}
[[ $# -le 1 && ( $mode == --load || $mode == --check ) ]] || exit 2
[[ $(cat /sys/module/apparmor/parameters/enabled) == Y ]] || exit 3
directory=/var/lib/snapd/apparmor/profiles
[[ -d $directory && ! -L $directory && $(stat -c %u "$directory") == 0 ]] || exit 4
[[ -z $(find "$directory" -maxdepth 0 -perm /022 -print) ]] || exit 4
[[ -f $directory/snap.certbot.certbot && -f $directory/snap.certbot.renew ]] || exit 5
shopt -s nullglob
profiles=("$directory"/snap.certbot.* "$directory"/snap-update-ns.certbot "$directory"/snap-confine.core.*)
(( ${#profiles[@]} >= 4 )) || exit 5
# Validate every input before loading any profile. Never use complain/disable flags.
for profile in "${profiles[@]}"; do
[[ -f $profile && ! -L $profile && $(stat -c %u "$profile") == 0 ]] || exit 6
[[ -z $(find "$profile" -maxdepth 0 -perm /022 -print) ]] || exit 6
/usr/sbin/apparmor_parser --skip-kernel-load --skip-cache "$profile"
done
if [[ $mode == --load ]]; then
for profile in "${profiles[@]}"; do
/usr/sbin/apparmor_parser --replace --skip-cache "$profile"
done
fi
printf 'Certbot/core profiles checked: %s; mode: %s\n' "${#profiles[@]}" "$mode"