公网云服务器半年没管,会变成什么样:一次强迫症级体检实录
摘要:一台跑了半年的某云服务商 4G 轻量服务器,从「OpenClaw 把自己 kill -9 没拉起来」开始,顺手做了一次完整体检。文章覆盖四块:SSH 暴露面、系统补丁积压、内存瓶颈、磁盘垃圾,以及「不交出私钥让 AI 助手登服务器」「Let's Encrypt 自动化续证书」「AccessKey 90 天政策解读」三个配套可复用的运维模式。
故事的起点
那天只是想确认一下 OpenClaw 的升级有没有做干净,结果发现它昨天自己执行了两次 kill -9,第二次卡在 restart drain 阶段就再没起来。重启之后我顺手让它做了一次「稍微详细一些」的全面评估——从磁盘、内存、服务版本到安全配置逐项过了一遍。
报告出来之后,问题密度比预想高得多。于是我把这次体检的过程、发现和补救整理成这篇文章,希望能给同样「服务器跑了大半年没动」的读者一份参考清单。
一、不交出私钥,让 AI 助手登服务器
在开始体检之前,先解决一个前置问题:怎么让 AI 助手能登服务器,又不把我的私钥交出去。
常见的几个方案我对比过:
- 共享私钥:直接把私钥文件给 AI,不推荐,密钥外泄风险太高
- SSH Agent:把已有私钥
ssh-add加载进 agent,AI 通过 agent 代签。缺点是 agent 重启要重新加载 - 端口隧道:手动起一条
ssh -L隧道,AI 只访问 localhost。缺点是只能转发端口,不能让 AI 在服务器上执行命令 - 专用密钥对(我最终选的):AI 在自己跑的那台机器上生成一对专用的 ed25519 密钥对,把公钥发给我,我在服务器
~/.ssh/authorized_keys里追加这一行
专用密钥对方案有几个关键优点:
- 公钥不是秘密,可以贴给任何人看,私钥永远不离开 AI 运行的那台机器
- 随时可吊销:回收权限 = 服务器上删掉一行
- 与你已有的密钥完全隔离:即使这套专用密钥泄露,也不影响你日常使用的密钥对
- 可以加限制:在
authorized_keys里可以加no-agent-forwarding、from="某 IP"等选项
实际操作就是一条命令的事:在我自己的 PowerShell 里把公钥文件 cat 出来,pipe 给 ssh 在服务器上追加。弄完之后 AI 就可以用 ssh ubuntu@<我的域名> 直接登录,全程我没给过任何私钥内容。
这个模式适合所有需要让某个工具(不一定是 AI)登录你服务器的场景。
二、半年没管的服务器,体检发现了什么
1. SSH 暴露面:半年累计近九千次密码爆破
这是最严重的一项。检查 auth.log 发现:
- UFW 防火墙根本没启用,所有端口直接暴露在公网
- sshd 同时允许 root 登录 + 密码登录
- 半年累计 8876 次密码爆破失败记录,平均每天 46 次
- fail2ban 没有安装
目前还没被攻破,只是因为我的用户密码强度还行 + 攻击者还在字典试。但这种状态如果再持续半年,被攻破的概率会指数级上升。
防护方案(按优先级):- 安装 fail2ban(自动封禁多次失败 IP)
- 关闭 sshd 密码认证,只保留密钥登录
- 启用 UFW,只开放需要的端口
- 可选:把 SSH 端口从 22 改到非标准端口(降低被扫到的概率)
2. 系统补丁:247 个待升级
apt list --upgradable 显示有 247 个包待升级,其中包含若干安全更新。
unattended-upgrades 在跑,但只覆盖部分自动安全更新(CVE 级别),大量包仍需手动 apt upgrade。这是 Ubuntu 默认配置的局限:稳定性优先,安全更新滞后。
建议:每季度跑一次 apt upgrade,重大安全公告发布时主动 apt update && apt upgrade。
3. 内存压力:第一个未来的瓶颈
机器规格是 4G 内存,当前状况:
- 总内存 3.6G,已用 2.7G
- OpenClaw 的 node 进程峰值 1.7GB(接近 2G 的 max-old-space 上限)
- 可用内存只剩 900M
- swap 已用 760M
平时能跑,但 OpenClaw 高峰 + Halo Java 同时吃内存时,随时可能触发 OOM 或者明显的卡顿。暂时不需要扩容,但未来如果想加任何服务,内存会是第一个瓶颈。
预判方法:用ps aux --sort=-%mem | head 看 top 内存进程,结合 free -h 看 swap 是否在持续增长。
4. 磁盘垃圾:3.4G 可清理
| 项目 | 大小 |
|---|---|
| systemd journal 日志 | 1.7G(默认无上限堆积) |
| ~/.npm 缓存 | 763M(历次升级 OpenClaw 积累) |
| 未使用的 docker 镜像 | 约 1G |
sudo journalctl --vacuum-size=500M
rm -rf ~/.npm/_cacache
docker image prune -a
三、配套案例:Let's Encrypt 自动续期 + 自动部署到群晖 NAS
体检期间发现另一个更糟心的问题:另一台群晖 NAS 上的 SSL 证书用的是某云服务商免费证书(3 个月手动续),已经过期 4 个月了才被发现。
不能再这样手动续。决定落地一个全自动方案:
技术选型
- acme.sh:轻量 shell 实现的 ACME 客户端
- DNS-01 验证:因为我的域名走花生壳内网穿透(没有公网 IP 直指 NAS),HTTP-01 验证(需要 80 端口可达)不可靠,DNS-01 只用 API 在 DNS 上加一条 TXT 记录就完事
- 某云服务商 DNSPod API:我的 DNS 托管在 DNSPod,直接用 API 自动加/删验证记录
- acme.sh 的
synology_dsm部署钩子:签发后一条命令自动导入 DSM、设为默认证书、重启相关服务
自动化链路
cron (每天 3:30)
↓
acme.sh --renew
↓ 续期成功
↓ 调用 synology_dsm 钩子
↓ 自动导入 DSM + 设为默认 + 重启 webserver
踩过的坑
- DSM 现有证书已过期导致 curl 拒绝连接:部署钩子里要加
HTTPS_INSECURE=1(已写进 crontab 环境) - 新证书导入后默认证书不切换:DSM 的命令行删除接口有限制,最后改用「按旧证书名字原地替换」让新证书继承默认身份和全部服务绑定
当前状态
新证书 Let's Encrypt,CN 是我的域名 + www 子域,有效期 3 个月,60 天自动续期,certbot/acme.sh timer 活跃,零人工。
四、配套案例:AccessKey 90 天自动禁用政策,会影响我吗?
某云服务商 2025 年 6 月发的公告:「连续 90 天零调用的 AccessKey 会被自动禁用」。
我的 NAS acme.sh 自动化用的是最小权限子账号密钥(只勾了 QcloudDNSPodFullAccess),担心会踩到这个政策。
简单算一下
- 续期周期:每 60 天一次
- 每次续期:DNS-01 验证加/删 TXT 记录都要调 API,至少有 2 次调用
- 60 天 ≤ 90 天阈值 → 永远不会触发禁用条件
真正要防的两个风险
1. 续期连续失败 + crontab 同时失效 90 天理论上如果 acme.sh 续期一直失败、crontab 又不跑,会出现「0 调用」。但 acme.sh 每天 cron 都跑,失败也会重试,每次重试都是 API 调用,实际很难凑出 90 天完全零调用。
2. DSM 系统升级会重置/etc/crontab(更现实的风险)
群晖大版本更新时自定义的 cron 条目可能被冲掉,续期静默停摆,直到证书再次过期才发现。这跟某云服务商政策无关,但更值得防。
防护建议
- 每季度看一眼
/var/log/acme_renew.log - DSM 升级后检查一次
/etc/crontab里 acme.sh 那行还在不在 - 进阶:加一个「证书到期检查」脚本,发现证书剩余 < 30 天但续期失败时通过飞书机器人告警
五、给读者的可复用 checklist
把这次体检的发现抽象成一份清单,下次给任何公网服务器做体检都可以照着过:
- SSH 暴露面
cat /var/log/auth.log | grep "Failed password" | wc -l— 看爆破次数ufw status— 看防火墙是否启用grep -E "^(PermitRootLogin|PasswordAuthentication)" /etc/ssh/sshd_config— 看 sshd 关键配置systemctl status fail2ban— 看 fail2ban 状态
- 系统补丁积压
apt list --upgradable | wc -l— 看待升级包数量systemctl status unattended-upgrades— 看自动更新是否在跑
- 内存瓶颈
free -h— 看 swap 是否在用ps aux --sort=-%mem | head -5— 看 top 内存进程
- 磁盘垃圾
journalctl --disk-usage— journal 占用du -sh ~/.npm— npm 缓存docker system df— docker 占用
- 证书生命周期
- 列出所有外网服务的证书 + 有效期 + 自动续期是否真的在跑
- 把每个 AccessKey / Token 的使用频率对照闲置政策算一遍
- agent 自管理风险
- 任何能在服务器上执行
kill -9的工具,都应该被审计「能 kill 自己」这件事
写在最后
半年不管一台公网服务器,它不会自己变安全,但也不会立刻崩——会慢慢地、持续地、往「迟早出问题」的方向漂移。
这次体检最大的收获不是修了多少问题,而是把「服务器长期无人值守」这件事的风险模型建立起来了。下次再遇到类似情况,我有现成的 checklist 跑一遍。
以及,让任何 agent(包括你自己写的脚本)拥有对自己 kill -9 的权限,本身就是个设计漏洞。这次 OpenClaw 就是这么把自己搞挂的。