
我的个人博客项目采用 docker-compose 统一部署,包含 MySQL, Redis, RabbitMQ, MinIO 及一个 Spring Boot 后端应用 (app.jar)。某天发现 docker ps -a 显示 mysql 容器的启动时间(如 Up 5 hours)远小于其他服务(如 Up 6 days),表明其在近期被重启过。
登录 mysql 容器后,发现原有的业务数据库 Ruyu-Blog 内容全部消失,只剩下一个空的同名库或一些奇怪的 README 表。
通过查看数据库,发现了名为 README_TO_RECOVER... 或 RECOVER_YOUR_DATA 的数据库。查询其中的表内容,看到了明确的勒索信息,要求支付比特币以恢复数据。

这次攻击的成功,源于两个基础但致命的安全疏忽,这也是绝大多数个人开发者服务器被攻击的共同原因:
结论:开放的公网端口 + 弱密码 = 服务器门户大开,任人宰割。
我们的目标是:在不牺牲开发和管理便利性的前提下,彻底杜绝此类攻击。核心策略是 “封死外门,加固内门,只开VIP通道”。
这是最关键的一步。编辑 docker-compose.yml 文件,将所有不需要从用户浏览器直接访问的内部服务端口,全部从 0.0.0.0 (公网) 绑定到 127.0.0.1 (仅本机)。
修改前 (危险的配置):
services:
mysql:
ports:
- "3306:3306"
redis:
ports:
- "6379:6379"修改后 (安全的配置):
services:
mysql:
ports:
- "127.0.0.1:3306:3306"
redis:
ports:
- "127.0.0.1:6379:6379"
rabbitmq:
ports:
- "127.0.0.1:5672:5672" # 程序连接端口
- "127.0.0.1:15672:15672" # 管理后台端口
minio:
ports:
- "127.0.0.1:9000:9000" # API端口
- "127.0.0.1:9001:9001" # 管理后台端口原理:127.0.0.1 (localhost) 是一个特殊的回环地址,永远指向服务器自身。绑定到此地址的端口,无法被外部网络访问,只有服务器内部的程序(包括其他Docker容器)才能连接。
在 docker-compose.yml 中为所有服务设置全新的、由大小写字母、数字和特殊符号组成的复杂密码。
services:
mysql:
environment:
- MYSQL_ROOT_PASSWORD=Ruyu-Blog_DB_P@ssw0rd!2025#
redis:
command: redis-server --requirepass Your_Super_Complex_Redis_P@ssw0rd!修改 Spring Boot 应用的 application.yml 文件,将所有服务的连接地址从公网IP改为 127.0.0.1,并更新为新的复杂密码。
修改前:
datasource:
url: jdbc:mysql://8.148.31.90:3306/Ruyu-Blog
password: 123456
redis:
host: 8.148.31.90
password: 123456修改后:
datasource:
url: jdbc:mysql://127.0.0.1:3306/Ruyu-Blog
password: Ruyu-Blog_DB_P@ssw0rd!2025#
redis:
host: 127.0.0.1
password: Your_Super_Complex_Redis_P@ssw0rd!现在所有服务都无法从外部直接访问了,我们需要为自己(管理员)建立一条安全的“秘密通道”来进行可视化管理。
技术:SSH 隧道 (本地端口转发)
原理:利用 SSH 连接作为加密管道,将服务器上的内部端口(如 127.0.0.1:3306)安全地映射到我们自己电脑的一个本地端口上(如 localhost:3307)。
操作方法:
通过这次代价高昂的“实战演练”,我深刻理解了服务器安全的基础原则。希望这篇笔记能帮助到每一个正在使用云服务器的开发者,避免重蹈我的覆辙。