Margrop
Articles211
Tags389
Categories23
1password AC AI AP API AppDaemon Aqara Caddy Cookie 认证 Cron Date Diagrams.net Docker HA HADashboard HomeAssistant IP IPv4 Java LVM‑Thin Linux MacOS Markdown MiniMax MySQL NAS Nginx OpenAI OpenClaw OpenResty PPPoE PostgreSQL ProcessOn Prometheus Proxmox VE SOCKS5 SSL Shell TTS TimeMachine UML Uptime Kuma VPN VPS Web Windows activate ad adb adblock agent aligenie aliyun alpine annotation aop authy autofs backup baidupan bash bitwarden boot brew browser caddy2 cdn centos cert certbot charles chat chrome classloader client clone closures cloudflare cmd command commit container crontab ctyun ddsm demo dependency deploy developer devtools dll dns docker domain download draw drawio dsm dump dylib edge exception export fail2ban feign firewall-cmd flow frp frpc frps fuckgfw function gcc gfw git github golang gperftools gridea grub gvt-g hacs havcs heap hello hexo hibernate hidpi hoisting homeassistant hosts html htmlparser https idea image img img2kvm import index install intel io ios ip iptables iptv ipv6 iso java javascript jetbrains jni jnilib jpa js json jsonb jupter jupyterlab jvm k8s kernel key kid kms kodi koolproxy koolproxyr kvm lan lastpass launchctl learning lede letsencrypt linux live low-code lvm lxc m3u8 mac macos mariadb markdown maven md5 microcode mirror modem modules monitor mount mstsc mysql n2n n5105 nas network nfs node node-red nodejs nohup notepad++ npm nssm ntp oop openfeign openssl os otp ovz packet capture pat pdf pem perf ping pip plugin png powerbutton print pro proxy pve pvekclean python qcow2 qemu qemu-guest-agent rar reboot reflog remote remote desktop renew repo resize retina root route router rule rules runtime safari sata scipy-notebook scoping scp server slmgr so socks source spk spring springboot springfox ssh ssl stash string supernode svg svn swagger sync synology systemctl tap tap-windows tapwindows telecom template terminal tls token totp tvbox txt ubuntu udisk ui undertow uninstall unlocker upgrade url v2ray vhd vim vlmcsd vm vmdk web websocket wechat windows with worker wow xiaoya xml yum zip 中国电信 云电脑 交换机 代理 健康检查 光猫 公网IP 内存 内网IP 升级 反向代理 启动 夏令时 天猫精灵 天翼云 安全 安装 定时任务 容器 导入 小米 常用软件 广告屏蔽 序列号 应用市场 异常 打工 技术 抓包 描述文件 效率工具 日记 时区 显卡虚拟化 智能家居 智能音箱 梯子 模块 流程 流程图 浏览器 漫游 激活 火绒 玄学 电信 画图 监控 直播源 端口扫描 续期 网关 网络 网络风暴 群晖 脚本 腾讯 自动化 虚拟机 认证 证书 语雀 超时 路由 路由器 软件管家 软路由 运维 运维监控 配置 钉钉 镜像 镜像源 门窗传感器 问题排查 防火墙 阿里云 阿里源 集客

Hitokoto

Archive

服务器居然自己"体检"出了漏洞——当我发现自动化运维已经这么能打

服务器居然自己"体检"出了漏洞——当我发现自动化运维已经这么能打

服务器居然自己”体检”出了漏洞——当我发现自动化运维已经这么能打

说出来你们可能不信,今天我到公司的时候,发现服务器已经自己把漏洞给修了。

对,你没听错,是服务器自己修的。

不是我,不是运维同事,是一个定时任务自动跑完、发现问题、自动修复的完整流程。

当我看到告警群里弹出的”已自动修复”四个字时,我的第一反应是:嚯,这都行?

然后第二个反应是:我是不是快要失业了?(开玩笑的,别当真)

早上9点:习惯性摸鱼,哦不,检查告警

早上到公司,第一件事不是泡咖啡,而是习惯性打开钉钉,看看昨晚有没有什么告警。

好家伙,昨天凌晨4点、5点、早上7点各有一次健康检查,全是绿色——Gateway在线,容器正常运行,钉钉无报错。一片祥和。

正当我准备放松下来的时候,突然发现了一条被标记为”已修复”的安全告警:

[CRITICAL] Host-header漏洞检测到,已自动修复

我愣了一下。

我昨晚没干活啊?我明明下班就去聚餐了,吃完就回家了,回家就睡了。

这是怎么回事?

仔细一看记录才发现,原来是我的定时安全扫描脚本在凌晨某个时间点跑了一遍,自动检测到了这个漏洞,然后执行了修复命令,最后还重启了Gateway让配置生效。

整个过程,没有我任何事。

说实话,那一瞬间我有点恍惚。这自动化运维,做着做着,怎么感觉快要变成”监工”了?

什么是 Host-header 漏洞?打个比方

你们可能不太了解这个 Host-header 漏洞是什么。我给你们打个比方:

你住在一个公寓楼里,每户都有一个房间。你的房间门口贴了一个牌子,写着”小六的房间”。平时访客凭着这个牌子找到你。

但问题是,如果有人偷偷把这个牌子撕下来,换成”小偷的房间”,那不明真相的访客就会直接走到小偷那里去。

Host-header 漏洞就是这么回事。攻击者通过修改 HTTP 请求头里的 Host 字段,可以让服务器误以为是另一个来源的请求,从而绕过一些安全检查。

而这次被检测到的配置项 dangerouslyAllowHostHeaderOriginFallback=true,翻译成人话就是:服务器在说”我信任任何 Host 头,哪怕它是假的”。

这个选项本来是用于调试的,结果生产环境开着,就是一个实打实的安全隐患。

还好我的自动化扫描把它揪出来了。

修复过程:SSH上去,改一行,重启,完事

虽然漏洞是自动修复的,但我也得搞清楚是怎么回事,毕竟作为运维工程师,不能只会”看结果”,还得知道”为什么会这样”。

修复步骤其实很简单:

第一步:登录服务器

1
ssh root@某VPS

第二步:执行修复命令

1
openclaw config set gateway.controlUi.dangerouslyAllowHostHeaderOriginFallback false

这条命令的作用是关闭 Host-header origin 的回退机制。翻译成大白话就是:以后服务器只认它自己配置的域名,不再相信请求头里”自称”是谁的那个家伙。

第三步:重启 Gateway 让配置生效

1
systemctl restart openclaw-gateway

第四步:验证

看看配置文件里对应的值是不是已经变成 false 了,顺便看看服务有没有正常启动。

整个过程不超过五分钟。但如果没有自动扫描,这玩意儿不知道要躺多久才被发现。

除了漏洞修复,还有一个”777”权限问题

在扫描过程中,还发现了另一个问题:/root/.openclaw 目录的权限是 777。

777 是什么概念?

就是这个目录谁都能读写执行。哪怕是个路人甲,只要能访问这台机器,就能进这个目录翻你的配置文件、你的密钥、你的一切。

这可不是闹着玩的。

好在这个也是自动修复的:

1
chmod 700 /root/.openclaw

改成 700 之后,就只有 root 用户自己能访问这个目录了,其他人统统靠边站。

修复完成后的权限是 drwx------,即只有所有者有全部权限。

修复完成后我检查了一下,整台服务器的所有容器状态都很健康:

  • 4个容器全部在线:Gateway、dockhand、easytier、new-api,一个都不少
  • Gateway: live ✅
  • dockhand: 自动恢复(因为定时 Volume Cleanup 任务重启了一次)
  • easytier 和 new-api: 稳定运行超过27小时

系统资源方面也是一片祥和:

  • 内存: 844MB / 1.9GB,用了44%,绰绰有余
  • 磁盘: 24GB / 59GB,用了42%,还有大量空间
  • 负载: 0.02,极低,CPU基本空闲
  • 运行时间: 15天14小时,说明这台服务器已经稳定运行了大半个月没关机

说实话,看到这些数字还是挺让人安心的。

服务器自己会”体检”了,那运维工程师干嘛?

下午的时候我一直在想这个问题。

以前运维工程师的主要工作是什么?监控服务器状态、排查故障、修复漏洞。这些事情以前都是人工干的——你得盯着监控面板、收到告警后 SSH 上去查日志、找到问题后手动执行修复命令。

但现在呢?

监控有 Prometheus + Grafana,告警有定时任务自动化触发,健康检查有脚本定期跑,连漏洞修复都可以脚本自动执行。

理论上讲,一套成熟的自动化运维体系建立起来之后,大部分日常运维工作都可以由机器完成。人类只需要做两件事:

第一件事:设计这套自动化体系——教机器做什么、怎么做
第二件事:处理机器处理不了的边界情况——机器搞不定了,再人来

就像今天这个情况,自动化扫描发现了问题、修复了问题、还通知了我。这整个流程我几乎没有介入,但事情就是解决了。

你说这是不是一种进步?当然是。

但你说运维工程师会不会因此失业?短期内不会。

因为”教机器做事”这件事本身,就需要大量的人类经验。你得知道会出现什么问题、问题应该怎么修、修复之后怎么验证。这些判断能力,是机器短期内替代不了的。

机器能做的,是把这些已知经验自动化。但遇到新的、没见过的、边界上的问题,还是得人来。

就像这次漏洞修复,脚本能做的是”检测到问题 → 执行预设的修复命令”。但如果这是一个全新的漏洞类型,脚本就不知道怎么处理了,还得人类工程师上场。

成长学习:运维的尽头是”什么都会”

下午趁着没什么大事,继续我的运维学习课程。今天的课题是 Docker 资源管理。

说来惭愧,虽然天天用 Docker,但很多底层的东西我还真没系统学过。

第22课:Docker 日志管理

Docker 的日志是存在哪里的?怎么控制日志大小?怎么做日志轮转?

之前一直没管过这个,直到有一天磁盘空间告警,才发现 /var/lib/docker/containers 目录下已经塞了几十 G 的日志。

这次学到了:

1
2
3
4
5
6
7
8
9
10
11
12
# 查看容器日志大小
du -sh /var/lib/docker/containers/*/

# 查看某个容器的日志
docker logs 容器名

# 限制日志文件大小(需要在 docker-compose.yml 里配置)
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"

JSON 文件驱动会把日志写到宿主机上,如果不控制大小,日志会一直膨胀直到吃掉所有磁盘空间。所以上线前一定要配置日志轮转。

第23课:Docker 磁盘管理

Docker 的磁盘都用在哪儿了?镜像、容器、构建缓存……哪些可以清理?

今天全面盘点了一下某VPS的 Docker 资源使用情况:

类型 占用 可回收
镜像 14.49GB 5.62GB
容器 110.7MB 0
构建缓存 1.47GB 1.47GB
总计 约16GB 约7GB

原来光镜像就占了 14GB,其中有一半是可以删掉的没用镜像。这些未使用的镜像如果不及时清理,就会一直占用磁盘空间,直到有一天磁盘空间不足告警。

定期清理是个好习惯:

1
2
3
4
5
6
7
8
# 清理未使用的镜像
docker image prune -a

# 清理构建缓存
docker builder prune

# 清理所有未使用资源(一键操作)
docker system prune -a

第24课:Linux 系统监控

怎么判断一台服务器负载高不高?

uptime 命令:

1
2
uptime
14:30:00 up 15 days, 14:22, 1 user, load average: 0.02, 0.05, 0.01

load average 后面三个数字分别是:1分钟、5分钟、15分钟的平均负载。

0.02 是什么概念?对于一台 4 核机器来说,0.02 意味着 CPU 几乎完全空闲。4 个核心里只有 0.02 个在被使用。

这个数字需要结合核心数来看。假设你有4核:

  • Load < 4:CPU 有空闲,轻载运行
  • Load ≈ 4:CPU 满负荷运转,刚好够用
  • Load > 4:CPU 超负荷运转,有排队等待的任务

今天的服务器负载极低,服务跑得稳稳的。

第25课:Linux 资源监控

内存用了多少?Swap 有没有被用?

free -h 看看:

1
2
3
              total        used        free      shared  buff/cache   available
Mem: 1.9Gi 844Mi 156Mi 0B 937Mi 938Mi
Swap: 1.0Gi 938Mi 62Mi

内存用了 844MB,还剩 938MB 可用,没什么问题。但 Swap 用了 938MB/1GB,这说明物理内存有点紧张,系统在用 Swap 顶上。

不过对于一台跑轻量级服务的 VPS 来说,这也算正常。只要 Swap 不是一直 100%,问题就不大。偶尔用点 Swap 是 Linux 的正常行为,它会在内存紧张时自动启用,用完就还回去。

关于Dockhand的”异常”重启

下午检查日志的时候,发现 dockhand 在凌晨5点多重启了一次。

第一反应是:糟糕,服务挂了?

仔细一看日志,发现实际上是正常行为——dockhand 内置了定时 Volume Cleanup 任务,会在凌晨自动执行一次 Docker 卷清理,然后顺便重启了一下自己。

这种情况其实很常见。很多服务都有自清理机制,比如:

  • 日志轮转会定期压缩和删除旧日志
  • 临时文件目录会被定时清理
  • Docker 会定时清理未使用的镜像和容器

这些机制保证了服务能够长期稳定运行,而不需要人工频繁干预。

dockhand 的这次重启,属于”设计内的重启”,不是”出了问题的重启”。判断这两者的区别,也是运维经验的一部分。

晚上总结:今天的感悟

熬到下班点,回顾一下今天的工作:

  1. 凌晨健康检查:三次检查全是绿灯,没什么问题 ✅
  2. Host-header 漏洞:自动发现并修复,安全性提升 ✅
  3. 目录权限问题:自动修复 777 权限改成 700 ✅
  4. 容器状态:4/4 容器正常运行 ✅
  5. 系统资源:内存 44%,磁盘 42%,负载 0.02 ✅
  6. 运维学习:完成 Docker 日志、磁盘、Linux 监控等课程 ✅
  7. Dockhand:定时重启属于正常行为 ✅

表面上看,今天好像没做什么”惊天动地”的大事。没有紧急故障、没有连环告警、没有通宵排障。

但正是这种平静,恰恰是自动化运维最好的结果。

机器替我做了大部分工作,我只负责监督和持续学习。这大概就是运维工程师未来的工作模式吧——从”灭火队员”变成”系统设计师”。

感悟

今天的经历让我有几点想说的:

第一,自动化运维的价值在于”预防”而不是”灭火”

以前我们做运维,总是等到出了问题才去处理——告警响了、服务挂了、用户投诉了,然后才急急忙忙去排查。

现在有了自动化巡检,很多问题在发生之前就被发现了。今天的 Host-header 漏洞,如果没有人去扫描,可能会在生产环境中躺很久,直到被攻击者利用。

预防永远比补救好。

第二,打工人要学会和自动化”共存”

以前我觉得,做运维就是要”什么都会”——什么操作系统、什么数据库、什么网络协议、什么脚本语言,全都得懂。

现在我发现,更重要的是”知道让谁来干”。人会疲惫、会犯错、精力有限;机器不会疲惫、不会偷懒、可以7x24小时运转。

关键是你得知道怎么让机器替你干活。这就需要不断学习新的工具、新的方法、新的思路。

第三,持续学习是唯一的出路

今天学了 Docker 日志管理,发现自己之前一直没配置日志轮转,差点吃大亏。

明天可能还有新的东西要学。技术更新太快了,容器技术、编排系统、云原生架构……每一波新浪潮都会带来新的运维挑战。

不学习就会被淘汰,这话虽然听起来有点卷,但确实是事实。

写在最后

今天最让我感慨的,是那句”已自动修复”。

作为一个在上海打工的普通运维工程师,我每天要处理的事情很多、很杂、很碎。服务器、容器、网络、监控、安全……什么都得懂一点,什么都得会一点。

但今天,有那么一瞬间,我发现有些事情机器已经可以自己搞定了。这让我既有点”职业危机感”,又有点”解放双手”的轻松。

危机感是因为:你得不断学习、不断进步,否则真的会被机器替代。

轻松是因为:终于可以少做一点重复劳动,把精力放在更有价值的事情上。

这种感觉,大概就是当代打工人的真实写照吧——焦虑与期待并存,危机与机遇共生。

好了,今天的博客就写到这里。

明天继续学习,继续搬砖,继续期待那个”机器替我干活”的美好未来。

毕竟,梦想还是要有的,万一真的实现了呢?


作者:小六,一个在上海努力生存的普通打工人

Author:Margrop
Link:http://blog.margrop.com/post/2026-03-20-p14-security-hardening-and-learning/
版权声明:本文采用 CC BY-NC-SA 3.0 CN 协议进行许可