使用TLS解决Docker API暴露2375端口的问题

问题起因

由于本人开发环境是在 Windows,开发完成后需要使用 Dockerfile 打包镜像,这个过程需要有一个 Docker 服务完成,Windows 安装 Docker 会影响到很多环境,我又不想本地开虚拟机使用 Docker,于是我就索性使用服务器上的 Docker,并放开了 2375 端口,这个是 Docker 默认 API 的端口,于是就可以很愉快的打包发布了。

但是没过几天,我就收到阿里云的告警,服务器负载长时间在 100%,服务器卡得不行,上服务器一看,不知道为什么多了几个没见过的 Docker 镜像以及很多不认识的容器,于是判断服务器应该是被黑客入侵了,被用来挖矿了,而入侵的入口就是 Docker 的 2375端口。

解决方法

解决方法最简单的就是尽量不要启用 API 功能,或者把默认端口改一下,但是这个也是只能解决一时的问题,后来查询资料,找到了使用 TLS 通信机制的解决方法。解决方法的过程如下:

  1. 生成一系列证书和文件

    bash 复制代码
    # 创建一个文件夹,用于存放需要用到的证书等信息
    mkdir -p ~/docker-certs
    cd ~/docker-certs
    # 生成一个 CA(证书颁发机构)私钥,CA私钥用于为服务器或客户端证书生成签名。这个签名证明了该证书是由可信的 CA 颁发的。当服务器或客户端收到证书时,它会用 CA 的公钥来验证证书的签名。如果验证通过,意味着该证书确实是由该 CA 颁发的,确保了证书持有者的身份合法性。
    openssl genrsa -aes256 -out ca-key.pem 4096
    # 生成 key 的过程中,可能会出现要求输入 Enter pass phrase for ca-key.pem,这个相当于私钥的密码,能够进一步保证私钥的安全,哪怕别人获取到你的私钥,也不能直接使用,要输入密码。
    
    # 用 CA私钥自签名生成一个 CA 的证书,CA证书用于验证 CA 身份的合法性,要信任某个证书,关键就是要信任CA的证书。
    openssl req -new -x509 -days 365 -key ca-key.pem -sha256 -out ca.pem
    # 创建服务器端私钥和证书
    openssl genrsa -out server-key.pem 4096
    openssl req -new -key server-key.pem -out server.csr
    # CA 为服务端证书签名
    openssl x509 -req -days 365 -sha256 -in server.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem
    # 创建客户端私钥和证书
    openssl genrsa -out key.pem 4096
    openssl req -new -key key.pem -out client.csr
    # 签署客户端证书
    openssl x509 -req -days 365 -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out cert.pem
  2. 移除不必要的 CSR 文件

    bash 复制代码
    rm -v server.csr client.csr
  3. 设置权限

    bash 复制代码
    chmod -v 0400 ca-key.pem key.pem server-key.pem
    chmod -v 0444 ca.pem server-cert.pem cert.pem
  4. 修改 /usr/lib/systemd/system/docker.service 文件

    bash 复制代码
    vim /usr/lib/systemd/system/docker.service

    ExecStart 那改成:

    properties 复制代码
    ExecStart=/usr/bin/dockerd \
    --tlsverify \
    --tlscacert=/root/docker-certs/ca.pem \
    --tlscert=/root/docker-certs/server-cert.pem \
    --tlskey=/root/docker-certs/server-key.pem \
    -H tcp://0.0.0.0:2376 -H unix://var/run/docker.sock \
    -H fd:// --containerd=/run/containerd/containerd.sock
  5. 重启 Docker 服务

    bash 复制代码
    systemctl daemon-reload && systemctl restart docker
  6. 客户端所在机器找个地方存放 ca.pem、cert.pem、key.pem 三个文件,并且添加以下三个环境变量:

    text 复制代码
    DOCKER_HOST=tcp://你 docker 所在的IP地址:2376
    DOCKER_CERT_PATH=存放三个文件的地方
    DOCKER_TLS_VERIFY=1
  7. 然后测试即可

相关推荐
Siren_dream31 分钟前
在VMware上运行Linux(我选择的是Ubuntu)
linux·运维·ubuntu
荣光波比1 小时前
K8S(十五)—— 企业级K8s集群管理实践:Rancher安装配置与核心功能实操
容器·kubernetes·rancher
JanelSirry1 小时前
微服务是不是一定要容器化(如 Docker)?我该怎么选
docker·微服务·架构
励志不掉头发的内向程序员1 小时前
【Linux系列】掌控 Linux 的脉搏:深入理解进程控制
linux·运维·服务器·开发语言·学习
小屁不止是运维1 小时前
k8s问题详解1:k8s集群上传文件过大导致413 Request Entity Too Large(请求文件实体过大)
docker·容器·kubernetes
東雪蓮☆1 小时前
K8s Ingress 详解与部署实战
linux·运维·kubernetes
塔能物联运维2 小时前
物联网运维中的边缘计算任务调度优化策略
运维·人工智能·物联网·边缘计算
真正的醒悟2 小时前
什么是网络割接
运维·服务器·网络
Bruce_Liuxiaowei2 小时前
Win7虚拟机加入域错误排查指南:解决无法启动服务问题
运维·网络·windows·安全·网络安全
聆风吟º2 小时前
无需 VNC / 公网 IP!用 Docker-Webtop+cpolar,在手机浏览器远程操控 Linux
linux·运维·docker