万万没想到,我的Docker居然被挖矿了!

3,388 阅读5分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

本文已参与 「掘力星计划」 ,赢取创作大礼包,挑战创作激励金。


事情是这样的,前段时间的周末刚在外面坐下准备吃个饭,突然收到一条短信:

什么情况?我一个小小的个人服务器都能被挖矿?回想了一下,也没想到之前做了什么能引起被挖矿的操作啊,直到两个小时后,又收到一条短信报警:

端口?提到端口我想起来了,自己前一天因为要用idea连接服务器上的docker,开启了一个2375的端口。至于具体操作,就是简单修改了一下配置文件/usr/lib/systemd/system/docker.service/usr/lib/systemd/system/docker.servicevv,修改了下面的内容:

ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock

在这句后面添加了一句:

-H tcp://0.0.0.0:2375

这样,就开启了一个2375端口,通过这个端口,可以在idea中配置docker,并在打包的同时进行镜像的上传:

图片

通过这个端口,我们就可以直接对远程的docker daemon进行操作了。

紧急处理

既然找到了问题所在,那我们就得立马处理这个问题了。回到家,马上在安全配置里关闭了2375端口的外网访问:

图片

再看一下后台的报警信息:

使用kill命令杀死这个进程:

图片

好了,这下进程也杀死了,外网的端口访问也关闭了,应该没事了吧?没想到晚上7点多,又连着报了两条警告信息:

使用ps指令看一下13102进程,没有查到。查一下masscan进程,能够找到,这个masscan是一个端口扫描工具,能够根据IP地址的范围和端口号,快速进行端口扫描:

图片

顺便查询了下父进程的pid,居然使用了portainer,居然连docker的图形化管理界面都帮我安装上了。需要注意的是在杀死masscan进程前,一定要杀死父进程,否则masscan进程会不断重启。

再看一下第二个报警的32452进程,能够找到docker-cache进程,使用kill杀死后不会进行重启。

图片

停止运行的容器并删除:

图片

删除挖矿image

图片

修改配置文件,删掉2375端口的tcp连接,然后重启docker:

systemctl daemon-reload
systemctl  start docker

入侵原理

到这,先总结一下为什么能够通过2375端口入侵宿主主机?

  • docker对user namespace没有做隔离,也就是说,容器内部的root用户就是宿主机的root用户,一旦挂载目录,就可以在容器内部以宿主机的root用户身份对挂载的文件系统随意修改了
  • docker服务拥有很高的执行权利(相当于root),并且在docker用户组下的普通用户不需要任何其他验证就可以执行docker run等命令
  • 而暴露的docker remote API端口如果没有启动ssl验证的话,任何能连通到这台docker宿主机的的机器都可以随意操作这台docker宿主机的docker daemon

漏洞修复

那么应该如何修复这个漏洞呢,通过查阅资料,docker本身提供了加密的远程管理端口2376,配合CA证书,就能提供TLS连接了。

首先要准备5个证书和秘钥文件,分别是ca.pemserver-cert.pemserver-key.pemclient-cert.pemclient-key.pem。其中,server-cert.pem中限制了能够访问Docker主机的客户端列表。

启动docker deamon时,需要设置-H–tls–tlscacert=ca.pem–tlscert=server-cert.pem–tlskey=server-key.pem。此时,只有客户端列表中的主机能够访问docker主机。

1.生成CA私钥ca-key.pem,使用该私钥对CA证书签名

openssl genrsa -out ~/docker/ca-key.pem 4096

2.使用CA私钥生成自签名CA证书ca.pem。生成证书时,通过-days 365设置证书的有效期。单位为天,默认情况下为30天

openssl req -x509 -sha256 -batch -subj '/C=CN/ST=Sichuan/L=Chengdu/O=Ghostcloud Co.,Ltd/OU=Laboratory/CN=www.ghostcloud.cn' -new -days 365 -key ~/docker/ca-key.pem -out ~/docker/ca.pem

3.生成服务器私钥server-key.pemCSR(Certificate Signing Request)server-csr.pem

openssl genrsa -out ~/docker/server-key.pem 4096
openssl req -subj '/CN=DockerDaemon' -sha256 -new -key ~/docker/server-key.pem -out ~/docker/server-csr.pem

4.使用CA证书生成服务器证书server-cert.pem。TLS连接时,需要限制客户端的IP列表或者域名列表。只有在列表中的客户端才能通过客户端证书访问docker daemon

echo subjectAltName = IP:127.0.0.1,IP:192.168.1.100 > ~/docker/allow.list
openssl x509 -req -days 365 -sha256 -in ~/docker/server-csr.pem -CA ~/docker/ca.pem -CAkey ~/docker/ca-key.pem -CAcreateserial -out ~/docker/server-cert.pem -extfile ~/docker/allow.list

5.生成客户端私钥client-key.pemCSRclient-csr.pem

openssl genrsa -out ~/docker/client-key.pem 4096
openssl req -subj '/CN=DockerClient' -new -key ~/docker/client-key.pem -out ~/docker/client-csr.pem

6.使用CA证书生成客户端证书client-cert.pem。需要加入extendedKeyUsage选项

echo extendedKeyUsage = clientAuth > ~/docker/options.list
openssl x509 -req -days 365 -sha256 -in ~/docker/client-csr.pem -CA ~/docker/ca.pem -CAkey ~/docker/ca-key.pem -CAcreateserial -out ~/docker/client-cert.pem -extfile ~/docker/options.list

7.成功生成了需要的证书和秘钥,可以删除临时文件

rm -f ~/docker/server-csr.pem ~/docker/client-csr.pem ~/docker/allow.list ~/docker/options.list

8.为了保证证书和私钥的安全,需要修改文件的访问权限

chmod 0444 ~/docker/ca.pem ~/docker/server-cert.pem ~/docker/client-cert.pem
chmod 0400 ~/docker/ca-key.pem ~/docker/server-key.pem ~/docker/client-key.pem

9.重启docker daemon,加入ca.pemserver-cert.pemserver-key.pem-H=0.0.0.0:2376表示docker daemon监听在2376端口

docker daemon --tlsverify --tlscacert=~/docker/ca.pem --tlscert=~/docker/server-cert.pem --tlskey=~/docker/server-key.pem -H=0.0.0.0:2376

10.在客户端,运行docker命令时,加入ca.pemclient-cert.pemclient-key.pem

docker --tlsverify --tlscacert=~/docker/ca.pem --tlscert=~/docker/client-cert.pem --tlskey=~/docker/client-key.pem -H=tcp://127.0.0.1:2376 info
Containers: 41 Running: 16 Paused: 0 Stopped: 25 Images: 821 Server Version: 1.10.3 

这样,就可以安全的远程控制docker主机了。

最后

如果觉得对您有所帮助,小伙伴们可以点赞、转发一下,非常感谢

公众号码农参上,加个好友,做个点赞之交啊