首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >那个向我索要比特币的黑客,教会我如何正确部署Docker

那个向我索要比特币的黑客,教会我如何正确部署Docker

作者头像
Ynchen
发布2025-12-21 13:33:17
发布2025-12-21 13:33:17
1290
举报
一、事故背景与现象

1. 初始现象:数据神秘丢失与服务重启

我的个人博客项目采用 docker-compose 统一部署,包含 MySQL, Redis, RabbitMQ, MinIO 及一个 Spring Boot 后端应用 (app.jar)。某天发现 docker ps -a 显示 mysql 容器的启动时间(如 Up 5 hours)远小于其他服务(如 Up 6 days),表明其在近期被重启过。

2. 核心问题:数据库被清空,数据丢失

登录 mysql 容器后,发现原有的业务数据库 Ruyu-Blog 内容全部消失,只剩下一个空的同名库或一些奇怪的 README 表。

3. 最终确认:遭受勒索软件攻击

通过查看数据库,发现了名为 README_TO_RECOVER... 或 RECOVER_YOUR_DATA 的数据库。查询其中的表内容,看到了明确的勒索信息,要求支付比特币以恢复数据。


二、事故原因分析:安全防线的致命漏洞

这次攻击的成功,源于两个基础但致命的安全疏忽,这也是绝大多数个人开发者服务器被攻击的共同原因:

  1. 【核心漏洞】将内部服务的端口暴露于公网
    • 在 docker-compose.yml 文件中,使用了如 ports: - "3306:3306" 的默认配置。
    • 这等同于 ports: - "0.0.0.0:3306:3306",意味着将 MySQL 数据库的端口直接开放给了整个互联网。
    • 比喻:相当于把自家金库的大门直接开在了人来人往的大街上,任何人都可以过来尝试开锁。
  2. 【雪上加霜】使用极度脆弱的弱密码
    • MySQL 的 root 账户密码设置为 123456。
    • Redis 也使用了 123456 这样的弱密码。
    • 后果:攻击者的自动化扫描程序在全网扫描开放了 3306、6379 等端口的服务器,然后用一个包含海量弱密码的字典进行暴力破解,几乎瞬间就能成功。

结论:开放的公网端口 + 弱密码 = 服务器门户大开,任人宰割。


三、解决方案:构建零信任的内部安全网络

我们的目标是:在不牺牲开发和管理便利性的前提下,彻底杜绝此类攻击。核心策略是 “封死外门,加固内门,只开VIP通道”

Step 1: 全面收紧端口暴露(封死外门)

这是最关键的一步。编辑 docker-compose.yml 文件,将所有不需要从用户浏览器直接访问的内部服务端口,全部从 0.0.0.0 (公网) 绑定到 127.0.0.1 (仅本机)。

修改前 (危险的配置):

代码语言:javascript
复制
services:
  mysql:
    ports:
      - "3306:3306"
  redis:
    ports:
      - "6379:6379"

修改后 (安全的配置):

代码语言:javascript
复制
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容器)才能连接。

Step 2: 强制使用高强度密码(加固内门)

在 docker-compose.yml 中为所有服务设置全新的、由大小写字母、数字和特殊符号组成的复杂密码。

代码语言:javascript
复制
services:
  mysql:
    environment:
      - MYSQL_ROOT_PASSWORD=Ruyu-Blog_DB_P@ssw0rd!2025#
  redis:
    command: redis-server --requirepass Your_Super_Complex_Redis_P@ssw0rd!
Step 3: 更新应用配置,连接内部网络

修改 Spring Boot 应用的 application.yml 文件,将所有服务的连接地址从公网IP改为 127.0.0.1,并更新为新的复杂密码。

修改前:

代码语言:javascript
复制
datasource:
  url: jdbc:mysql://8.148.31.90:3306/Ruyu-Blog
  password: 123456
redis:
  host: 8.148.31.90
  password: 123456

修改后:

代码语言:javascript
复制
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!
Step 4: 建立SSH隧道,实现安全的远程可视化管理(开VIP通道)

现在所有服务都无法从外部直接访问了,我们需要为自己(管理员)建立一条安全的“秘密通道”来进行可视化管理。

技术SSH 隧道 (本地端口转发)

原理:利用 SSH 连接作为加密管道,将服务器上的内部端口(如 127.0.0.1:3306)安全地映射到我们自己电脑的一个本地端口上(如 localhost:3307)。

操作方法:

  1. 数据库管理 (以 Navicat 为例):
    • 常规设置:主机填 127.0.0.1,端口 3306,并填入新的复杂密码。
    • SSH设置:勾选“使用SSH通道”,并填写服务器的公网IP、SSH端口(22)、SSH用户名(root)和SSH登录密码
    • 连接成功后,即可像操作本地数据库一样安全地进行管理。
  2. Web管理后台 (如 MinIO, RabbitMQ):
    • 使用图形化SSH客户端 (如 Xshell): 在会话属性的“隧道”设置中,添加转发规则。例如,为 MinIO 添加:源主机: localhost | 侦听端口: 9001 | 目标主机: 127.0.0.1 | 目标端口: 9001。
    • 使用命令行SSH: 执行 ssh -L 9001:127.0.0.1:9001 -L 15672:127.0.0.1:15672 root@你的服务器IP。
    • 建立隧道后,在本地浏览器中访问 http://localhost:9001 即可打开 MinIO 后台。

四、总结与反思
  1. 最小权限原则:永远不要暴露不必要的端口到公网。服务之间应默认通过内部网络通信。
  2. 密码即盾牌:绝不使用弱密码。密码的复杂性是抵御暴力破解的最后一道防线。
  3. SSH隧道是神器:它是兼顾服务器安全和远程管理便利性的“瑞士军刀”,是每个开发者和运维人员都应掌握的核心技能。
  4. 安全是一个整体:仅仅加固一个点是不够的。必须从 docker-compose 的网络配置,到各个服务的密码,再到应用的连接配置,最后到管理员的访问方式,形成一个完整的安全闭环。

通过这次代价高昂的“实战演练”,我深刻理解了服务器安全的基础原则。希望这篇笔记能帮助到每一个正在使用云服务器的开发者,避免重蹈我的覆辙。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-08-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、事故背景与现象
    • 1. 初始现象:数据神秘丢失与服务重启
    • 2. 核心问题:数据库被清空,数据丢失
    • 3. 最终确认:遭受勒索软件攻击
  • 二、事故原因分析:安全防线的致命漏洞
  • 三、解决方案:构建零信任的内部安全网络
    • Step 1: 全面收紧端口暴露(封死外门)
    • Step 2: 强制使用高强度密码(加固内门)
    • Step 3: 更新应用配置,连接内部网络
    • Step 4: 建立SSH隧道,实现安全的远程可视化管理(开VIP通道)
  • 四、总结与反思
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档