Docker服务开放了这个端口,服务器分分钟变肉机!

之前有很多朋友提过,当使用docker-maven-plugin打包SpringBoot应用的Docker镜像时,服务器需要开放2375端口。由于开放了端口没有做任何安全保护,会引起安全漏洞,被人入侵、挖矿、CPU飙升这些情况都有发生,今天我们来聊聊如何解决这个问题。

问题产生的原因

首先我们要明白问题产生的原因,才能更好地解决问题!

Docker为了实现集群管理,提供了远程管理的端口。Docker Daemon作为守护进程运行在后台,可以执行发送到管理端口上的Docker命令。

当我们修改docker.service文件,修改启动命令,加入-H tcp://0.0.0.0:2375时,就会开放2375端口,且没有任何加密和认证过程,这种方式一般用在内网测试环境。如果你的服务器部署在公网上,任何知道你IP的人,都可以管理这台主机上的容器和镜像,想想就觉得可怕。

解决思路

开放远程管理端口后,没有做任何安全保护导致了这个问题。我们只要使用安全传输层协议(TLS)进行传输并使用CA认证即可。

制作证书及秘钥

我们需要使用OpenSSL制作CA机构证书、服务端证书和客户端证书,以下操作均在安装Docker的Linux服务器上进行。

  • 首先创建一个目录用于存储生成的证书和秘钥;
mkdir /mydata/docker-ca && cd /mydata/docker-ca
  • 创建CA证书私钥,期间需要输入两次用户名和密码,生成文件为ca-key.pem;
openssl genrsa -aes256 -out ca-key.pem 4096
  • 根据私钥创建CA证书,期间需要输入上一步设置的私钥密码,生成文件为ca.pem;
openssl req -new -x509 -days 365 -key ca-key.pem -sha256 -subj "/CN=*" -out ca.pem
  • 创建服务端私钥,生成文件为server-key.pem;
openssl genrsa -out server-key.pem 4096
  • 创建服务端证书签名请求文件,用于CA证书给服务端证书签名,生成文件server.csr;
openssl req -subj "/CN=*" -sha256 -new -key server-key.pem -out server.csr
  • 创建CA证书签名好的服务端证书,期间需要输入CA证书私钥密码,生成文件为server-cert.pem;
openssl x509 -req -days 365 -sha256 -in server.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem
  • 创建客户端私钥,生成文件为key.pem;
openssl genrsa -out key.pem 4096
  • 创建客户端证书签名请求文件,用于CA证书给客户证书签名,生成文件client.csr;
openssl req -subj "/CN=client" -new -key key.pem -out client.csr
  • 为了让秘钥适合客户端认证,创建一个扩展配置文件extfile-client.cnf;
echo extendedKeyUsage = clientAuth > extfile-client.cnf
  • 创建CA证书签名好的客户端证书,期间需要输入CA证书私钥密码,生成文件为cert.pem;
openssl x509 -req -days 365 -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out cert.pem -extfi
  • 删除创建过程中多余的文件;
rm -rf ca.srl server.csr client.csr extfile-client.cnf
  • 最终生成文件如下,有了它们我们就可以进行基于TLS的安全访问了。
ca.pem CA证书
ca-key.pem CA证书私钥
server-cert.pem 服务端证书
server-key.pem 服务端证书私钥
cert.pem 客户端证书
key.pem 客户端证书私钥

配置Docker支持TLS

  • 用vim编辑器修改docker.service文件;
vi /usr/lib/systemd/system/docker.service
  • 修改以ExecStart开头的配置,开启TLS认证,并配置好CA证书、服务端证书和服务端私钥,修改内容如下;
ExecStart=/usr/bin/dockerd -H fd:// -H tcp://0.0.0.0:2375 --tlsverify --tlscacert=/mydata/docker-ca/ca.pem --tlscert=/m
  • 重启Docker服务,这样我们的Docker服务就支持使用TLS进行远程访问了!
systemctl daemon-reload && systemctl restart docker

客户端访问

接下来我们将使用docker-maven-plugin来打包Docker镜像,使用的代码为原来的mall-tiny-docker例子。

  • 直接使用docker-maven-plugin打包试试,由于我们的插件版本有点低,使用新一点版本的Docker会出现如下问题,升级到1.2.2版本解决该问题;
[ERROR] Failed to execute goal com.spotify:docker-maven-plugin:1.1.0:build (build-image) on project mall-tiny-docker: Exception caught: com.spotify.docker.client.shaded.com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `com.spotify.docker.client.messages.RegistryAuth` (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('desktop')
[ERROR] at [Source: UNKNOWN; line: -1, column: -1] (through reference chain: java.util.LinkedHashMap["credsStore"])
[ERROR] -> [Help 1]
  • 修改完版本后打包,发现TLS不再支持http了,需要改用https,修改<dockerHost>配置为https;
[ERROR] Failed to execute goal com.spotify:docker-maven-plugin:1.2.2:build (build-image) on project mall-tiny-docker: Exception caught: Request error: GET http://192.168.3.101:2375/version: 400, body: Client sent an HTTP request to an HTTPS server. HTTP 400 Bad Request -> [Help 1]
  • 修改完成后再次打包,继续失败,需要添加对应的客户端证书才能访问
[ERROR] Failed to execute goal com.spotify:docker-maven-plugin:1.2.2:build (build-image) on project mall-tiny-docker: Exception caught: java.util.concurrent.ExecutionException: com.spotify.docker.client.shaded.javax.ws.rs.ProcessingException: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target -> [Help 1]
  • 将如下文件复制到指定目录,这里复制到了I:\developer\env\docker-ca;
ca.pem CA证书
cert.pem 客户端证书
key.pem 客户端证书私钥
  • 然后将该目录配置在插件的<dockerCertPath>节点下,最终插件配置如下;
<plugin>
    <groupId>com.spotify</groupId>
    <artifactId>docker-maven-plugin</artifactId>
    <version>1.2.2</version>
    <executions>
        <execution>
            <id>build-image</id>
            <phase>package</phase>
            <goals>
                <goal>build</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <imageName>mall-tiny/${project.artifactId}:${project.version}</imageName>
        <dockerHost>https://192.168.3.101:2375</dockerHost>
        <baseImage>java:8</baseImage>
        <entryPoint>["java", "-jar","/${project.build.finalName}.jar"]
        </entryPoint>
        <dockerCertPath>I:\developer\env\docker-ca</dockerCertPath>
        <resources>
            <resource>
                <targetPath>/</targetPath>
                <directory>${project.build.directory}</directory>
                <include>${project.build.finalName}.jar</include>
            </resource>
        </resources>
    </configuration>
</plugin>
  • 再次打包镜像,发现已经可以成功打包镜像,从此我们的2375端口终于可以安全使用了!
[INFO] Building image mall-tiny/mall-tiny-docker:0.0.1-SNAPSHOT
Step 1/3 : FROM java:8

 ---> d23bdf5b1b1b
Step 2/3 : ADD /mall-tiny-docker-0.0.1-SNAPSHOT.jar //

 ---> 5cb5a64ccedd
Step 3/3 : ENTRYPOINT ["java", "-jar","/mall-tiny-docker-0.0.1-SNAPSHOT.jar"]

 ---> Running in 5f3ceefdd974
Removing intermediate container 5f3ceefdd974
 ---> ee9d0e2b0114
ProgressMessage{id=null, status=null, stream=null, error=null, progress=null, progressDetail=null}
Successfully built ee9d0e2b0114
Successfully tagged mall-tiny/mall-tiny-docker:0.0.1-SNAPSHOT
[INFO] Built mall-tiny/mall-tiny-docker:0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 20.550 s
[INFO] Finished at: 2020-07-31T15:02:15+08:00
[INFO] Final Memory: 50M/490M
[INFO] ------------------------------------------------------------------------

参考资料

官方文档:https://docs.docker.com/engine/security/https/

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,951评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,606评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,601评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,478评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,565评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,587评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,590评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,337评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,785评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,096评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,273评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,935评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,578评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,199评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,440评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,163评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,133评论 2 352