encrypt certificate 证书更新详解

encrypt certificate 证书更新详解

原理说明

  1. 通过certbot容器,将宿主机上映射的证书文件,通过域名方式续期更新。
  2. 通过nginx容器,读取宿主机上映射的证书文件,供博客https访问

========== 证书操作部分 ===========

1. 创建certbot容器
   a. 见下文贴的docker-compose.yaml配置文件
   b. 将该配置文件放到某个目录下,执行docker-compose up -d创建容器

certbot:
  container_name: "certbot"
  image: certbot/certbot:v1.14.0
  privileged: true
  tty: true
  stdin_open: true
  volumes:
    - /etc/letsencrypt:/etc/letsencrypt # 将容器更新的证书,映射在宿主机
    - /var/lib/letsencrypt:/var/lib/letsencrypt
  entrypoint: "/bin/sh" # 必须使用 entrypoint 而不是 command, 以重写 certbot image 的 entrypoint

2. 创建证书(dns方式验证)
   a. 了解证书验证方式:验证方式有两种,在网站下创建静态文件,或dns加一条解析,通过--preferred-challenges这个参数指定,不指定的默认方式之前是dns,但最近变成了静态文件方式,所以还是自己指定一下比较好。
   b. 进certbot容器:容器已创建,并在对应目录下执行命令进容器,docker-compose exec certbot sh
   c. 怎么创建证书?容器内执行,certbot certonly -a manual --preferred-challenges=dns-01(后续交互会提示输入邮箱、域名、验证要求),执行过程原文见下

[ghost@instance-20210526-1514 certbot]$ docker-compose exec certbot sh
/opt/certbot # certbot certonly -a manual --preferred-challenges=dns-01
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator manual, Installer None
Enter email address (used for urgent renewal and security notices)
 (Enter 'c' to cancel): ***@***.***

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must
agree in order to register with the ACME server. Do you agree?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: Y

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing, once your first certificate is successfully issued, to
share your email address with the Electronic Frontier Foundation, a founding
partner of the Let's Encrypt project and the non-profit organization that
develops Certbot? We'd like to send you email about our work encrypting the web,
EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: Y
Account registered.
Please enter in your domain name(s) (comma and/or space separated)  (Enter 'c'
to cancel): atibm.com
Requesting a certificate for ghost.atibm.com
Performing the following challenges:
dns-01 challenge for ghost.atibm.com

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please deploy a DNS TXT record under the name
_acme-challenge.ghost.atibm.com with the following value:

Md183vHytSH7ZUxrJkCCfRQtTdaPbkq47c3r0REbu0Q

Before continuing, verify the record is deployed.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Press Enter to Continue
Waiting for verification...
Cleaning up challenges
Subscribe to the EFF mailing list (email: ***@***.***).

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/ghost.atibm.com/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/ghost.atibm.com/privkey.pem
   Your certificate will expire on 2021-08-25. To obtain a new or
   tweaked version of this certificate in the future, simply run
   certbot again. To non-interactively renew *all* of your
   certificates, run "certbot renew"
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le
/opt/certbot # exit

3. 删除和查看证书命令
   a. 怎么删除证书?在容器内执行,certbot delete --cert-name ghost.atibm.com
   b. 怎么查看证书有效期?certbot certificates执行效果如下

/opt/certbot # certbot certificates
Saving debug log to /var/log/letsencrypt/letsencrypt.log

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Found the following certs:
  Certificate Name: ghost.atibm.com
    Serial Number: 336402f715a5e2e8d9a37e60f3ef22bebdc
    Key Type: RSA
    Domains: ghost.atibm.com
    Expiry Date: 2021-08-25 04:34:08+00:00 (VALID: 29 days)
    Certificate Path: /etc/letsencrypt/live/ghost.atibm.com/fullchain.pem
    Private Key Path: /etc/letsencrypt/live/ghost.atibm.com/privkey.pem
  Certificate Name: ghost.atibm.com
    Serial Number: 4dc16882a468e352fe437d1e10c0bae5bf7
    Key Type: RSA
    Domains: ghost.atibm.com
    Expiry Date: 2021-08-25 23:53:11+00:00 (VALID: 29 days)
    Certificate Path: /etc/letsencrypt/live/ghost.atibm.com/fullchain.pem
    Private Key Path: /etc/letsencrypt/live/ghost.atibm.com/privkey.pem
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

4. 更新证书续期(dns方式)
   a. 重点说明:证书需要定期renew更新有效期,网上可以找到N个教程,自动更新,sh程序封装,手动更新……这里记录一下我的成功操作
   b. 怎么更新证书?容器内执行一行命令:certbot certonly -d ghost.atibm.com --preferred-challenges dns --server https://acme-v02.api.letsencrypt.org/directory --manual
   c. 域名的txt解析:到域名商的控制面板增加一条txt解析,_acme-challenge.ghost.atibm.com解析为提示的验证码MD9K7IAp3an9bXAZUj88eYwxn_zyhdfXG0FQEFxWrIs
 d. 无脑完成后续提示操作即可,另外完成续期之后,我的docker nginx读取证书仍是旧的,docker-compose restart 之后就好了
 

---------------------命令参数说明---------------
--preferred-challenges dns # 域名验证方式:dns解析
--manual # 交互式执行
--server https://acme-v02.api.letsencrypt.org/directory # 申请证书的服务器
-d ghost.atibm.com # 申请证书的域名

---------------------执行过程-------------------
[ghost@instance-20210526-1514 nginx]$ cd /www/certbot
[ghost@instance-20210526-1514 certbot]$ docker-compose exec certbot sh
/opt/certbot # certbot certonly -d ghost.atibm.com --preferred-challenges dns --server https://acme-v02.api.letsencrypt.org/directory --manual
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator manual, Installer None
Cert is due for renewal, auto-renewing...
Renewing an existing certificate for ghost.atibm.com
Performing the following challenges:
dns-01 challenge for ghost.atibm.com

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please deploy a DNS TXT record under the name
_acme-challenge.ghost.atibm.com with the following value:

MD9K7IAp3an9bXAZUj88eYwxn_zyhdfXG0FQEFxWrIs

Before continuing, verify the record is deployed.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Press Enter to Continue
Waiting for verification...
Cleaning up challenges

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/ghost.atibm.com/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/ghost.atibm.com/privkey.pem
   Your certificate will expire on 2022-03-01. To obtain a new or
   tweaked version of this certificate in the future, simply run
   certbot again. To non-interactively renew *all* of your
   certificates, run "certbot renew"
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

========== nginx部分 ===========

提示:刚才的各种操作,仅仅是用了一个certbot容器,在容器内的目录下,创建和更新维护一份证书文件,仅仅这样操作,并不能将证书用到你的网站https上

  1. 证书文件传递原理解释
    certbot容器维护的证书目录 -> 映射宿主机目录 -> 映射nginx容器 -> nginx的conf.d配置读取nginx容器ssl证书文件 -> 用户访问你的https网站成功
    这个链路就是用户访问读取ssl过程。
  2. certbot容器的证书映射到宿主机:
    在certbot的docker-compose.yml文件里的volumes设置,增加一行
    - /etc/letsencrypt:/etc/letsencrypt
  3. nginx容器映射到宿主机的证书地址:
    在nginx的docker-compose.yml文件里的volumes设置,增加一行
    - /etc/letsencrypt:/etc/letsencrypt
  4. nginx的conf.d网站配置文件增加https设置:
    a. 直接贴配置,留意其中443 ssl端口监听和ssl文件地址
#server {
#    listen 80;
#    server_name ghost.atibm.com;
#    location / {
#        proxy_pass http://172.17.0.1:2368;
#    }
#}

server {
    listen 80;
    server_name ghost.atibm.com;
    return 301 https://$server_name$request_uri;
}


server {
    listen 443 ssl;
    server_name ghost.atibm.com;
    ssl_certificate     /etc/letsencrypt/live/ghost.atibm.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/ghost.atibm.com/privkey.pem;
    root /var/lib/ghost/current/core/server/public;
    access_log /var/log/nginx/ghost-access.log;
    error_log /var/log/nginx/ghost-error.log;
    location / {
        proxy_pass         http://ghost:2368;
        proxy_set_header     Host $host;
        proxy_set_header     X-Real-IP $remote_addr;
        proxy_set_header    X-Forwarded-Proto https;
        proxy_set_header     X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_connect_timeout     150;
        proxy_send_timeout     100;
        proxy_read_timeout    100;
        proxy_buffers        4 32k;
        client_max_body_size    10m;
        client_body_buffer_size    128;    
    }
}

通过以上的证书文件映射,主要实现了2个关键操作:

  1. certbot容器维护nginx所访问的证书文件
  2. nginx容器设置ghost网站配置的ssl地址

最终实现了用户访问https网站成功,以及每三个月的证书更新