从被入侵挖矿到全面安全加固
序:发现黑客还在攻击
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 明文存储,可能被窃取 |
| 数据 | 无法确认攻击者是否读取/拷贝了文件 |
漏洞清单(入侵时状态,已全部修复)
| # | 问题 | 严重度 | 当前状态 |
|---|---|---|---|
| 1 | SSH 允许密码登录 - 根本原因 | 🔴 | ✅ 已禁用 |
| 2 | test 账户密码太弱 - 字典一撞就进 | 🔴 | ✅ 已锁定 |
| 3 | 多余系统账户 - 系统中存在不止一个弱密码的非核心账户 | 🟡 | ✅ 已清理 |
| 4 | 非标准端口不防扫描 - 全端口扫描不挑端口号 | 🟡 | ✅ 已加固 |
| 5 | 无 fail2ban - 1412 次失败尝试无任何自动阻断 | 🟡 | ✅ 已安装 |
| 6 | API Key 明文放 bashrc - 被入侵即泄露 | 🟡 | ✅ 已吊销 |
首次修复措施
# 1. 关闭密码登录(全局,所有用户)
# 2. 锁定失陷账户
# 3. 杀掉恶意进程
# 4. 清除 crontab 后门
# 5. 删除后门脚本
二、持续攻击发现(2026-05-29)
发现过程
5 月 29 日,在排查系统 CPU 发热问题时,通过检查 SSH 日志发现了持续的暴力破解攻击:
# 检查攻击日志
| |
# 输出: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配置
# 输出:
分析:为什么首次修复不完整?
| 问题 | 原因 |
|---|---|
| 只修复了客户端 | 服务器端(your-server-ip)配置仍不安全 |
| 无自动封禁机制 | fail2ban 未安装,攻击者可以无限尝试 |
| 无用户限制 | 没有 AllowUsers 配置,所有用户都暴露 |
| Mac 未加固 | Mac 的 SSH 也通过 rathole 暴露,且无安全配置 |
三、全面安全加固(2026-05-29)
3.1 客户端(本机)加固
安装 fail2ban
# 安装
# 配置
# 启动
SSH 配置加固
3.2 服务器端(your-server-ip)加固
⚠️ 配置冲突问题
服务器默认配置存在冲突,需要先修复:
# 检查配置
# 输出示例(存在冲突):
# /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_config 和 50-cloud-init.conf 中的配置会覆盖 hardening.conf 的配置。
修复方法:
# 1. 注释掉 sshd_config 中的冲突配置
# 2. 注释掉 50-cloud-init.conf 中的冲突配置
# 3. 重启 SSH 服务
安装 fail2ban
# 连接服务器
# 安装 fail2ban
# 配置 fail2ban
SSH 加固
3.3 Mac 加固
# 禁用密码登录
# 禁止root登录
# 测试配置
# 重启SSH
四、安全等级对比
防护体系演进
| 维度 | 入侵前 | 首次修复后 | 全面加固后 |
|---|---|---|---|
| 整体安全 | 🔴 高危 | 🟡 中等 | 🟢 安全 |
| 暴力破解防护 | ❌ 无 | ⚠️ 基础 | ✅ 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.1 | Permission denied (publickey) ✅ |
| root 登录被拒绝 | ssh root@127.0.0.1 | Permission denied (publickey) ✅ |
| AllowUsers 配置生效 | 用 test 用户尝试登录 | not allowed because not listed in AllowUsers ✅ |
服务器端(your-server-ip)
| 验证项 | 测试方法 | 结果 |
|---|---|---|
| SSH 密码登录被拒绝 | ssh -o PubkeyAuthentication=no root@your-server-ip | Permission denied (publickey) ✅ |
| 普通用户密码登录被拒绝 | ssh -o PubkeyAuthentication=no your-username@your-server-ip | Permission denied (publickey) ✅ |
| 配置冲突已修复 | 检查配置文件 | sshd_config 和 50-cloud-init.conf 已注释冲突配置 ✅ |
| fail2ban 服务运行 | systemctl status fail2ban | active ✅ |
| fail2ban 监控日志 | fail2ban-client status sshd | File 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 封禁记录
- 审计系统用户和权限
七、事后清单:入侵后该做什么
如果发现被入侵,按这个顺序过一遍:
- 杀进程止血 -
pkill -KILL -u <失陷用户>先把矿机/后门进程停掉 - 查持久化 - crontab、authorized_keys、bashrc/profile、systemd user services、/tmp 和 /var/tmp 隐藏文件
- 吊销泄露的凭证 - 入侵者可能已经读走了配置文件中的 API Key、token,到对应平台后台全部吊销换新
- 关密码改密钥 - 这是根本防线,不是换端口
- 清理多余账户 - 回顾系统上有哪些用户、哪些有弱密码、哪些根本不需要
- 全链路加固 - 不只修客户端,还要修服务器端和所有通过 rathole 暴露的服务
八、相关配置文件
| 文件 | 位置 | 说明 |
|---|---|---|
| 客户端 SSH 配置 | /etc/ssh/sshd_config.d/hardening.conf | AllowUsers, 密码禁用 |
| 服务器 SSH 配置 | /etc/ssh/sshd_config.d/hardening.conf | root限制, 密码禁用 |
| fail2ban 配置 | /etc/fail2ban/jail.local | 自动封禁规则 |
| rathole 服务 | /etc/systemd/system/rathole.service | 笔记本电脑转发 |
| rathole-mac 服务 | /etc/systemd/system/rathole-mac.service | Mac 转发 |
| Mac SSH 配置 | /etc/ssh/sshd_config | 密码禁用, root限制 |
总结
这次事件从发现入侵到全面加固,经历了两个阶段:
- 首次修复(5月23日):只修复了客户端,头痛医头
- 全面加固(5月29日):发现攻击仍在继续,进行全链路加固
关键教训:
- 安全不靠隐藏,靠密钥
- 公网暴露 = 零信任
- 被入侵后要查持久化
- rathole 隧道需要双向加固
- fail2ban 需要在服务器端安装
最终状态:
- ✅ 客户端 SSH 加固完成
- ✅ 服务器端 SSH 加固完成
- ✅ Mac SSH 加固完成
- ✅ fail2ban 自动封禁配置完成
- ✅ 验证测试通过
攻击者仍在尝试,但我们的防线已经建立。
评论