在开始这篇博客之前有必要讲讲我的经历和编写这篇教程的初衷
事情是这样的,一年前博主斥巨资200缘购买了腾某云轻量应用服务器一台,服务器上只部署了自己的私人网站,也没做什么特别的安全维护,一年来一点问题都没有。直到前段时间想在服务器上安装docker容器部署微服务的项目,第一天部署完成第二天我的服务器就沦陷了,起初并没有意识到问题的严重性以为只是一些小问题,当我远程连接服务器时发现连接总是超时,访问网站的时候也一直加载不出来,于是登录到服务器运营商管理后台,在站内邮箱中发现了好几篇恶意文件通知我意识到可能是服务器中毒了,然后我复制邮件中的xmrigMiner去某度上搜索发现是一种挖矿木马病毒,网安小白自然没办法处理,于是我花了一天时间尝试了网上基本上百分之八十的教程,包括更换强密码,更换SSH连接默认的端口,限制root用户远程登录,根据官方文档整改等等操作,这些记录在我的另一篇博客腾讯云服务器被恶意挖矿处理建议里面,当然里面只记录了我第一天与木马病毒搏斗的经历,后续一连两三天都还在继续与之搏斗。那篇文章的东西虽然没能解决我的问题,但是对大部分病毒还是又不错的防御效果。
这时候有朋友要好奇了,为什么花了几天时间去自己解决而不去找官方解决问题呢?
那我不得不吐槽一下腾某云的售后了,连续两天找客服给出的建议就是自行处理,然后给一堆手册连接,不得不说这些是真的没用。由于聊天内容的特殊性,我并不方便将所有的内容截图。
后来尝试重装系统,重装docker容器,重新部署项目,禁用密码登录改为本地密钥登录,不出意外即使我重装系统服务器在第二天依然被入侵!!!
一连几天被官方检测到挖矿肯定是要被封停服务器,尽管如此依旧请求不到官方的技术支持,博主只能考虑暂时关闭服务器,然后再花时间找服务器的漏洞(重装系统基本上可以完全删除黑客留下的后门),重装系统后依然被入侵只能说明服务器存在漏洞,比如说端口或者docker,想到这里我不禁联想到我每次重装系统后都会安装docker,设置docker远程登录,莫非是这里出了问题?
说干就干,直接检查docker的镜像,发现除了自己pull和手动上传的镜像之外,还多出一个ubantu的镜像和一个不知名的镜像,于是又去网上查,果然是docker的问题,原来万能的网友们早就深受其扰,好吧居然让我遇上了,那今天必须将他彻底根除,于是我参考大佬门的操作(下文有引用),更新了这篇文章,根据以下步骤进行配置,绝对能解决你的问题!!!
一、入侵原理
黑客为什么能够通过2375端口入侵宿主主机?
1. docker对
user namespace
没有做隔离,也就是说,容器内部的root
用户就是宿主机的root
用户,一旦挂载目录,就可以在容器内部以宿主机的root
用户身份对挂载的文件系统随意修改了2. docker服务拥有很高的执行权利(相当于
root
),并且在docker用户组下的普通用户不需要任何其他验证就可以执行docker run
等命令3. 而暴露的
docker remote
API端口如果没有启动ssl
验证的话,任何能连通到这台docker宿主机的的机器都可以随意操作这台docker宿主机的docker daemonz
二、漏洞修复方案(针对安全连接配置)
docker本身提供了加密的远程管理端口2376,配合CA证书,就能提供TLS
连接了。
首先要准备5个证书和秘钥文件,分别是ca.pem
、server-cert.pem
、server-key.pem
、client-cert.pem
和client-key.pem
。其中,server-cert.pem
中限制了能够访问Docker主机的客户端列表。
启动docker deamon
时,需要设置-H
、–tls
、–tlscacert=ca.pem
、–tlscert=server-cert.pem
和–tlskey=server-key.pem
。此时,只有客户端列表中的主机能够访问docker主机。
二、简单配置
仅限于连接使用,也是网上大部分渣土教程的配置内容,其实对风险没有社么抵御能力,黑客一旦盯上你的服务器,可以轻而易举的通过docker的2375端口爆破你的服务器然后为所欲为。
1 修改docker配置文件
# 打开docker.service文件
vi /lib/systemd/system/docker.service
# 修改第13行,设置任何主机都可以连接
ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix://var/run/docker.sock
# 重启docker后台
systemctl daemon-reload
# 重启docker
systemctl restart docker
2 开放docker远程连接端口
sudo firewall-cmd --zone=public --add-port=2375/tcp --permanent
sudo systemctl restart firewalld.service
sudo firewall-cmd --reload
sudo firewall-cmd --list-ports
通过以上两步简单配置基本就可以了,然后去IDEA的插件库里安装docker相应插件配置连接就可以了,连接的内容并不是我们这篇文章的重点,这里我就不写太多避免把文章写的四不像,有需要的朋友可以去查查别人的文章跟着配就完了。
三、安全连接配置
下面的配置是我根据大佬码农参上的文章万万没想到,我的Docker居然被挖矿了!修改后配置的,建议大家可以去看看原文。我在配置的时候和大佬的流程是有些不一样的,另外我也对每个命令做了更为详细的解释,授人以鱼不如授人以渔。如果根据我下面的步骤进行配置,基本不会出现什么问题,相应命令建议直接复制粘贴,需要修改IP地址的地方改为自己的IP地址或者域名即可。
1、先在/usr/local
目录下创建个文件夹,这里取名叫ca
,然后进入ca
文件夹中
mkdir -p /usr/local/ca
cd /usr/local/ca
2、生成CA私钥ca-key.pem
,使用该私钥对CA证书签名(需要输入密码,自由指定,两次输入保持一致并记住即可,后面会用到)
openssl genrsa -aes256 -out ca-key.pem 4096
3、使用CA私钥ca-key.pem
生成自签名CA证书ca.pem
。生成证书时,通过-days 365
设置证书的有效期。单位为天,默认情况下为30天(需要先输入上面设置的密码,然后根据提示分别输入国家,省份、城市、组织、等一系列信息)
openssl req -new -x509 -sha256 -batch -subj '/C=CN/ST=Sichuan/L=Chengdu/O=Ghostcloud Co.,Ltd/OU=Laboratory/CN=www.ghostcloud.cn' -days 365 -key ca-key.pem -out ca.pem
4、生成服务器私钥server-key.pem
和CSR(Certificate Signing Request)server-csr.pem
# 生成server-key.pem
openssl genrsa -out server-key.pem 4096
# 生成CSR(把下面的$Host换成你自己服务器外网的IP或者域名)
openssl req -subj "/CN=175.178.1.179" -sha256 -new -key server-key.pem -out server.csr.pem
5、使用CA证书生成服务器证书server-cert.pem
。TLS连接时,需要限制客户端的IP列表或者域名列表。只有在列表中的客户端才能通过客户端证书访问docker daemon
(允许哪些IP可以连接到服务器的docker(条件:只有拥有证书的才可以连接成功),这样配置好之后其他IP也可以访问到。如果不想限制IP,可以设置为0.0.0.0(注意如果用域名话就把 IP:192.168.1.195替换成DNS:域名)),需要输入密码
# 生成服务器证书server-cert.pem
# IP之间以逗号分隔
echo subjectAltName = IP:127.0.0.1,IP:0.0.0.0 > allow.list
openssl x509 -req -days 365 -sha256 -in server.csr.pem -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem -extfile allow.list
6、生成客户端私钥client-key.pem
和CSRclient-csr.pem
# 生成client-key.pem
openssl genrsa -out client-key.pem 4096
# 生成CSR(client-csr.pem)
openssl req -subj '/CN=DockerClient' -new -key client-key.pem -out client-csr.pem
7、使用CA证书生成客户端证书client-cert.pem
。需要加入extendedKeyUsage
选项,需要输入密码
# 生成客户端证书client-cert.pem
echo extendedKeyUsage = clientAuth > options.list
openssl x509 -req -days 365 -sha256 -in client-csr.pem -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out client-cert.pem -extfile options.list
8、成功生成了需要的证书和秘钥,可以删除临时文件
rm -f server.csr.pem client-csr.pem allow.list options.list
9、为了保证证书和私钥的安全,需要修改文件的访问权限
# 设置ca证书、服务器证书、客户端证书的权限为r--r--r--
chmod 444 ca.pem server-cert.pem client-cert.pem
# 设置ca私钥、服务器私钥、客户端私钥的权限为r--------
chmod 400 ca-key.pem server-key.pem client-key.pem
10、重启docker daemon
,加入ca.pem
、server-cert.pem
和server-key.pem
。-H=0.0.0.0:2376
表示docker daemon
监听在2376端口
# Docker 1.16版本及以前
docker daemon --tlsverify --tlscacert=/usr/local/ca/ca.pem --tlscert=/usr/local/ca/server-cert.pem --tlskey=/usr/local/ca/server-key.pem -H=0.0.0.0:2376
# Docker 1.16版本之后
dockerd --tlsverify --tlscacert=/usr/local/ca/ca.pem --tlscert=/usr/local/ca/server-cert.pem --tlskey=/usr/local/ca/server-key.pem -H=0.0.0.0:2376
11、在客户端,运行docker命令时,加入ca.pem
、client-cert.pem
和client-key.pem
docker --tlsverify --tlscacert=/usr/local/ca/ca.pem --tlscert=/usr/local/ca/client-cert.pem --tlskey=/usr/local/ca/client-key.pem -H=tcp://127.0.0.1:2376 info
12、复制文件到docker目录下
cp server-cert.pem server-key.pem ca.pem /etc/docker/
13、修改docker配置文件
vim /lib/systemd/system/docker.service
# 修改第13行(将ExecStart替换成)
ExecStart=/usr/bin/dockerd --tlsverify --tlscacert=/etc/docker/ca.pem --tlscert=/etc/docker/server-cert.pem --tlskey=/etc/docker/server-key.pem -H tcp://0.0.0.0:2376 -H unix://var/run/docker.sock
14、重新加载daemon
systemctl daemon-reload
systemctl restart docker
15、开放2376端口
sudo firewall-cmd --zone=public --add-port=2376/tcp --permanent
sudo systemctl restart firewalld.service
sudo firewall-cmd --reload
16、重启docker
systemctl restart docker