docker环境下的网站接入免费SSL证书并实现自动续签功能

目前,腾讯云免费SSL证书有效期将从12个月缩短至3个月,其他服务商SSL证书有效期也减短。网站过多懒得手动更新ssl证书,因此准备为网站接入免费SSL证书 let’s encrypt 并用 acme.sh 实现自动续签功能

0. 环境

Ubuntu 22.04.3 LTS

Nginx + docker

CONTAINER ID   IMAGE                 COMMAND                  CREATED        STATUS                     PORTS                                                                      NAMES
fa4xxxxxx45f   nginx:1.17.9          "nginx -g 'daemon of…"   7 months ago   Up 3 months                0.0.0.0:80->80/tcp, :::80->80/tcp, 0.0.0.0:443->443/tcp, :::443->443/tcp   nginx

域名 test.pnut.top

网站根目录 /docker/www/project/

证书存放路径 /docker/usr/nginx/conf/conf.d/ca/ -> 容器内 /etc/nginx/conf.d/ca/

1. 安装 acme.sh

安装很简单, 一个命令:

curl https://get.acme.sh | sh -s email=mail@pnut.top

如果国内安装失败可用以下命令:

git clone https://gitee.com/neilpang/acme.sh.git
cd acme.sh
./acme.sh --install -m mail@pnut.top

安装过程进行了以下几步:

1.把 acme.sh 安装到你的 home 目录下:

~/.acme.sh/

并创建 一个 shell 的 alias, 例如 .bashrc,方便你的使用: alias acme.sh=~/.acme.sh/acme.sh

2.自动为你创建 cronjob, 每天 0:00 点自动检测所有的证书, 如果快过期了, 需要更新, 则会自动更新证书.

2. 生成证书

http 方式需要在网站根目录下放置一个文件, 来验证你的域名所有权,完成验证. 然后就可以生成证书了.

nginx配置文件下需加配置:

server {
  listen 443 ssl http2;
  listen [::]:443 ssl http2;
  root   /docker/www/project/;
  index   index.php index.html index.htm;
  server_name test.pnut.top;

  ssl_certificate     /etc/nginx/conf.d/ca/test.pnut.top.pem;
  ssl_certificate_key /etc/nginx/conf.d/ca/test.pnut.top.key;

  ssl_session_timeout 1d;
  ssl_session_cache shared:MozSSL:10m; # about 40000 sessions
  ssl_session_tickets off;
  ssl_protocols TLSv1.2 TLSv1.3;
  ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
  ssl_prefer_server_ciphers off;
   
  access_log /var/log/nginx/test.pnut.top.access.log;
  error_log /var/log/nginx/test.pnut.top.error.log;
  error_page 404 /404.html;
  error_page 500 502 503 504 /50x.html;
   
  location / {
  ...
  }


###下方为新加配置
  location ~ \.well-known{
      allow all;
  }
  ###上方为新加配置

}

执行命令:

acme.sh --issue -d test.pnut.top --webroot /docker/www/project/

执行结果:

[Fri May  3 03:45:01 PM CST 2024] Using CA: https://acme.zerossl.com/v2/DV90
[Fri May 3 03:45:01 PM CST 2024] Creating domain key
[Fri May 3 03:45:01 PM CST 2024] The domain key is here: /root/.acme.sh/...
...
[Fri May 3 03:45:08 PM CST 2024] Processing, The CA is processing your order, please just wait. (1/30)
[Fri May 3 03:45:12 PM CST 2024] Success
[Fri May 3 03:45:12 PM CST 2024] Verify finished, start to sign.
[Fri May 3 03:45:12 PM CST 2024] Lets finalize the order.
...
[Fri May 3 03:45:31 PM CST 2024] Downloading cert.
...
[Fri May 3 03:45:32 PM CST 2024] Cert success.

3. copy/安装 证书

前面证书生成以后, 接下来需要把证书 copy 到真正需要用它的地方.

注意, 默认生成的证书都放在安装目录下: ~/.acme.sh/, 请不要直接使用此目录下的文件, 例如: 不要直接让 nginx/apache 的配置文件使用这下面的文件. 这里面的文件都是内部使用, 而且目录结构可能会变化.

执行命令:

acme.sh --install-cert -d test.pnut.top \
--key-file       /docker/usr/nginx/conf/conf.d/ca/test.pnut.top.key \
--fullchain-file /docker/usr/nginx/conf/conf.d/ca/test.pnut.top.pem \
--reloadcmd     "docker exec -it nginx service nginx force-reload"

执行结果:

[Fri May  3 03:46:00 PM CST 2024] Installing key to: /docker/usr/nginx/conf/conf.d/ca/test.pnut.top.key
[Fri May 3 03:46:00 PM CST 2024] Installing full chain to: /docker/usr/nginx/conf/conf.d/ca/test.pnut.top.pem
[Fri May 3 03:46:00 PM CST 2024] Run reload cmd: docker exec -it nginx service nginx force-reload
[ ok ] Reloading nginx: nginx.
[Fri May 3 03:46:00 PM CST 2024] Reload success

4. 更新证书

目前证书在 60 天以后会自动更新, 你无需任何操作. 今后有可能会缩短这个时间, 不过都是自动的, 你不用关心.

请确保 crontab 正常运行, 看起来是类似这样的:

root@VM-12-7-ubuntu:~# crontab  -l

36 0 * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" > /dev/null

参考资料

https://github.com/acmesh-official/acme.sh

acme.sh中文说明

上一篇