学习是一个逐步发现自己无知的过程!

Portainer 使用 TLS 加密连接远端节点上的 Docker Portainer 使用 TLS 加密

默认情况下,Docker 通过非联网的 UNIX 套接字运行。它还可以选择使用 SSH 或 TLS (HTTPS) 套接字进行通信。

由于Portainer管理的是容器主机,安全手段不能没有,不加密的连接就等于将主机送给别人,Portainer也支持了TLS连接。

现在立马就把安全手段加上、但 Docker 的 TLS 极其繁琐,需要一系列的证书、私钥生成,在 Mac 上或者 Linux 上生成都可以。

1、首先就是生成证书

官方也提供了详细的文章:https://docs.docker.com/engine/security/protect-access/

服务器证书

  • 新建一个目录,因为生成的文件太多了
mkdir tls
cd tls
  • 生成根证书 RSA 私钥,过程中需要设置密码,待会儿需要用到,不要忘记。
[root@prometheus tls]# openssl genrsa -aes256 -out ca-key.pem 4096

Generating RSA private key, 4096 bit long modulus
....++
...........................................................................++
e is 65537 (0x10001)
Enter pass phrase for ca-key.pem:
Verifying - Enter pass phrase for ca-key.pem:
  • 生成 ca 证书(这里指定证书有效期365天,根证书 HOST 指定为 lckiss-docker.com ,以自己的私钥签发的证书,也就是自己给自己签发证书)。
[root@prometheus tls]# openssl req -new -x509 -days 365 -key ca-key.pem -sha256 -subj "/CN=lckiss-docker.com" -out ca.pem

Enter pass phrase for ca-key.pem:
  • 生成服务器私钥
[root@prometheus tls]# openssl genrsa -out server-key.pem 4096

Generating RSA private key, 4096 bit long modulus
...........................++
...........................................................++
e is 65537 (0x10001)

此时目录结构为:

  • 生成服务的证书签名请求(可在证书请求中定义允许访问的 ip,想了解可以访问官方文档:https://docs.docker.com/engine/security/protect-access/
[root@prometheus tls]# openssl req -subj "/CN=lckiss-docker.com" -sha256 -new -key server-key.pem -out server.csr
  • 生成服务器证书
[root@prometheus tls]# openssl x509 -req -days 365 -sha256 -in server.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem

Signature ok
subject=/CN=lckiss-docker.com
Getting CA Private Key
Enter pass phrase for ca-key.pem:

服务器的证书告一段落,用自己的私钥创建了一个 ca 根证书,再用 ca 证书签发了一个服务器证书。依次为根证书私钥、ca 证书、服务器证书私钥、服务器证书

生成证书的过程过于繁琐,这里用写了个脚本。

#!/bin/bash
# 
# -------------------------------------------------------------
# 自动创建 Docker TLS 凭证
# -------------------------------------------------------------

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

CODE="por"  
IP="10.150.3.21" #Docker主机IP
PASSWORD="1234"
COUNTRY="CN"
STATE="ShangHai"
CITY="ShangHai"
ORGANIZATION="ep"
ORGANIZATIONAL_UNIT="Dev"
COMMON_NAME="$IP"
EMAIL="sirliux@foxmail.com"

# --[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" 

客户端证书

  • 生成客户端证书私钥
[root@prometheus tls]# openssl genrsa -out key.pem 4096
  • 生成客户端证书请求(host 为 lckiss-mac.com)
[root@prometheus tls]# openssl req -subj '/CN=lckiss-mac.com' -new -key key.pem -out client.csr
  • 使用最开始的 ca 证书来生成客户端证书(需要输入 ca 证书密码)
[root@prometheus tls]# openssl x509 -req -days 365 -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem \
  -CAcreateserial -out cert.pe
Signature ok
subject=/CN=lckiss-mac.com
Getting CA Private Key
Enter pass phrase for ca-key.pem:
  • 删除无用文件
rm -v client.csr server.csr ca.srl 

密钥生成完了,主要是生成了这两个文件:

将生成的证书文件,放到docker主机随后需要使用。

2、修改docker启动文件

现在可以让 Docker 守护进程只接受来自提供 CA 信任的证书的客户端的连接:

编辑启动文件

vim /usr/lib/systemd/system/docker.service

修改ExecStart

ExecStart=/usr/bin/dockerd   --tlsverify \
    --tlscacert=/root/tls/ca-por.pem \
    --tlscert=/root/tls/cert-por.pem \
    --tlskey=/root/tls/key-por.pem  \
    -H tcp://0.0.0.0:2375 -H fd:// -H unix:///var/run/docker.sock

修改的内容

dockerd \
    --tlsverify \
    --tlscacert=ca.pem \
    --tlscert=server-cert.pem \
    --tlskey=server-key.pem

测试证书

找一台主机测试证书的可用性。

[root@pro tls]# curl -k https://{Docker站点IP}:2375/info --cert ./cert-por.pem --key ./key-por.pem
{"ID":"MYRG:IFEC:X3ZD:F74G:2OTF:JAQT:Q4XF:EHXH:QBNK:OVKJ:732Q:EJAA","Containers":28,"ContainersRunning":21,"ContainersPaused":0,"ContainersStopped":7,"Images":72,"Driver":"overlay2","DriverStatus":[["Backing Filesystem","xfs"],["Supports d_type","true"],["Native Overlay Diff","true"]],"SystemStatus":null,"Plugins":{"Volume":["local"],"Network":["bridge","host","ipvlan","macvlan","null","overlay"],"Authorization":null,"Log":["awslogs","fluentd","gcplogs","gelf","journald","json-file","local","logentries","splunk","syslog"]},"MemoryLimit":true,"SwapLimit":true,"KernelMemory":true,"KernelMemoryTCP":true,"CpuCfsPeriod":true,"CpuCfsQuota":true,"CPUShares":true,"CPUSet":true,"PidsLimit":true,"IPv4Forwarding":true,"BridgeNfIptables":false,"BridgeNfIp6tables":false,"Debug":false,"NFd":148,"OomKillDisable":true,"NGoroutines":120,"SystemTime":"2021-11-30T17:08:16.862021235+08:00","LoggingDriver":"json-file","CgroupDriver":"cgroupfs","NEventsListener":0,"KernelVersion":"3.10.0-862.el7.x86_64","OperatingSystem":"CentOS Linux 7 (Core)","OSType":"linux","Architecture":"x86_64","IndexServerAddress":"https://index.docker.io/v1/","RegistryConfig":{"AllowNondistributableArtifactsCIDRs":[],"AllowNondistributableArtifactsHostnames":[],"InsecureRegistryCIDRs":["127.0.0.0/8"],"IndexConfigs":{"docker.io":{"Name":"docker.io","Mirrors":["https://n6ei3rs2.mirror.aliyuncs.com/"],"Secure":true,"Official":true}},"Mirrors":["https://n6ei3rs2.mirror.aliyuncs.com/"]},"NCPU":1,"MemTotal":4143456256,"GenericResources":null,"DockerRootDir":"/var/lib/docker","HttpProxy":"","HttpsProxy":"","NoProxy":"","Name":"localhost.localdomain","Labels":[],"ExperimentalBuild":false,"ServerVersion":"19.03.12","ClusterStore":"","ClusterAdvertise":"","Runtimes":{"runc":{"path":"runc"}},"DefaultRuntime":"runc","Swarm":{"NodeID":"","NodeAddr":"","LocalNodeState":"inactive","ControlAvailable":false,"Error":"","RemoteManagers":null},"LiveRestoreEnabled":false,"Isolation":"","InitBinary":"docker-init","ContainerdCommit":{"ID":"7ad184331fa3e55e52b890ea95e65ba581ae3429","Expected":"7ad184331fa3e55e52b890ea95e65ba581ae3429"},"RuncCommit":{"ID":"dc9208a3303feef5b3839f4323d9beb36df0a9dd","Expected":"dc9208a3303feef5b3839f4323d9beb36df0a9dd"},"InitCommit":{"ID":"fec3683","Expected":"fec3683"},"SecurityOptions":["name=seccomp,profile=default"],"Warnings":["WARNING: bridge-nf-call-iptables is disabled","WARNING: bridge-nf-call-ip6tables is disabled"]}

file

3、通过TLS添加主机

添加方法和普通添加一样,不同的是需要勾选上"TLS" 并将生成的证书上传到Portainer。

file

赞(0)
未经允许不得转载:劉大帥 » Portainer 使用 TLS 加密连接远端节点上的 Docker

你的评论可能会一针见血! 抢沙发

登录

找回密码

注册