使用Let’s Encrypt的Certbot为Nginx网站自动配置SSL证书并续期

· 3225字 · 7分钟 · 阅读量

要在Docker容器中的Nginx使用Certbot的certonly模式获取证书,您可以按照以下步骤操作:

(一)创建Nginx容器 🔗

  1. 创建Nginx容器: 如果您还没有Nginx容器,请先创建一个。以下是一个简单的示例:

     docker run -itd -p 80:80 -p 443:443 --name https-nginx -e TZ=Asia/Shanghai --restart always -v /usr/local/src/nginx/conf.d:/etc/nginx/conf.d -v /usr/local/src/nginx/log:/var/log/nginx nginx:1.25.0-bullseye
    

    这会创建一个名为 my-nginx 的Nginx容器,并将主机的端口80映射到容器的端口80,端口443映射到容器的端口443。

    在宿主机/usr/local/src/nginx/conf.d目录中放入nginx配置文件default.conf:

    
     server {
         listen       80;
         listen  [::]:80;
         server_name  localhost;
    
         #access_log  /var/log/nginx/host.access.log  main;
    
         location / {
             root   /usr/share/nginx/html;
             index  index.html index.htm;
         }
    
         #error_page  404              /404.html;
    
         # redirect server error pages to the static page /50x.html
         #
         error_page   500 502 503 504  /50x.html;
         location = /50x.html {
             root   /usr/share/nginx/html;
         }
     }
    

(二)进入Nginx容器 🔗

  1. 进入Nginx容器: 使用以下命令进入Nginx容器的bash shell:

    docker exec -it https-nginx /bin/bash
    

(三)安装Certbot 🔗

  1. 安装Certbot: 在Nginx容器内,安装Certbot。具体步骤可能因Linux发行版而异。以下是在Debian/Ubuntu上的示例:

    apt-get update
    apt-get install certbot
    

(四)获取证书 🔗

  1. 获取证书: 运行Certbot以获取证书。确保Nginx容器内的80端口是可访问的,因为Certbot通常使用HTTP验证来确认您对域名的控制权。

    certbot certonly --webroot -w /usr/share/nginx/html -d yourdomain.com你的域名
    

    在上述命令中,请将 yourdomain.com 替换为您要为其获取证书的域名。-w /usr/share/nginx/html 参数告诉Certbot在Nginx的默认HTML目录中查找验证文件。

(五)配置Nginx使用证书 🔗

  1. 配置Nginx使用证书: 在Nginx容器中,将证书和私钥的路径添加到Nginx配置文件中。打开Nginx配置文件,通常在 /etc/nginx/nginx.conf/etc/nginx/conf.d/default.conf

    nano /etc/nginx/nginx.conf
    

    nano /etc/nginx/conf.d/default.conf
    

    在宿主机/usr/local/src/nginx/conf.d目录nginx配置文件default.conf中添加SSL配置,如下所示:

    
     server {
         listen       80;
         listen  [::]:80;
         server_name  你的域名;
         rewrite ^(.*)$ https://${server_name}$1 permanent;
         #access_log  /var/log/nginx/host.access.log  main;
    
         location / {
             root   /usr/share/nginx/html;
             index  index.html index.htm;
         }
    
         #error_page  404              /404.html;
    
         # redirect server error pages to the static page /50x.html
         #
         error_page   500 502 503 504  /50x.html;
         location = /50x.html {
             root   /usr/share/nginx/html;
         }
     }
    
     server {
         listen 443 ssl;
         server_name 你的域名;
    
         ssl_certificate /etc/letsencrypt/live/你的域名/fullchain.pem;
         ssl_certificate_key /etc/letsencrypt/live/你的域名/privkey.pem;
    
         location ^~ /.well-known/acme-challenge/ {
             allow all;
             root /usr/share/nginx/html;
         }
    
         # Other SSL configurations...
    
         location / {
         #配置阿里云内网地址,也可以使用docker的network连接
             proxy_pass                 http://IP地址:端口;
             proxy_redirect             off;
             proxy_set_header           Host             $host;
             proxy_set_header           X-Real-IP        $remote_addr;
             proxy_set_header           X-Forwarded-For  $proxy_add_x_forwarded_for;
         }
     }
    

    请确保替换 yourdomain.com 为您的实际域名。

(六)重启Nginx 🔗

  1. 重启Nginx: 保存并关闭配置文件,并重新启动Nginx服务:

    nginx -s reload
    

现在,您的Nginx容器应该已经配置为使用通过Certbot获取的SSL证书。请注意,证书在90天后过期,您需要设置定期更新的计划任务或使用Certbot的自动更新功能。

(七)运行certbot certonly 🔗

  1. certbot certonly运行步骤:

root@d162442980ab:/usr/share/nginx/html# certbot certonly --webroot -w /usr/share/nginx/html -d yourdomain.com替换为您要为其获取证书的域名
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator webroot, Installer None
Enter email address (used for urgent renewal and security notices)
 (Enter 'c' to cancel): ***********@163.com你的联系联系邮箱

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.3-September-21-2022.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.
Requesting a certificate for yourdomain.com
Performing the following challenges:
http-01 challenge for yourdomain.com
Using the webroot path /usr/share/nginx/html for all unmatched domains.
Waiting for verification...
Cleaning up challenges
Subscribe to the EFF mailing list (email: ***********@163.com).

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/www.yourdomain.com/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/www.yourdomain.com/privkey.pem
   Your certificate will expire on 2024-04-26. 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

使用Certbot的certonly模式获取证书后,您可以使用 certbot renew 命令来更新证书。Certbot提供了一个自动续订的机制,通过运行 certbot renew 可以检查所有已安装证书的有效期,如果证书将在30天内过期,Certbot将尝试自动续订它们。

(八)Certbot续订 🔗

  1. Certbot手动测试续订和自动续订证书:

    1. 手动测试续订: 在运行自动续订之前,您可以先手动测试一下是否可以成功续订证书。运行以下命令:

      certbot renew --dry-run
      

      --dry-run选项用于模拟续订,而不会实际更新证书。这可以帮助您验证是否存在潜在的问题。

    2. 自动续订证书: 使用以下命令执行实际的证书续订:

      certbot renew
      

      这将检查所有已安装证书的有效期,如果某个证书将在30天内过期,Certbot将尝试自动续订它。

    3. 设置定时任务: 为了确保证书在到期前能够自动续订,建议将 certbot renew 命令设置为定时任务。您可以使用systemd timer来定期运行 certbot renew。以下是一个systemd timer的示例:

      Systemd定时器配置 🔗

      1. Systemd定时器单元文件 certbot-renew.timer
      [Unit]
      Description=Run certbot renew daily
      
      [Timer]
      OnCalendar=daily
      Persistent=true
      
      [Install]
      WantedBy=timers.target
      

      在此配置中,OnCalendar 字段设置为 daily,表示每天执行一次。

      1. Systemd服务单元文件 certbot-renew.service
      [Unit]
      Description=Renew Let's Encrypt certificates with certbot
      Requires=docker.service
      After=docker.service
      
      [Service]
      Type=oneshot
      ExecStart=/bin/bash -c 'echo "$(date)" && docker exec https-nginx certbot renew'
      StandardOutput=file:/var/log/certbot-renew.log
      StandardError=inherit
      

      这个Systemd服务单元文件用于定期使用Certbot更新Let’s Encrypt证书。下面是每个部分的详细说明:

      • Description:描述了服务的目的,即使用Certbot更新Let’s Encrypt证书。

      • RequiresAfter:这两个字段指定了服务所依赖的其他服务以及服务的启动顺序。在这种情况下,服务依赖于docker.service,并在其之后启动。

      • [Service]:定义了服务的配置参数。

      • Type=oneshot:指定服务的类型为一次性任务,即服务将在执行完毕后立即退出。

      • ExecStart:指定了服务启动时要执行的命令。这里的命令使用docker exec命令在名为https-nginx的Docker容器中运行certbot renew命令,以更新证书。$(date)用于记录当前时间,以便在日志中进行跟踪。

      • StandardOutput:定义了标准输出的目标。在这里,标准输出被重定向到/var/log/certbot-renew.log文件中,以便将更新的日志信息保存到文件中。

      • StandardError:定义了标准错误输出的目标。在这里,标准错误输出被继承到父进程,即与标准输出一样。

      通过这个服务单元文件,您可以定期更新Let’s Encrypt证书,并将更新的日志信息保存到指定的日志文件中,以便进行跟踪和排查问题。

      1. 将这两个文件放置在 Systemd 单元文件的存储路径中,通常是 /etc/systemd/system/ 目录。

      2. 启用并启动定时器:

      sudo systemctl daemon-reload
      sudo systemctl enable certbot-renew.timer
      sudo systemctl start certbot-renew.timer
      

      现在,Systemd 定时器将每天执行一次 docker exec <container_id_or_name> certbot renew 命令,并将输出写入日志文件中。

      自动启动 🔗

      一旦您通过 sudo systemctl enable certbot-renew.timer 命令启用了定时器,并且通过 sudo systemctl start certbot-renew.timer 命令启动了定时器,它将会在系统重启后自动运行。

      Systemd 在系统启动时会自动加载所有已启用的单元文件,并在适当的时间重新启动这些单元文件中定义的服务或定时器。因此,一旦您启用并启动了 certbot-renew.timer 定时器,它就会在系统重启后继续按照您配置的计划执行。

      如果您想要在系统启动后确认定时器是否正常运行,您可以使用以下命令来检查其状态:

      sudo systemctl status certbot-renew.timer
      

      这将显示定时器的状态信息,包括它最近一次的运行状态和计划的下一次运行时间。

       这将每天在午夜执行 `certbot renew`。请根据您的需求调整 cron job 的定时设置。
      
      1. 监控续订过程: 定期检查 Certbot 的日志,确保续订过程没有报错。您可以查看 Certbot 的日志文件,通常位于 /var/log/letsencrypt/ 目录下。

确保设置自动续订是很重要的,因为Let’s Encrypt证书的有效期只有90天,手动更新可能不够及时,而自动续订可以确保您的证书持续保持有效。