certbot➕ nginx➕docker 免费申请网站https证书

certbot➕ nginx➕docker 免费申请网站https证书

2023-07-17
编程开发

Certbot是一个开源工具,它是由Let's Encrypt提供的官方客户端,用于自动化获取、更新和安装Let's Encrypt证书。 优点:免费。 缺点:证书非永久,需要定期更新

申请证书

docker run --rm -it \
  -e TZ=Asia/Shanghai \
  -v "${PWD}/certs/:/etc/letsencrypt/" \
  -v "${PWD}/logs/:/var/log/letsencrypt/" \
  -p 18080:80 \
  certbot/certbot certonly --standalone -d <需要申请证书的域名,如:smpt.example.com>

原理

当certbot程序运行后,letsencrypt服务器会访问目标域名的80端口(因为此时没有证书,只能访问80端口),访问路径为 "GET /.well-known/acme-challenge/YqE1g3IcgPC3PwIK7ZxNJdiU5nQimQrx6PsK8yAbvfI HTTP/1.1" 200 98 "-" "Mozilla/5.0 (compatible; Let's Encrypt validation server; +https://www.letsencrypt.org)" "-" 服务器接收到GET请求后,被nginx转发到本机的18080端口,18080端口刚好又映射了certbot容器的80端口,然后certbot程序会去完成这个acme-challenge,完成后letencrypt服务器会向访问的域名颁发证书,30天之后过期,需要再次续订

参数说明

  • ${PWD}/certs 生成的证书会保存在这个文件夹
  • ${PWD}/logs 日志文件
  • -p 18080:80 将certbot的80端口映射到服务器的非80端口,并用nginx进行转发,避免出现端口被占用的问题

nginx转发

server {
    listen 80;
    server_name [需要申请https证书的域名];

    location / {
        proxy_pass http://localhost:18080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

证书自动续订

为刚才申请到的证书文件夹${PWD}/certs/赋予可读权限

chmod -R a+r certs/

把certs目录挂载到nginx容器中

-v /home/docker/dms/certbot/certs/:/etc/certs

申请证书只需要80端口,但是证书的续订要用到443端口,将443端口转发到certbot容器中

server {
    listen 443 ssl http2;
    server_name <申请证书的域名>;

    # 证书的挂载的路径
    ssl_certificate /etc/certs/live/域名/fullchain.pem;
    ssl_certificate_key /etc/certs/live/域名/privkey.pem;

    location / {
        # 在这里,14443端口是certbot容器443端口的映射
        proxy_pass http://localhost:14443;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

创建一个certbot-renew.sh脚本

# 删除之前的logs文件夹,避免log文件夹无限制递增
rm -rf logs

docker run --rm -i \
  -e TZ=Asia/Shanghai \
  -v "${PWD}/certs/:/etc/letsencrypt/" \
  -v "${PWD}/logs/:/var/log/letsencrypt/" \
  -p 18080:80 \
  -p 14443:443 \
  certbot/certbot renew

(自己先试着运行一下这个脚本)

❗注意:crontab运行docker命令时,docker run后面不能加-t参数,会报错“the input device is not a TTY”

最后,在你的服务器上,添加一条crontab任务,脚本要写成绝对路径,配置好之后保存退出, 输入crontab -l检查crontab是否配置成功

# 每天0点执行一次certbot-renew.sh
0 0 * * * cd [脚本所在目录] && /bin/bash start-certbot-renew.sh

总结

经过上面一折腾,域名的https证书就搞定了,保存在${PWD}/certs/目录下,其他docker容器挂载一下就能用

THE END
0/500
暂无评论