序:发现黑客还在攻击

2026 年 5 月 29 日,在排查系统 CPU 发热问题时,我惊讶地发现:黑客仍在持续攻击我的电脑!

今日 SSH 暴力破解尝试:293 次
攻击来源:通过 rathole 隧道 (your-server-ip:2334)
被尝试用户名:ubuntu, test, root, centos, dell, user...

更令人担忧的是,服务器端的安全配置仍然不完善:

问题状态
SSH 允许密码登录
SSH 允许 root 登录
无 fail2ban 防护
防火墙未启用

这说明之前的修复只是“头痛医头”,没有从根本上解决问题。攻击者仍在尝试,我们的防线仍有漏洞。

于是,我决定进行一次全面的安全加固。

系统架构

本次事件涉及三台主机,都通过 rathole 隧道将 SSH 服务暴露到公网:

┌─────────────────────────────────────────────────────────────┐
│                      家中局域网                              │
│  ┌─────────────┐    ┌─────────────┐                        │
│  │   主机 A    │    │   主机 B    │                        │
│  │  (WSL2)     │    │   (Mac)     │                        │
│  │  SSH 服务   │    │  SSH 服务   │                        │
│  └──────┬──────┘    └──────┬──────┘                        │
│         │                  │                                │
│         └────────┬─────────┘                                │
│                  │ rathole 隧道                             │
│                  ↓                                          │
│         ┌──────────────┐                                   │
│         │   服务器     │                                   │
│         │ (your-server-ip)│                                 │
│         └──────┬───────┘                                   │
│                ↓                                            │
│            公网访问                                         │
└─────────────────────────────────────────────────────────────┘
  • 主机 A:主要受害者,被入侵并植入矿机
  • 主机 B:次要风险点,SSH 也暴露在公网
  • 服务器:运行 rathole 服务,转发流量

一、原始入侵事件(2026-05-23)

事件概述

WSL 通过 rathole 内网穿透将 SSH 暴露到公网(非标准端口)。5 月 22 日晚,攻击者通过字典暴力破解 test 用户的弱密码,成功登录并植入门罗币矿机。到 5 月 23 日凌晨被发现时,矿机已满负荷运行约一天,占用 2.4 GiB 内存。

攻击路径

公网扫描器 → 公网入口:非标准端口 (rathole 穿透)
            WSL SSH (内网)
                  ↓ 字典爆破
            test 用户 (弱密码)
            部署矿机 + crontab 后门

受害程度

项目情况
矿机进程伪装成 systemd-udevdar,吃满 CPU(1062%),占 2.4 GiB 内存。疑似 XMRig/RandomX 挖门罗币
后门crontab @reboot /var/tmp/.sys_cache_94(清理时空文件,未部署完)
密码攻击者登录后立刻改了 test 密码
API Key 泄露~/.bashrc 中 DeepSeek API Key 明文存储,可能被窃取
数据无法确认攻击者是否读取/拷贝了文件

漏洞清单(入侵时状态,已全部修复)

#问题严重度当前状态
1SSH 允许密码登录 - 根本原因🔴✅ 已禁用
2test 账户密码太弱 - 字典一撞就进🔴✅ 已锁定
3多余系统账户 - 系统中存在不止一个弱密码的非核心账户🟡✅ 已清理
4非标准端口不防扫描 - 全端口扫描不挑端口号🟡✅ 已加固
5无 fail2ban - 1412 次失败尝试无任何自动阻断🟡✅ 已安装
6API Key 明文放 bashrc - 被入侵即泄露🟡✅ 已吊销

首次修复措施

# 1. 关闭密码登录(全局,所有用户)
sudo sed -i 's/^PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
sudo systemctl restart sshd

# 2. 锁定失陷账户
sudo passwd -l test

# 3. 杀掉恶意进程
sudo pkill -KILL -u test

# 4. 清除 crontab 后门
sudo rm /var/spool/cron/crontabs/test

# 5. 删除后门脚本
sudo rm /var/tmp/.sys_cache_94

二、持续攻击发现(2026-05-29)

发现过程

5 月 29 日,在排查系统 CPU 发热问题时,通过检查 SSH 日志发现了持续的暴力破解攻击:

# 检查攻击日志
grep "Invalid user" /var/log/auth.log | grep "2026-05-29" | wc -l
# 输出:293

攻击详情

时间范围:14:45 - 18:20(约 3.5 小时)
攻击频率:每 30-60 秒一次
攻击来源:通过 rathole 隧道,显示为 127.0.0.1
被尝试用户名:ubuntu, test, root, centos, dell, user, vq, pq, ba, qg, ii, eq...

服务器端安全问题

# 检查服务器SSH配置
ssh root@your-server-ip "grep -E '^(PermitRootLogin|PasswordAuthentication)' /etc/ssh/sshd_config"

# 输出:
PermitRootLogin yes        # ❌ 危险!
PasswordAuthentication yes # ❌ 危险!

分析:为什么首次修复不完整?

问题原因
只修复了客户端服务器端(your-server-ip)配置仍不安全
无自动封禁机制fail2ban 未安装,攻击者可以无限尝试
无用户限制没有 AllowUsers 配置,所有用户都暴露
Mac 未加固Mac 的 SSH 也通过 rathole 暴露,且无安全配置

三、全面安全加固(2026-05-29)

3.1 客户端(本机)加固

安装 fail2ban

# 安装
sudo apt install -y fail2ban

# 配置
cat > /etc/fail2ban/jail.local << 'EOF'
[DEFAULT]
bantime = 86400
findtime = 600
maxretry = 3

[sshd]
enabled = true
port = ssh
filter = sshd
backend = systemd
journalmatch = _SYSTEMD_UNIT=ssh.service + _COMM=sshd
maxretry = 3
bantime = 86400
findtime = 600
EOF

# 启动
sudo systemctl enable fail2ban
sudo systemctl start fail2ban

SSH 配置加固

cat > /etc/ssh/sshd_config.d/hardening.conf << 'EOF'
# SSH加固配置
MaxStartups 3:50:10
MaxSessions 3
MaxAuthTries 3
LoginGraceTime 30
AllowUsers your-username
PasswordAuthentication no
PermitRootLogin no
EOF

sudo systemctl restart sshd

3.2 服务器端(your-server-ip)加固

⚠️ 配置冲突问题

服务器默认配置存在冲突,需要先修复:

# 检查配置
ssh root@your-server-ip "grep -E '^(PasswordAuthentication|PermitRootLogin)' /etc/ssh/sshd_config /etc/ssh/sshd_config.d/*.conf"

# 输出示例(存在冲突):
# /etc/ssh/sshd_config:PermitRootLogin yes          ❌ 覆盖 hardening.conf
# /etc/ssh/sshd_config:PasswordAuthentication yes    ❌ 覆盖 hardening.conf
# /etc/ssh/sshd_config.d/50-cloud-init.conf:PasswordAuthentication yes  ❌ 覆盖 hardening.conf
# /etc/ssh/sshd_config.d/hardening.conf:PermitRootLogin prohibit-password  ✅ 被覆盖
# /etc/ssh/sshd_config.d/hardening.conf:PasswordAuthentication no          ✅ 被覆盖

问题:sshd_config50-cloud-init.conf 中的配置会覆盖 hardening.conf 的配置。

修复方法:

# 1. 注释掉 sshd_config 中的冲突配置
sed -i 's/^PermitRootLogin yes/#PermitRootLogin yes/' /etc/ssh/sshd_config
sed -i 's/^PasswordAuthentication yes/#PasswordAuthentication yes/' /etc/ssh/sshd_config

# 2. 注释掉 50-cloud-init.conf 中的冲突配置
sed -i 's/^PasswordAuthentication yes/#PasswordAuthentication yes/' /etc/ssh/sshd_config.d/50-cloud-init.conf

# 3. 重启 SSH 服务
systemctl restart ssh

安装 fail2ban

# 连接服务器
ssh root@your-server-ip

# 安装 fail2ban
apt install -y fail2ban

# 配置 fail2ban
cat > /etc/fail2ban/jail.local << 'EOF'
[DEFAULT]
bantime = 86400
findtime = 600
maxretry = 3

[sshd]
enabled = true
port = ssh
filter = sshd
backend = systemd
journalmatch = _SYSTEMD_UNIT=ssh.service + _COMM=sshd
maxretry = 3
bantime = 86400
findtime = 600
EOF

systemctl enable fail2ban
systemctl start fail2ban

SSH 加固

cat > /etc/ssh/sshd_config.d/hardening.conf << 'EOF'
MaxStartups 3:50:10
MaxSessions 3
MaxAuthTries 3
LoginGraceTime 30
PasswordAuthentication no
PermitRootLogin prohibit-password
EOF

systemctl restart sshd

3.3 Mac 加固

# 禁用密码登录
sudo sed -i '' 's/#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config

# 禁止root登录
sudo sed -i '' 's/#PermitRootLogin prohibit-password/PermitRootLogin no/' /etc/ssh/sshd_config

# 测试配置
sudo sshd -t

# 重启SSH
sudo launchctl stop com.openssh.sshd
sudo launchctl start com.openssh.sshd

四、安全等级对比

防护体系演进

维度入侵前首次修复后全面加固后
整体安全🔴 高危🟡 中等🟢 安全
暴力破解防护❌ 无⚠️ 基础✅ fail2ban 自动封禁
密码认证⚠️ 允许⚠️ 部分禁用✅ 全部禁用
用户限制❌ 无⚠️ 部分✅ AllowUsers
连接限制❌ 无❌ 无✅ MaxStartups
服务管理⚠️ 手动⚠️ 手动✅ systemd 自动重启
Mac 防护❌ 无❌ 无✅ 完整加固

当前防护体系

攻击者
服务器 (your-server-ip)
fail2ban → 3次失败 → 封禁24小时 ✅
SSH加固 → 密码禁用 → 无法暴力破解 ✅
rathole隧道
客户端SSH
AllowUsers → 只允许your-username ✅
✅ 安全

五、验证结果(2026-05-31)

实际验证

客户端(Windows WSL2)

验证项测试方法结果
SSH 密码登录被拒绝ssh -o PubkeyAuthentication=no test@127.0.0.1Permission denied (publickey)
root 登录被拒绝ssh root@127.0.0.1Permission denied (publickey)
AllowUsers 配置生效用 test 用户尝试登录not allowed because not listed in AllowUsers

服务器端(your-server-ip)

验证项测试方法结果
SSH 密码登录被拒绝ssh -o PubkeyAuthentication=no root@your-server-ipPermission denied (publickey)
普通用户密码登录被拒绝ssh -o PubkeyAuthentication=no your-username@your-server-ipPermission denied (publickey)
配置冲突已修复检查配置文件sshd_config50-cloud-init.conf 已注释冲突配置 ✅
fail2ban 服务运行systemctl status fail2banactive
fail2ban 监控日志fail2ban-client status sshdFile list: /var/log/auth.log

理论可行(未实际触发)

验证项理论依据
fail2ban 自动封禁配置正确:maxretry=3, bantime=86400, findtime=600。filter 规则匹配 “Invalid user” 和 “not allowed” 模式。需 3 次失败触发封禁。

fail2ban 工作原理

攻击者尝试登录
sshd 记录日志到 journal(_SYSTEMD_UNIT=ssh.service)
fail2ban 读取 journal 日志(backend = systemd)
filter 匹配失败模式("Invalid user" / "not allowed")
累计失败次数(maxretry = 3)
超过阈值 → 封禁 IP(bantime = 86400)

六、核心教训

1. 安全不靠隐藏,靠密钥

换端口是障眼法。masscan/zmap 这类工具可以在几分钟内扫描整个 IPv4 的指定端口段–攻击者不需要知道你的具体端口,扫一遍全网就全出来了。非标准端口只是少了一些噪声级别的攻击,真正的扫描器照样能找到。只有禁用密码、强制密钥认证能真正挡住。

2. 每一个系统账户都是入口

系统上有多个用户(包括一个弱密码的 test)。攻击者试到 test 就成了。任何暴露到公网的服务,所有本地用户都同时暴露在攻击面下–只要有一个密码弱,整个系统就门户大开。

3. 公网暴露 = 零信任

rathole 把内网服务直接映射到公网,等同于把 SSH 直接放到互联网上。必须假设公网流量 100% 是恶意的。

4. 被入侵后要查持久化

攻击者做了三件事:矿机、改密码、留 crontab。如果只杀进程不动 crontab,重启矿机又复活。排查时至少检查:

  • crontab -l / /var/spool/cron/crontabs/
  • ~/.ssh/authorized_keys 是否多了不明密钥
  • ~/.bashrc / ~/.profile 是否有后门代码
  • systemd user services
  • /tmp / /var/tmp / /dev/shm 可疑文件

5. rathole 隧道需要双向加固

rathole 会把内网服务完全暴露到公网,必须在客户端和服务器端都做安全加固。只修一端等于没修。

6. fail2ban 对 localhost 无效

通过 rathole 转发的连接显示为 127.0.0.1,fail2ban 无法封禁真正的攻击者IP。需要在服务器端也安装 fail2ban。

7. 定期检查安全配置

安全不是一次性工作,需要定期检查:

  • 监控 SSH 日志
  • 检查 fail2ban 封禁记录
  • 审计系统用户和权限

七、事后清单:入侵后该做什么

如果发现被入侵,按这个顺序过一遍:

  1. 杀进程止血 - pkill -KILL -u <失陷用户> 先把矿机/后门进程停掉
  2. 查持久化 - crontab、authorized_keys、bashrc/profile、systemd user services、/tmp 和 /var/tmp 隐藏文件
  3. 吊销泄露的凭证 - 入侵者可能已经读走了配置文件中的 API Key、token,到对应平台后台全部吊销换新
  4. 关密码改密钥 - 这是根本防线,不是换端口
  5. 清理多余账户 - 回顾系统上有哪些用户、哪些有弱密码、哪些根本不需要
  6. 全链路加固 - 不只修客户端,还要修服务器端和所有通过 rathole 暴露的服务

八、相关配置文件

文件位置说明
客户端 SSH 配置/etc/ssh/sshd_config.d/hardening.confAllowUsers, 密码禁用
服务器 SSH 配置/etc/ssh/sshd_config.d/hardening.confroot限制, 密码禁用
fail2ban 配置/etc/fail2ban/jail.local自动封禁规则
rathole 服务/etc/systemd/system/rathole.service笔记本电脑转发
rathole-mac 服务/etc/systemd/system/rathole-mac.serviceMac 转发
Mac SSH 配置/etc/ssh/sshd_config密码禁用, root限制

总结

这次事件从发现入侵到全面加固,经历了两个阶段:

  1. 首次修复(5月23日):只修复了客户端,头痛医头
  2. 全面加固(5月29日):发现攻击仍在继续,进行全链路加固

关键教训:

  • 安全不靠隐藏,靠密钥
  • 公网暴露 = 零信任
  • 被入侵后要查持久化
  • rathole 隧道需要双向加固
  • fail2ban 需要在服务器端安装

最终状态:

  • ✅ 客户端 SSH 加固完成
  • ✅ 服务器端 SSH 加固完成
  • ✅ Mac SSH 加固完成
  • ✅ fail2ban 自动封禁配置完成
  • ✅ 验证测试通过

攻击者仍在尝试,但我们的防线已经建立。