要在Docker容器中的Nginx使用Certbot的certonly
模式获取证书,您可以按照以下步骤操作:
(一)创建Nginx容器 🔗
-
创建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容器 🔗
-
进入Nginx容器: 使用以下命令进入Nginx容器的bash shell:
docker exec -it https-nginx /bin/bash
(三)安装Certbot 🔗
-
安装Certbot: 在Nginx容器内,安装Certbot。具体步骤可能因Linux发行版而异。以下是在Debian/Ubuntu上的示例:
apt-get update apt-get install certbot
(四)获取证书 🔗
-
获取证书: 运行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使用证书 🔗
-
配置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 🔗
-
重启Nginx: 保存并关闭配置文件,并重新启动Nginx服务:
nginx -s reload
现在,您的Nginx容器应该已经配置为使用通过Certbot获取的SSL证书。请注意,证书在90天后过期,您需要设置定期更新的计划任务或使用Certbot的自动更新功能。
(七)运行certbot certonly 🔗
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续订 🔗
-
Certbot手动测试续订和自动续订证书:
-
手动测试续订: 在运行自动续订之前,您可以先手动测试一下是否可以成功续订证书。运行以下命令:
certbot renew --dry-run
--dry-run
选项用于模拟续订,而不会实际更新证书。这可以帮助您验证是否存在潜在的问题。 -
自动续订证书: 使用以下命令执行实际的证书续订:
certbot renew
这将检查所有已安装证书的有效期,如果某个证书将在30天内过期,Certbot将尝试自动续订它。
-
设置定时任务: 为了确保证书在到期前能够自动续订,建议将
certbot renew
命令设置为定时任务。您可以使用systemd timer来定期运行certbot renew
。以下是一个systemd timer的示例:Systemd定时器配置 🔗
- Systemd定时器单元文件
certbot-renew.timer
:
[Unit] Description=Run certbot renew daily [Timer] OnCalendar=daily Persistent=true [Install] WantedBy=timers.target
在此配置中,
OnCalendar
字段设置为daily
,表示每天执行一次。- 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证书。
-
Requires 和 After:这两个字段指定了服务所依赖的其他服务以及服务的启动顺序。在这种情况下,服务依赖于docker.service,并在其之后启动。
-
[Service]:定义了服务的配置参数。
-
Type=oneshot:指定服务的类型为一次性任务,即服务将在执行完毕后立即退出。
-
ExecStart:指定了服务启动时要执行的命令。这里的命令使用
docker exec
命令在名为https-nginx
的Docker容器中运行certbot renew
命令,以更新证书。$(date)
用于记录当前时间,以便在日志中进行跟踪。 -
StandardOutput:定义了标准输出的目标。在这里,标准输出被重定向到
/var/log/certbot-renew.log
文件中,以便将更新的日志信息保存到文件中。 -
StandardError:定义了标准错误输出的目标。在这里,标准错误输出被继承到父进程,即与标准输出一样。
通过这个服务单元文件,您可以定期更新Let’s Encrypt证书,并将更新的日志信息保存到指定的日志文件中,以便进行跟踪和排查问题。
-
将这两个文件放置在 Systemd 单元文件的存储路径中,通常是
/etc/systemd/system/
目录。 -
启用并启动定时器:
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 的定时设置。
- 监控续订过程: 定期检查 Certbot 的日志,确保续订过程没有报错。您可以查看 Certbot 的日志文件,通常位于
/var/log/letsencrypt/
目录下。
- Systemd定时器单元文件
-
确保设置自动续订是很重要的,因为Let’s Encrypt证书的有效期只有90天,手动更新可能不够及时,而自动续订可以确保您的证书持续保持有效。