完蛋,我被挖矿木马包围了|使用 TLS 连接 Docker

事故还原

近日,白泽在使用 docker 的时候,开放了防火墙的端口,以 SSH 方式访问远程服务器的 docker 守护进程(无需使用密钥即可建立连接),随后竟遭到了挖矿木马的攻击,好一顿折腾之后,使用 TLS 证书加密通信才解决了问题。

时间线

部分腾讯云短信和云服务器安全主机管理后台的截图(失眠.jpg):

TLS 实践

TLS For Docker:docs.docker.com/engine/secu...

TLS 的主要作用是提供加密、认证和数据完整性,以确保在网络上进行的通信是安全的。下面的实践在你对照复现的时候,白泽建议你同时打开 docker 的文档,一并参考,注意命令格式。

为了允许机器 A 通过 TLS 访问机器 B 上的 Docker,你需要在机器 B 上进行一系列设置,以确保 Docker 守护程序(Docker Daemon)使用 TLS,并为客户端提供相应的证书。

服务端(docker 守护进程对应服务器)配置

一、在 B 机器上生成 CA(Certificate Authority)证书和密钥

vbnet 复制代码
openssl genrsa -aes256 -out ca-key.pem 4096
openssl req -new -x509 -days 365 -key ca-key.pem -sha256 -out ca.pem
  • 生成 rsa 私钥

    • 私钥生成:rsa
    • 私钥位数:4096
    • 加密私钥:aes256(生成过程中会提示输入密码,用于对私钥进行加密,后续使用私钥时也会提示输入这个密码
  • 生成自签名证书(根证书 CA)

    • 格式:x509
    • 签名:使用 sha256 计算 hash 摘要,对摘要使用私钥进行加密,加密的过程就是签名
    • 作用:作为根证书用于对后续 server 和 client 端的证书进行签名

二、生成 Docker 守护程序的未签名证书和密钥

vbnet 复制代码
openssl genrsa -out server-key.pem 4096
openssl req -subj "/CN=主机名" -sha256 -new -key server-key.pem -out server.csr
  • 创建服务器密钥
  • 生成服务器证书签名请求(CSR)文件:以便后续将其发送给证书颁发机构 (CA) 进行签名,从而得到服务器的证书

三、创建一个扩展属性配置文件(extfile.cnf),用于指定 IP 地址和 DNS 名称

ini 复制代码
echo subjectAltName = IP:机器B的IP地址,DNS:机器B的DNS名 >> extfile.cnf
echo extendedKeyUsage = serverAuth >> extfile.cnf
  • 创建一个 extfile.cnf 配置文件,其中包含主题备用名称(subjectAltName)的信息,包括 DNS 名称和 IP 地址。
  • echo extendedKeyUsage = serverAuth >> extfile.cnf:添加一个扩展属性,指定此证书仅用于服务器认证

四、生成 Docker 守护程序的签名证书

objectivec 复制代码
openssl x509 -req -days 365 -sha256 -in server.csr -CA ca.pem -CAkey ca-key.pem \
    -CAcreateserial -out server-cert.pem -extfile extfile.cnf
  • 使用 CA 的私钥 (ca-key.pem) 和 CA 签名证书 (ca.pem) 对服务器的 CSR (server.csr) 进行签名,生成服务器的证书 (server-cert.pem)。此命令还使用了 extfile.cnf 文件中的配置信息,确保证书包含了正确的主题备用名称和扩展属性。

五、配置 Docker 守护程序

在 Docker 守护程序的启动配置中添加 TLS 相关的参数:

ini 复制代码
dockerd \
    --tlsverify \
    --tlscacert=ca.pem \
    --tlscert=server-cert.pem \
    --tlskey=server-key.pem \
    -H=0.0.0.0:2376

防火墙配置: 如果机器 B 上有防火墙,确保允许来自机器 A 的流量通过 2376 端口。

🌟 Note:此时已经完成了服务端的配置,接下来需要在服务端上,借助根证书 CA,类似的生成客户端使用的证书,再将其拷贝到客户端机器上,即可使用 TLS 连接服务端 docker。

客户端配置

客户端的证书的生成和配置是类似的,这里简单罗列命令,不做重复解释。

  • 生成客户端私钥
csharp 复制代码
openssl genrsa -out key.pem 4096
  • 创建客户端证书签名请求 (CSR)
csharp 复制代码
openssl req -subj '/CN=client' -new -key key.pem -out client.csr
  • 创建客户端证书扩展配置文件
ini 复制代码
echo extendedKeyUsage = clientAuth > extfile-client.cnf
  • 生成签名的客户端证书
objectivec 复制代码
openssl x509 -req -days 365 -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem \
  -CAcreateserial -out cert.pem -extfile extfile-client.cnf
  • 在机器 B 上使用 docker 客户端连接到机器 B 的 docker 守护进程,并成功打印 docker version(后续只需要将客户端证书拷贝至 A 机器上即可实现安全的 TLS 连接
ini 复制代码
docker --tlsverify \
    --tlscacert=ca.pem \
    --tlscert=cert.pem \
    --tlskey=key.pem \
    -H=机器B的IP地址:2376 version

安全性工作

  • 设置文件访问权限
vbnet 复制代码
chmod -v 0400 ca-key.pem key.pem server-key.pem
chmod -v 0444 ca.pem server-cert.pem cert.pem
  • 清理临时文件
bash 复制代码
rm -v client.csr server.csr extfile.cnf extfile-client.cnf
  • 方便使用 docker(通过这种方式就不用每次连接都指定客户端证书的路径了)
bash 复制代码
mkdir -p ~/.docker
cp -v {ca,cert,key}.pem ~/.docker
export DOCKER_HOST=tcp://82.156.171.8:2376 DOCKER_TLS_VERIFY=1

当然只通过 export 配置环境变量只在当前会话生效,你需要在额外的配置文件中进行声明,这是 gpt 的回答:

参考文献

结语

本次事故,让我意识到服务器安全的重要性,每次被迫重装系统需要做很多数据备份迁移工作,服务也被迫暂停。平日维护服务器,更应当预防为主,做好规划,降低出错带来的恢复成本。

公众号 「白泽talk」,闲聊群:622383022

相关推荐
千|寻6 分钟前
【画江湖】langchain4j - Java1.8下spring boot集成ollama调用本地大模型之问道系列(第一问)
java·spring boot·后端·langchain
杰哥技术分享15 分钟前
在 CentOS 上安装 Docker 和 Docker Compose 并配置使用国内镜像源
linux·docker·centos
知更鸟呆呆19 分钟前
【Linux操作系统】基础开发工具(yum、vim、gcc/g++)
linux·运维·vim
程序员岳焱20 分钟前
Java 与 MySQL 性能优化:MySQL 慢 SQL 诊断与分析方法详解
后端·sql·mysql
龚思凯26 分钟前
Node.js 模块导入语法变革全解析
后端·node.js
天行健的回响28 分钟前
枚举在实际开发中的使用小Tips
后端
wuhunyu34 分钟前
基于 langchain4j 的简易 RAG
后端
techzhi34 分钟前
SeaweedFS S3 Spring Boot Starter
java·spring boot·后端
Gold Steps.1 小时前
Docker容器部署elasticsearch8.*与Kibana8.*版本使用filebeat采集日志
运维·docker·云原生·es
m0_637146931 小时前
C语言基础面试问答
运维·服务器