用TLS保护Docker Remote API
本文最后修改于 41 天前,其中的信息可能已经有所发展或是发生改变。

前言

Portainer[^1]可以使用Docker Remote API的方式来管理远程的Docker,但是Docker Remote API又不能设置密码,就代表着所有人都可以访问。通过设置TLS认证,客户端在调用Docker Remote API的时候就需要携带签发的证书,如果证书验证通过才能调用API。

签发证书

用这个脚本自动生成证书,在运行之前需要修改配置信息。

  • CODE,起个代号,生成证书文件的时候作为后缀,以便区分;
  • IP,机器的公网IP;
  • PASSWORD,在签发证书时用的密码。
#!/bin/bash
# 
# -------------------------------------------------------------
# 自动创建 Docker TLS 证书
# -------------------------------------------------------------

# 以下是配置信息
# --[BEGIN]------------------------------

CODE="tx"
IP="1.1.1.1"
PASSWORD="pass"
COUNTRY="CN"
STATE="BEIJING"
CITY="BEIJING"
ORGANIZATION="Org"
ORGANIZATIONAL_UNIT="Dev"
COMMON_NAME="$IP"
EMAIL="."

# --[END]--

# Generate CA key
openssl genrsa -aes256 -passout "pass:$PASSWORD" -out "ca-key-$CODE.pem" 4096
# Generate CA
openssl req -new -x509 -days 365 -key "ca-key-$CODE.pem" -sha256 -out "ca-$CODE.pem" -passin "pass:$PASSWORD" -subj "/C=$COUNTRY/ST=$STATE/L=$CITY/O=$ORGANIZATION/OU=$ORGANIZATIONAL_UNIT/CN=$COMMON_NAME/emailAddress=$EMAIL"
# Generate Server key
openssl genrsa -out "server-key-$CODE.pem" 4096

# Generate Server Certs.
openssl req -subj "/CN=$COMMON_NAME" -sha256 -new -key "server-key-$CODE.pem" -out server.csr

echo "subjectAltName = IP:$IP,IP:127.0.0.1" >> extfile.cnf
echo "extendedKeyUsage = serverAuth" >> extfile.cnf

openssl x509 -req -days 365 -sha256 -in server.csr -passin "pass:$PASSWORD" -CA "ca-$CODE.pem" -CAkey "ca-key-$CODE.pem" -CAcreateserial -out "server-cert-$CODE.pem" -extfile extfile.cnf

# Generate Client Certs.
rm -f extfile.cnf

openssl genrsa -out "key-$CODE.pem" 4096
openssl req -subj '/CN=client' -new -key "key-$CODE.pem" -out client.csr
echo extendedKeyUsage = clientAuth >> extfile.cnf
openssl x509 -req -days 365 -sha256 -in client.csr -passin "pass:$PASSWORD" -CA "ca-$CODE.pem" -CAkey "ca-key-$CODE.pem" -CAcreateserial -out "cert-$CODE.pem" -extfile extfile.cnf

rm -vf client.csr server.csr

chmod -v 0400 "ca-key-$CODE.pem" "key-$CODE.pem" "server-key-$CODE.pem"
chmod -v 0444 "ca-$CODE.pem" "server-cert-$CODE.pem" "cert-$CODE.pem"

# 打包客户端证书
mkdir -p "tls-client-certs-$CODE"
cp -f "ca-$CODE.pem" "cert-$CODE.pem" "key-$CODE.pem" "tls-client-certs-$CODE/"
cd "tls-client-certs-$CODE"
tar zcf "tls-client-certs-$CODE.tar.gz" *
mv "tls-client-certs-$CODE.tar.gz" ../
cd ..
rm -rf "tls-client-certs-$CODE"

# 拷贝服务端证书
mkdir -p /etc/docker/certs.d
cp "ca-$CODE.pem" "server-cert-$CODE.pem" "server-key-$CODE.pem" /etc/docker/certs.d/

将脚本内容保存为 auto-tls-certs.sh,使用 sh auto-tls-certs.sh 来生成证书,并且生成好的证书会被自动打包为 .tar.gz,非常方便。

配置Docker

只需关注.pem文件,把证书找个专门的位置存放。

mkdir /etc/.docker
cp ~/docker-cert/*.pem /etc/.docker/

修改 Docker 启动文件。

nano /lib/systemd/system/docker.service

修改Service下的ExecStart配置。

ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock -D -H tcp://0.0.0.0:2376 --tlsverify --tlscacert=/etc/.docker/ca-tx.pem --tlscert=/etc/.docker/server-cert-tx.pem --tlskey=/etc/.docker/server-key-tx.pem

重启Docker。

systemctl daemon-reloadservice docker restart

开放端口

在防火墙、安全组中放行2376端口。

测试

把证书的压缩包tls-client-certs-tx.tar.gz下载到本机,解压得到证书文件。

curl命令测试,如果有JSON格式的信息输出则配置成功。

curl https://你的IP/info --cert cert-tx.pem --key key-tx.pem --cacert ca-tx.pem

用Portainer连接

Portainer是一款非常好用的Docker可视化管理工具,通过暴露Docker Remote API可以远程连接并管理Docker资源。

在Endpoints页面中点击“Add endpoint”,Environment type选择Docker。

在对应的输入框中填写IP地址和端口号,开启TLS,选择三个对应的证书文件。

参考资料

脚注

[^1]: Quick Start - Documentation

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇