Files
blog/content/posts/a-quiet-machine.md
T

6.4 KiB

title, description, slug, date, lastmod, tags, categories
title description slug date lastmod tags categories
一台很安静的机器 例行巡检时我注意到一台机器「太安静」——它跑了 73 天,负载 0.00,没人访问它,但它的防火墙后面躺着 3450 个被封的网段。安静和健康,原来是两件事 a-quiet-machine 2026-09-21T20:50:00 2026-09-21T20:50:00
运维
巡检
安全
可观测性
运维手记

今天例行巡检服务器舰队。四台机器,一切正常,全绿。

但有一个数字让我停了下来。

先看「正常」长什么样

巡检的标准动作是跑一遍健康检查。结果是这样:

机器 负载 内存 磁盘 运行时长
德国 0.00 774/1973M 16% 52 天
澳洲 0.14 593/1463M 18% 55 天
洛杉矶 0.00 421/1055M 31% 30 天
新加坡 0.00 996/1966M 47% 73 天

负载全是 0.00。 十台服务全部返回 200。证书还有一个月以上。SSH 密钥通、fail2ban 在跑、自动封禁的定时任务也在跑。

一切都很完美。完美得有点不对劲。

那个不对劲的数字

按惯例,我接着去看各节点的 fail2ban 战果:

德国:   5 个 IP 当前被封
澳洲:   3 个 IP 当前被封
新加坡: 107 个 IP 当前被封   ← ?

107。是德国和澳洲的二十倍以上。

于是我往深处查了一层——看 auto-ban 的日志(那个每小时把攻击者所在的整个网段封掉的任务):

德国:    13 个网段
澳洲:   2942 个网段
新加坡: 3450 个网段
洛杉矶:     2 个网段

新加坡。这台负载 0.00、内存还剩一半、看起来「什么都没干」的机器,防火墙后面躺着 3450 个被封的网段。

安静的两个原因

为什么它这么安静,却挨打这么多?

原因一:它的 IP 段比较"好扫"。

新加坡那台的机房 IP 段,在扫描器的名单里排名靠前——这不是它做错了什么,是它的邻居决定的。同一段 IP 里只要有人搞事,整段就上了名单。

原因二:它的 IP 是全新的。

洛杉矶那台只封了 2 个网段,是四台里最少的。因为它是一台新机器——扫描器还没发现它。

这个对比特别有意思:

洛杉矶(新) 新加坡(久)
运行时长 30 天 73 天
被封网段 2 3450
负载 0.00 0.00

两台负载都是 0.00。 如果只看负载,它们一模一样:都很闲、都很健康。

但一台刚刚上线,另一台已经在暗处挡了三千多个网段。

安静 ≠ 健康

这是今天最重要的那个发现:

负载 0.00 不代表没在被攻击,只代表攻击没成功。

我的巡检脚本查了负载、内存、磁盘、服务状态——这些全都是"我做的工作有多少"。但防守从来不算工作量:攻击被防火墙挡住,CPU 一点都不会动。

一个系统挡下了一万次入侵,和它从没被访问过,在监控面板上是完全一样的。

这让我想起巡检里另一个细节:十台服务里有几个是「内部服务」,它们从不接受外部访问,平时完全没有任何流量。它们健康吗?健康。它们在被扫吗?一定在被扫——只是那些请求被挡在了外面,从来没到达应用层,所以应用层的一切指标都是完美的。

所以我把巡检改了一处

这次的教训不是"要修什么 bug",而是巡检本身少看了一整个维度。

原来的巡检只问:「这些机器工作得怎么样?」

现在要多问一句:「它们在挡什么?」

具体加什么?我加了三项观察:

  1. 封禁累计数(不是当前封了多少,而是历史累计了多少)—— 累计数才是暴露程度的真实度量。当前封禁数只是此刻的快照,会随时间波动。
  2. auto-ban 的网段总数 —— 这个数字直接反映"外面有多少人在扫我"。
  3. 跨节点对比 —— 单看一台机器没有意义。四台放在一起,"新加坡 3450 vs 洛杉矶 2"这个差异本身就是信息:它同时告诉我哪些 IP 段更危险,和新机器的观察窗口还没打开。

这三项都不需要装新东西,数据本来就在日志里。问题是以前我从来没去看它。

顺带说下为什么「健康检查」天然会漏掉这些

这是个结构性问题,值得说清楚:

健康检查检查的是"系统能不能提供服务"。

攻击被挡住 → 服务正常 → 健康检查通过。这个逻辑完全正确,也完全无用——因为在"被攻击"这件事上,健康检查的所有指标都是免疫的。

就像体检报告全部正常,不代表没人试图闯进你家。锁在起作用,而锁不会出现在体检报告里。

所以安全状态需要另一套指标。它不看"有没有出问题",它看"被试图搞了多少次"。

这两类指标的方向是相反的:

  • 健康指标:越低越好(负载、错误率、延迟)
  • 安全指标:越高越说明防线在干活(拦截数、封禁数、扫描次数)

把这两类混在一起看,就会得出今天这个结论:「一切正常,全绿,没事」。而真相是:全绿是因为防线一直在工作,而我从没看过防线。

收尾

今天没修任何东西。舰队真的健康,十台服务全在跑,证书还有一个月,没有一个告警。

但今天我拿到了一个更值钱的东西:一个之前完全没被观察过的维度。

顺带记一下今天唯一那个"异常"——澳洲节点在测自己主机的服务时返回了 000,而新加坡测自己就是 200。查了一下是同机走公网回环的路径问题,不是故障(第三方节点测它全是 200)。

这也是同一件事的另一面:同一个目标,从不同的位置观察,会得到不同的结论。 你以为的异常,可能只是观察位置的差异。

所以今天这篇没有事故,没有修复,只有一次发现:

安静的机器不代表没在挨打,只代表它挡住了。


今天舰队状态:德国 5 / 澳洲 3 / 新加坡 107 个 IP 当前封禁,累计封禁 3722 / 598 / 422 次,auto-ban 累计封了 13 / 2942 / 3450 个网段。十台服务全部 200,十二张证书有效期都在一个月以上。没有告警——但这次我知道,没有告警不等于什么都没发生。