3.7 KiB
管理员重置命令限制验收
日期:2026-09-19。
需求与任务状态
- [✓] 仅显式
systemctl start smail-admin进入重置流程,systemctl stop smail-admin终止流程。 - [✓]
restart、reload及相关变体不能开启新的重置交互。 - [✓] 交互绑定启动终端,取消后无系统共享密码请求残留。
- [✓] 保留邮箱、动态码、安全码验证及受保护本机 IPC,不调整账户密码或生产数据库。
- [✓] Windows 定向测试、Linux 测试、服务器实际命令验证和部署完成。
原因与修改
systemd 会将 restart 的启动阶段转换成 start Job,因此只检查 list-jobs 无法识别原始动作。Restart=no 只禁止自动重启,不限制管理员手工重启。reload 本身已被拒绝,但 systemctl 创建的密码代理会显示已有的系统共享输入请求。
管理程序现在要求唯一、本机 root、前台终端的显式 systemctl start smail-admin 进程,同时校验可执行文件、参数、进程启动时间及终端设备,继续保留 systemd 上下文及本机 IPC 校验。非交互启动、多服务、通配符、并发启动及重启命令均不授权。
输入直接绑定启动终端,验证内容可见,新密码不回显。保留终端行编辑、信号和换行设置,避免停止过程中与 shell 的终端恢复竞争。监测原启动进程退出或 PID 复用,取消输入并关闭连接。服务使用 KillMode=mixed,主进程先处理取消,再由 systemd 兜底清理。
实机验证
环境:部署服务器的 systemd 259,使用两个独立 SSH 终端;只进入菜单或输入无效选项,没有发送邮件或执行真实改密。
| 场景 | 实际结果 |
|---|---|
start |
显示安全验证方式列表,仅启动终端可见 |
stop |
流程终止,inactive、Result=success,终端模式正常 |
| Ctrl+C | systemctl 退出,管理程序随后结束,无遗留输入请求 |
未运行时 restart |
拒绝启动,退出码 1,无验证菜单 |
正在输入时 restart |
systemd 先终止现有流程;新启动被拒绝,不重新显示菜单 |
reload |
systemd 报不支持;另一终端现有输入不被接管,原流程可继续 |
reload-or-restart |
拒绝启动,退出码 1,无验证菜单 |
未运行时 try-restart、try-reload-or-restart |
systemd 返回成功但不执行动作,管理进程 PID 为 0 |
| 无效选项及结果提示 | 显示失败原因,按回车结束 |
| 系统密码请求目录 | 验证期间及结束后均无本次重置产生的 ask.* |
自动化验证
- 本机:
go test ./services/adminreset ./cmd/smail-admin通过。 - Linux:交叉编译后的
adminreset完整测试在服务器隔离目录运行通过。 - 覆盖显式命令、危险参数变体、进程启动时间/PID 重用、root 身份、真实伪终端输入、密码无回显、输入取消和终端恢复。
go vet ./services/adminreset ./cmd/smail-admin、git diff --check通过。- unit 校验通过;systemd 对现有其他服务的
CPUAccounting弃用提示与本次修改无关。
systemd 行为边界
systemd 没有独立禁止手工 restart、同时允许 start/stop 的 unit 指令。因此不能删除 systemctl 自身的命令,也不能阻止它先执行重启的停止阶段。本次保证这些命令无法启动或重新进入重置流程。只读的 status、show 和日志查询继续可用。
原始命令检查约束正常部署操作,不构成对主机 root 的隔离;安全凭据验证和受保护本机 IPC 必须独立保留。验证二进制保存在 /run/smail-command-validation-20260919/,部署前备份保存在 /var/backups/smail-admin-command-20260919/。