自动运维最大的风险不是“不修”,而是“修坏了”。
你写了个脚本自动清理磁盘,结果删了正在写入的日志,程序崩了。你写了个脚本自动重启服务,结果nginx配置有错,重启一百次也没用,还把系统负载拉满了。你写了个脚本自动封IP,结果把自己的办公IP封了。
这种“越修越坏”的场景,才是自动运维真正的门槛。
ServerGuard的设计原则是:该出手时不犹豫,不该碰的不碰,不确定的交给你决定。 这篇文章拆解它的安全机制是怎么在代码层面落地的。
一、白名单机制:一个数组,一条死规矩 45+进程写死在白名单里,永远不杀:
Linux: systemd、sshd、nginx、httpd、apache2、mysqld、mariadbd、postgres、redis-server、mongod、php-fpm、php-cgi、bt-panel、pure-ftpd、vsftpd、named、postfix、dovecot、dockerd、containerd、cron、rsyslogd,以及ServerGuard自身。
Windows: System、smss.exe、csrss.exe、services.exe、lsass.exe、svchost.exe、w3svc、sqlservr.exe、mysqld.exe、postgres.exe、redis-server.exe、php-cgi.exe、nginx.exe,以及ServerGuard自身。
这个白名单不是配置文件里可以随便改的——它在代码层面强制生效。任何自动修复操作执行前,第一件事就是检查目标进程是否在白名单里。在,直接跳过。
二、11项安全检查链 每次自动修复执行前,必须通过11项检查:
- 目标进程是否在白名单 → 在则跳过
- 当前Kill次数是否超过预算(15次/小时)→ 超过则跳过
- 熔断器是否处于打开状态 → 是则跳过
- 系统CPU是否 > 95% → 是则进入存活模式,只告警
- 系统内存是否 > 95% → 是则降低操作优先级
- 目标是否是宝塔面板管理的进程 → 是则走特殊安全路径
- 操作类型是否触发级联防护 → 是则等待观察
- 是否处于维护窗口 → 是则跳过
- 是否处于开机保护期(开机5分钟内)→ 是则跳过
- 是否存在动作冲突(如磁盘满导致MySQL崩溃)→ 是则排序处理
- 全局紧急停止是否激活 → 是则全部跳过 任何一项不通过,操作不执行。 宁可不动,不做错事。
三、重启前配置预检 这是最容易被忽略但最关键的安全设计。
自动重启nginx之前,先跑nginx -t检查配置。配置有错就拒绝重启,服务保持原样至少还能跑。
同样的逻辑适用于:
Apache:apachectl configtest
SSH:sshd -t
预检不过,拒绝重启,并附上配置错误信息告警。
服务重启的优先级链:
reload(平滑重载,不断开现有连接)
restart(预检通过才执行)
启动后存活验证
四、重启风暴放弃机制 端口被占用时,重启100次也没用。
60秒内重启3次仍未恢复 → 判定重启无效 → 放弃30分钟 → 附自动诊断报告(systemctl日志尾部 + 端口被谁占用)。
不机械重试,不把系统拖垮。
五、级联防护 操作执行后,观察60秒。如果系统指标变差(CPU/内存/磁盘/网络任一恶化),停止后续操作。
Kill进程后,5分钟对比系统快照。系统更差则触发紧急停止。
核心思路:每次动手之后,先确认没搞坏,再决定要不要继续。
六、安全设计的取舍 为什么不用更“智能”的方案?
因为可解释性比智能更重要。自动运维场景下,每一步操作都必须能追溯到“为什么”。如果用了大模型来做决策,出了问题你根本无法复盘——“它觉得应该这样做”不是可接受的答案。
确定性规则 + 多层安全阀 = 可解释、可预测、可回滚。
七、总结 ServerGuard的安全设计本质上是把SRE的“信任但验证”原则工程化了:
信任:相信自动修复能解决问题
验证:11项检查链确保每次操作都是安全的
兜底:五层安全机制 + 一键急停
代码全部开源,白名单、检查链、熔断逻辑你都能在源码里找到。觉得哪个规则不对,直接改。
项目地址:
GitHub:suoten/ServerGuard
Gitee:suoten/ServerGuard