新主机开服 5 小时被扫 67 条记录,之后 9 天一条都没有

举报
逍遥渝枫 发表于 2026/11/04 08:35:47 2026/11/04
【摘要】 网上常说新云主机 24 小时会被扫上万次。我把一台华为云 ECS 三个多月的 sshd 与 ufw 丢弃日志按天摊开:67 条异常全在开服当天 5 小时内,之后 9 天零记录,ufw 拦下的 46 个包里 41 个打 3389。文中给出可直接复制的命令,解释日志行数为何不等于攻击次数、fail2ban 显示 0 次封禁为何不代表没人来,以及开服当天的四件事。

每次有人问"新买的服务器要不要马上加固",评论区总会出现一个数字:24 小时内被扫描上万次,不加固就是裸奔。

我手上有一台 2026-10-26 开的华为云 ECS,Ubuntu 22.04,1.7G 内存,公网 IP 直连。开服当天就做了 ufw 默认拒绝、SSH 只留密钥、fail2ban 三件套。三个多月过去,我把 sshd 的 journal 和 ufw 的丢弃日志按天摊开数了一遍,得到的曲线和那个"上万次"的说法完全对不上:67 条异常记录,全部落在开服当天 09:30 到 14:33 这 5 个小时里,之后 9 天一条都没有。

这篇文章不讲"要加固"这种正确的废话,只讲三件能验证的事:怎么自己量、量出来的数为什么会骗人、以及开服那天真正值得动手的地方在哪。

一、先明确观测点,否则数字没有意义

同一批扫描流量,在不同的位置看到的东西完全不同。这台机器上有三个位置能留下痕迹:

观测点 能看到什么 看不到什么
云平台安全组 所有被策略拒绝的包(在平台侧计数) 主机内部任何状态,日志不在机器上
ufw(netfilter) 到达网卡、被主机防火墙丢弃的包 安全组已经丢掉的包,一个字节都到不了这里
sshd 进程 TCP 建连之后的应用层行为(认证、KEX) 没连上的 SYN、被防火墙丢掉的包

所以"被扫了多少次"这个问题,答案取决于你问的是哪一层。我下面给的数,全部来自第三层和第二层,也就是主机自己记得的部分。这一点必须先说清楚,否则后面所有结论都会被误读。

二、实测:67 条记录,5 小时,16 个 IP

先看时间分布。这条命令是把所有"非正常登录"的行按日期归并:

# 按天统计 sshd 的异常行,先确认"从哪天开始、到哪天结束"
journalctl -u ssh --no-pager -o short-iso \
  | grep -E 'kex_exchange_identification|Connection closed by|Invalid user|Failed password' \
  | cut -c1-10 | sort | uniq -c

输出只有一行:

     67 2026-10-26

这台机器的 journal 是持久化的,最早一条能追到 7 月 31 日,所以"后面没有"不是被轮转吃掉了,是真的没有。

再看是谁来的:

# 按源 IP 归并。注意一次失败连接常留两行日志,这里的计数是"行"不是"连接"
journalctl -u ssh --no-pager \
  | grep -oE 'Connection closed by (authenticating user [a-z]+ )?[0-9.]+' \
  | grep -oE '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' \
  | sort | uniq -c | sort -rn | head -20

结果是 16 个不同的源地址,最多的是 195.178.110.232,出现 6 次,其中 5 次是这种形态:

Oct 26 13:18:30 hcss-ecs-7bdb sshd[8040]: Connection closed by authenticating user root 195.178.110.232 port 36408 [preauth]

[preauth] 说明它连认证阶段都没走完就断了。另外还有一批是这样的:

Oct 26 09:39:32 hcss-ecs-7bdb sshd[7687]: error: kex_exchange_identification: banner line contains invalid characters

这是扫描器直接把 HTTP 请求打到了 22 端口,sshd 等着收 SSH 版本号,收到的却是 GET / HTTP/1.1,于是报 banner 非法。这类流量在日志里根本不出现 IP,只有 error 行。

这里就是第一个陷阱:67 是日志行数,按 IP 归并后只有 28 行带源地址,16 个 IP。一次探测往往同时留下"kex 报错"和"Connection closed"两行,所以真实连接尝试大概在 30 次上下。把 67 当成"被攻击 67 次"是虚高,把 28 当成总数是虚低。

同一时间段,再看第二层,ufw 拦下的包:

# 按目标端口统计被丢弃的包,顺便看看扫描器最想敲哪个门
sudo zgrep -h 'UFW BLOCK' /var/log/ufw.log* \
  | grep -oE 'DPT=[0-9]+' | sort | uniq -c | sort -rn | head -10
     41 DPT=3389
      2 DPT=21
      2 DPT=20
      1 DPT=443

一共 46 个包。41 个打 3389(Windows 远程桌面),剩下是 FTP 的 20/21。这台是 Linux,从来没开过 RDP,但扫描器不知道,它按 IP 段批量扫常见端口,3389 的命中率最高,所以量最大。

有意思的是那 1 个 443:443 明明在 ufw 的放行列表里,为什么会被记成 BLOCK?看原始行就明白了:

[UFW BLOCK] ... PROTO=TCP SPT=61226 DPT=443 WINDOW=1200 RES=0x00 RST URGP=0

RST 而不是 SYN。这是一个不属于任何已建立连接的复位包,ufw 的放行规则接的是新连接,这种游离包匹配不上,落到默认 deny 上就记一条。同理,同一个 46.151.178.14 在 10-29 和 11-01 各留了一条一样的记录——并不是完全没人来敲门,是没人再来敲 22。

三、为什么"0 次失败密码"和"0 次封禁"都不代表安全

这台机器上有一条命令的输出很容易让人误判:

journalctl -u ssh --no-pager | grep -c 'Failed password'

返回 0。而 fail2ban 的状态是:

|- Filter
|  |- Currently failed:	1
|  |- Total failed:	1
`- Actions
   |- Currently banned:	0
   |- Total banned:	0

三个多月,累计失败 1 次,封禁 0 次。如果只看这两个数,结论会是"我这机器没人攻击"。真实原因是另一回事:

sudo sshd -T | grep -E '^(permitrootlogin|passwordauthentication|maxauthtries|logingracetime)'
permitrootlogin without-password
passwordauthentication no
maxauthtries 4
logingracetime 30

密码认证是关的。攻击者连"输密码"这一步都到不了——sshd 在密钥交换之后直接告诉对方可用认证方式是 publickey,对方要么放弃(留下 Connection closed ... [preauth]),要么硬发密码(直接协议层拒绝,不产生 Failed password 行)。fail2ban 抓的是 Failed password 这类模式,没有密码尝试,它就永远显示 0。 这不是它失灵,是它的输入没了。

这也解释了一个常见困惑:为什么装了 fail2ban 之后感觉"没起作用"。要么过滤器的输入被关掉了,要么攻击根本没走到那一层。要判断 fail2ban 是否真的在工作,别看封禁数,看它的过滤器有没有读到行:

# 确认 backend 走的是 systemd journal,且 jail 在监听正确的单元
sudo fail2ban-client status sshd
sudo fail2ban-client get sshd logpath
sudo journalctl -u fail2ban -n 30 --no-pager

这台机器上的配置是这样,backend = systemd 是 Ubuntu 22.04 上的关键项(默认的 /var/log/auth.log 在部分镜像里可能不存在或被 rsyslog 关掉):

# /etc/fail2ban/jail.local
[DEFAULT]
bantime  = 3600
findtime = 600
maxretry = 5
backend  = systemd

[sshd]
enabled = true
backend = systemd

改完 sudo systemctl restart fail2ban,再用 fail2ban-client status sshd 看 Journal matches 那一行,确认是 _SYSTEMD_UNIT=sshd.service。如果这里是空的,规则写得再漂亮也不会触发。

四、报错、成因与处理对照

下面这些是我在这台机器上真实撞到过的,按"看到什么 → 为什么 → 怎么办"排:

现象 原因 处理
grep -c 'Failed password' 返回 0,脚本里带 set -e 直接退出 grep 无匹配时退出码是 1,不是 0 用 grep -c ... || true,或把结果放进 $( ) 里赋值,别让退出码冒泡
fail2ban Total failed: 1 长期不动 密码认证已关闭,攻击者不产生 Failed password,过滤器没有输入 用 kex_exchange_identification 或 preauth 计数作为补充口径;或改 fail2ban 的 failregex 覆盖 preauth 断开
ufw status 显示 Logging: on (low),但 ufw.log 只有一行 low 级别只记部分被丢弃的包,且 logrotate 会切走历史 统计要看 /var/log/ufw.log*,用 zgrep 一并扫;排查期临时调 ufw logging medium,事后调回
443 明明放行,ufw.log 里却有 DPT=443 的 BLOCK 包带 RST 而非 SYN,不属于新连接,匹配不上放行规则 属正常现象,不用为它加规则;只要确认没有业务端口被误拦即可
journalctl -u ssh 只有几百行,以为日志丢了 主机日志量本来就小,加上轮转;Storage=persistent 才落盘 grep Storage /etc/systemd/journald.conf,必要时 persistent 并给 SystemMaxUse 上限
sshd -T 输出里 permitrootlogin 仍是 yes 改动写进了 sshd_config 主文件,被 sshd_config.d/*.conf 或 Include 覆盖 用 sshd -T 看生效值,不要看配置文件里写了什么

最后一条尤其值得记:sshd -T 是唯一可信的"当前生效配置",改完必须用它复核,而不是重读自己刚写的文件。

五、那么开服当天到底该做什么

对着上面这组数,我的结论是:不要追"被扫了多少次"这个数字,它既不可靠也不可行动。 该做的是把暴露面收到最小,然后保证自己有办法看见变化。四件事,按顺序:

第一,端口只留必须的。 默认拒绝入站,逐条放行:

sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp comment 'SSH'
sudo ufw allow 80/tcp comment 'HTTP'
sudo ufw allow 443/tcp comment 'HTTPS'
sudo ufw --force enable
sudo ufw status numbered

注意 Docker 的 -p 会绕过 ufw 直接写 iptables 的 DOCKER 链,这条在另一篇文章里单独写过,这里只提醒一句:容器端口映射必须在云平台安全组层面收口,别指望 ufw。

第二,SSH 只留密钥。 顺序很重要——先在新开的会话里确认密钥能登、sudo -n true 能过,再关密码登录,否则容易把自己锁在外面:

# /etc/ssh/sshd_config.d/99-hardening.conf
PermitRootLogin prohibit-password
PasswordAuthentication no
KbdInteractiveAuthentication no
MaxAuthTries 4
LoginGraceTime 30
sudo sshd -t && sudo systemctl reload ssh
# 另开一个终端验证能登上来之后,再继续
sudo sshd -T | grep -E '^(permitrootlogin|passwordauthentication|maxauthtries)'

第三,让日志能被复查。 这次能得出结论,靠的是 journal 持久化和 ufw 日志没被关掉。排查期把 ufw 日志级别提到 medium,看完调回 low,否则一条中等强度的扫描就能把磁盘写满——这跟 Docker 日志撑满磁盘是同一类问题,只是来源不同。

第四,别把 fail2ban 当主要防线。 它的价值是压掉持续爆破的噪音,不是挡住扫描。密码认证关掉之后,它对 SSH 的作用基本就没了;真要防爆破,密钥 + 端口收口 + 云平台安全组白名单,三件的收益都远大于调 maxretry。

六、边界

  • 数据来自单台实例:Ubuntu 22.04、ufw 0.36、fail2ban 0.11、华为云 ECS,观测窗口 2026-07-31 至 2026-11-04。样本量只有一台,不能推广成"所有云主机都这样"。
  • "之后 9 天零记录"只能证明这台主机没收到,不能证明没人扫。安全组和上游链路丢掉的包,主机侧一个字节都看不到,想拿到那部分数据只能去云平台的流量日志里找。
  • ufw 日志路径在 Debian/Ubuntu 系是 /var/log/ufw.log,RHEL 系用 firewalld,日志在 journal 里,zgrep 那条命令不通用。
  • 华为云安全组的默认规则、以及各区域对高危端口的处置策略会变,具体以控制台当前显示为准,本文不引用任何具体策略细节。

如果只能带走一句话:开服那 5 小时的密集探测是真的,但它会过去;真正决定这台机器安不安全的,是那 5 小时之后你有没有把门关小,而不是日志里那个吓人的数字。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。