Docker API 2375端口裸奔风险
Docker 2375端口是Docker API的默认明文监听端口,如果直接暴露到公网且未加任何鉴权,任何能访问该端口的人都能调用Docker API创建容器、挂载宿主机目录,进而拿到服务器控制权。
这不是理论风险,而是发生过多次的真实入侵案例。
本文会用案例拆解攻击路径,并给出普通人就能执行的检测和加固步骤。
一个真实的“裸奔”接管过程
假设你在云服务器上运行了dockerd -H tcp://0.0.0.0:2375,或者通过宝塔面板勾选了“允许远程访问Docker”。
此时2375端口会对全网开放。
攻击者不需要密码,只需要一条命令:
docker -H 你的服务器IP:2375 ps
如果命令回列出你服务器上的容器列表,说明Docker API已经可以被远程调用了。
接着攻击者可以直接创建恶意容器,并把宿主机根目录挂载进去:
docker -H 你的服务器IP:2375 run -it -v /:/mnt alpine chroot /mnt
执行后,攻击者就已经以root身份进入了你的宿主机文件系统,可以修改SSH密钥、添加后门用户、清除日志或直接运行勒索命令。
整个过程只需要几秒钟,而你在控制台看起来好像什么都没发生。
先自查:你的2375端口真的暴露了吗
即便你没有手动开启远程访问,也可能因为脚本启动参数、早期安装模板或内网穿透配置让2375暴露。
用下面两步自查。
第一步,确认Docker守护进程监听地址:
ss -tlnp | grep 2375
如果输出包含0.0.0.0:2375或:::2375,说明正在对所有网络接口监听。
如果只有127.0.0.1:2375,则相对安全,因为只允许本机访问。
第二步,从另一台机器或手机4G网络测试端口连通性:
curl -s http://你的服务器IP:2375/version
如果返回包含ApiVersion等字段的JSON,说明端口已完全暴露。
如果返回curl: (7) Failed to connect,那至少从你当前网络无法访问,但仍建议继续看下文加固部分。
立刻止血:两种临时关闭方式
确认暴露后,先做止血再考虑修复。
最简单的方式是重启Docker服务并移除监听参数。
如果是Linux systemd环境,执行:
sudo systemctl stop docker
然后直接重启Docker守护进程,但不要带-H tcp://0.0.0.0:2375参数:
sudo systemctl start docker
如果你是在宝塔面板中开启了Docker远程访问,
请进入面板的Docker设置页,
找到“远程访问”或“API监听”相关开关,
把0.0.0.0:改为
2375127.0.0.1:,
2375
然后重启Docker。
如果不想改配置,也可以用防火墙临时屏蔽端口:
sudo iptables -A INPUT -p tcp --dport 2375 -j DROP
但防火墙规则只是权宜之计,推荐立即按下面方式彻底修复。
彻底修复:绑定内网并且开启TLS认证
正确做法是让Docker API只监听内网地址,并且要求客户端提供TLS证书。
这里给一个零基础用户也能照做的方案。
第一步:生成CA证书和服务端证书
在宿主机上创建一个证书目录,并生成CA私钥和证书:
mkdir -p /etc/docker/certs && cd /etc/docker/certs
echo '01' > ca.srl
openssl genrsa -out ca-key.pem 2048
openssl req -new -x509 -days 365 -key ca-key.pem -out ca.pem -subj "/CN=MyDockerCA"
然后生成服务端私钥和证书请求:
openssl genrsa -out server-key.pem 2048
openssl req -new -key server-key.pem -out server.csr -subj "/CN=你的服务器IP或域名"
生成扩展文件,只允许通过指定IP或域名访问:
echo subjectAltName = IP:你的服务器IP,DNS:你的域名 > extfile.cnf
echo extendedKeyUsage = serverAuth >> extfile.cnf
openssl x509 -req -days 365 -in server.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem -extfile extfile.cnf
第二步:修改Docker启动配置
编辑/etc/docker/daemon.json,写入如下内容:
{
"tls": true,
"tlsverify": true,
"tlscacert": "/etc/docker/certs/ca.pem",
"tlscert": "/etc/docker/certs/server-cert.pem",
"tlskey": "/etc/docker/certs/server-key.pem",
"hosts": ["tcp://0.0.0.0:2376", "unix:///var/run/docker.sock"]
}
这里特意使用2376端口,这是Docker TLS的默认端口。
如果不想改端口,也可以保持2375,但建议换掉,减少扫描器自动探测的风险。
重启Docker:
sudo systemctl daemon-reload
sudo systemctl restart docker
如果没有报错,再运行ss -tlnp | grep 237确认监听端口。
第三步:生成本地客户端证书并测试
你需要在自己电脑上生成客户端证书,然后拷贝到本地使用。
在本机执行同样的CA签名流程:
openssl genrsa -out client-key.pem 2048
openssl req -new -key client-key.pem -out client.csr -subj "/CN=client"
echo extendedKeyUsage = clientAuth > extfile-client.cnf
openssl x509 -req -days 365 -in client.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out client-cert.pem -extfile extfile-client.cnf
将ca.pem、client-cert.pem、client-key.pem三个文件下载到你本机的~/.docker/目录。
之后用Docker客户端连接时,必须指定证书:
docker --tlsverify --tlscacert=~/.docker/ca.pem --tlscert=~/.docker/client-cert.pem --tlskey=~/.docker/client-key.pem -H tcp://你的服务器IP:2376 version
看到正常版本信息,说明TLS已经生效。
现在即使2376端口暴露在公网,没有证书也无法调用API。
已经被入侵了怎么办
如果你在自查时发现2375端口暴露了很长时间,或者已经观察到可疑容器,按以下顺序紧急处理。
- 立即断开Docker远程访问:按上文止血方式关闭2375监听。
- 备份关键业务数据:先备份数据库和配置文件到隔离环境,避免攻击者破坏数据。
- 排查并删除可疑容器:用
docker ps -a查看所有容器,重点看启动时间异常、镜像来源不明、挂载了/或/etc的容器。删除可疑容器后再处理镜像。 - 检查SSH授权文件:查看
~/.ssh/authorized_keys和/root/.ssh/authorized_keys,发现陌生公钥立即移除。 - 检查计划任务和后门用户:运行
crontab -l和cat /etc/passwd,删除攻击者添加的定时任务和可疑用户。 - 重装系统是最后兜底:如果攻击者已经拿到root权限并植入内核级后门,最稳妥的方式是备份数据后重装操作系统,同时修改所有密码和密钥。
如果你的业务数据本身没有备份习惯,建议先做一次全盘快照,再开始清理操作,避免误删文件导致业务无法恢复。
避坑:这些做法并不安全
很多教程会让你只修改Docker配置文件为tcp://127.0.0.1:2375就收工,但你从宝塔或云服务器控制台的“安全组”里可能仍然放行了2375端口。
如果你经常用SSH远程管理服务器,更推荐直接使用下面两种方式:
- SSH隧道访问Docker API:在本地执行
ssh -L 2375:127.0.0.1:2375 你的服务器用户@服务器IP,然后所有Docker命令都打向本机2375,期间不再需要额外开公网端口。这是最省事的方案。 - 内网访问:只在云服务器内网IP上监听,并且安全组只放行管理员来源IP。
另外不要在Docker Compose配置或启动脚本中硬编码2375端口,
因为一旦服务器被扫描到,
攻击者会直接用docker exec或docker run加--privileged绕过很多限制。
验证加固是否成功
最后按下面清单逐项确认:
# 检查监听端口
ss -tlnp | grep 237
# 不带证书访问,应该失败
curl -ks https://你的服务器IP:2376/version
# 用正确证书访问,应该成功
curl -ks --cert client-cert.pem --key client-key.pem https://你的服务器IP:2376/version
不带证书时,返回curl: (35) SSL connect error或类似证书错误,说明TLS校验生效。
带证书时能正常看到JSON版本信息,说明Docker API虽然开放,但已经要求身份认证。
如果你还没有到需要远程管理Docker的复杂程度,最简单也最安全的做法是:不开启任何TCP监听,只用默认的/var/run/docker.sock本地接口。
必须远程操作时,优先选择SSH隧道或TLS双向认证,并避免让2375端口裸奔在公网上。