一个开启 Docker 远程 TLS和CA认证 访问的一键脚本
Docker是目前很流行的一个平台工具。虽然我比较喜欢用命令行使用docker,但是用类似Portainer的可视化面板管理docker也是个不错的选择,检查docker的配置和状态都非常便捷。 Portainer不止能管理本机的docker,通过docker api ,进行一定的配置,可以通过网络远程连接和管理其它机器上的docker容器。具体教程可以参见以下两个链接: Docker开启TLS和CA认证 配置Docker 远程访问TLS 认证 - 乌帮图 但是每次新建一台VPS后,按照这些命令输入来开启docker的远程访问实在是太繁琐了,于是我整理了一下相关命令,编制了一个脚本,一键执行来完成相关配置。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 #!/bin/bash root_need(){ if [[ $EUID -ne 0 ]]; then echo "Error:这个脚本必须以root身份运行!" exit 1 fi } # 检查docker是否已经安装 if ! command -v docker &> /dev/null then echo "Docker未安装,开始安装Docker..." # 安装Docker wget -qO- get.docker.com | bash systemctl enable docker # 输出安装结果 docker --version else echo "Docker已经安装" # 输出Docker版本 docker --version fi # 获取主机的 IP 地址 IP=$(curl -s http://ipv4.icanhazip.com) # 设置证书目录 CERT_DIR="/root/docker_data/ca" mkdir -p "$CERT_DIR" # 生成 CA 证书 openssl genrsa -aes256 -passout pass:changepasswd -out "$CERT_DIR/ca-key.pem" 4096 openssl req -new -x509 -days 365 -key "$CERT_DIR/ca-key.pem" -passin pass:changepasswd -sha256 -out "$CERT_DIR/ca.pem" \ -subj "/C=US/ST=New York/L=New York/O=Example Company/OU=IT Department/CN=example.com/[email protected]" # 生成服务器证书 openssl genrsa -out "$CERT_DIR/server-key.pem" 4096 openssl req -subj "/CN=$(hostname)" -sha256 -new -key "$CERT_DIR/server-key.pem" -out "$CERT_DIR/server.csr" echo "subjectAltName = DNS:$(hostname),IP:$IP" > "$CERT_DIR/extfile.cnf" read -p "你想添加一个受信任的域名吗? (y/n): " add_domain if [ "$add_domain" == "y" ]; then read -p "输入域名: " domain_name echo "subjectAltName = DNS:$domain_name" >> "$CERT_DIR/extfile.cnf" echo "将$domain_name添加到受信任域列表中" else echo "跳过将域添加到受信任域列表的步骤" fi echo "extendedKeyUsage = serverAuth" >> "$CERT_DIR/extfile.cnf" openssl x509 -req -days 365 -sha256 -in "$CERT_DIR/server.csr" -CA "$CERT_DIR/ca.pem" -CAkey "$CERT_DIR/ca-key.pem" -CAcreateserial -out "$CERT_DIR/server-cert.pem" -extfile "$CERT_DIR/extfile.cnf" -passin pass:changepasswd # 生成客户端证书 openssl genrsa -out "$CERT_DIR/client-key.pem" 4096 openssl req -subj '/CN=client' -new -key "$CERT_DIR/client-key.pem" -out "$CERT_DIR/client.csr" echo "extendedKeyUsage = clientAuth" > "$CERT_DIR/client-extfile.cnf" openssl x509 -req -days 365 -sha256 -in "$CERT_DIR/client.csr" -CA "$CERT_DIR/ca.pem" -CAkey "$CERT_DIR/ca-key.pem" -CAcreateserial -out "$CERT_DIR/client-cert.pem" -extfile "$CERT_DIR/client-extfile.cnf" -passin pass:changepasswd # 生成 Docker 配置文件 cp /usr/lib/systemd/system/docker.service /usr/lib/systemd/system/docker.service.bak sed -i "s|^ExecStart=.*$|ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2376 -H fd:// --containerd=/run/containerd/containerd.sock --tlsverify --tlscacert=${CERT_DIR}/ca.pem --tlscert=${CERT_DIR}/server-cert.pem --tlskey=${CERT_DIR}/server-key.pem|" /usr/lib/systemd/system/docker.service # 重新加载 Docker 服务 systemctl daemon-reload systemctl restart docker # 检查 Docker 服务是否正常启动 if systemctl is-active --quiet docker; then echo -e "Docker TLS配置已经成功完成。" else # Docker 服务启动失败, 恢复原配置并报错 echo "Error: docker服务启动失败。恢复到原来的配置..." cp /usr/lib/systemd/system/docker.service.bak /usr/lib/systemd/system/docker.service systemctl daemon-reload systemctl restart docker echo "docker服务已被恢复到原始配置。" exit 1 fi # 配置证书自动更新脚本 cat > $CERT_DIR/renewcert.sh <<'EOF' #!/bin/bash CURRENT_TIME=$(date +"%F %T") # check if CA certificate is expired if openssl x509 -checkend 1728000 -noout -in $(dirname "$0")/ca.pem; then echo "[$CURRENT_TIME] CA certificate is still valid" >> $(dirname "$0")/crontab_log.txt else echo "[$CURRENT_TIME] CA certificate has expired. Renewing all certificates..." >> $(dirname "$0")/crontab_log.txt # regenerate server and client certificates using existing CA openssl req -new -x509 -days 365 -key "$(dirname "$0")/ca-key.pem" -passin pass:changepasswd -sha256 -out "$(dirname "$0")/ca.pem" \ -subj "/C=US/ST=New York/L=New York/O=Example Company/OU=IT Department/CN=example.com/[email protected]" openssl x509 -req -days 365 -sha256 -in "$(dirname "$0")/server.csr" -CA "$(dirname "$0")/ca.pem" -CAkey "$(dirname "$0")/ca-key.pem" -CAcreateserial -out "$(dirname "$0")/server-cert.pem" -extfile "$(dirname "$0")/extfile.cnf" -passin pass:changepasswd openssl x509 -req -days 365 -sha256 -in "$(dirname "$0")/client.csr" -CA "$(dirname "$0")/ca.pem" -CAkey "$(dirname "$0")/ca-key.pem" -CAcreateserial -out "$(dirname "$0")/client-cert.pem" -extfile "$(dirname "$0")/client-extfile.cnf" -passin pass:changepasswd systemctl daemon-reload systemctl restart docker echo "[$CURRENT_TIME] All certificates have been renewed" >> $(dirname "$0")/crontab_log.txt fi EOF # 配置脚本定时任务 chmod +x $CERT_DIR/renewcert.sh crontab -l | { cat; echo "0 0 */15 * * bash $CERT_DIR/renewcert.sh"; } | crontab - 执行成功后应该如下图所示: ...