## 什么是 Let's Encrypt Let's Encrypt 是一个免费、自动化和开放的证书颁发机构(Certificate Authority, CA),其目的是使获得和安装 SSL/TLS 证书的过程自动化,以便网站能够通过 HTTPS 提供加密的通信。 ## 生成证书 下面演示 Ubunut 系统操作步骤 ```Shell # 工具安装 $ sudo apt update $ sudo apt install snapd $ sudo snap install --classic certbot $ sudo ln -s /snap/bin/certbot /usr/bin/certbot # 生成证书 $ sudo certbot certonly --standalone -d domain.com # Successfully received certificate. # Certificate is saved at: /etc/letsencrypt/live/domain.com/fullchain.pem # Key is saved at: /etc/letsencrypt/live/domain.com/privkey.pem # 验证续签 $ sudo certbot renew # 查看证书 $ sudo certbot certificates # 删除证书 $ sudo certbot delete --cert-name ${域名} ``` ## 使用 Nginx 配置 HTTPS 证书 由于 Let's Encrypt 在验证域名时需要占用 80 端口,这可能与现有 Web 服务器产生端口冲突。为了解决该问题,可以使用 `webroot` 参数的方式进行验证。以下是一个通过 Docker 运行 Nginx 并申请证书的完整示例。 1. 生成证书 ```shell $ mkdir certbot-webroot $ sudo certbot certonly --key-type rsa --webroot -w ./certbot-webroot -d domain.com $ sudo certbot certonly --key-type rsa --webroot -w ./certbot-webroot -d www.domain.com ``` 2. nginx 配置文件 ```conf server { listen 80; listen [::]:80; server_name domain.com www.domain.com; location /.well-known/acme-challenge/ { root /var/www/certbot-webroot/; } location / { return 301 https://domain.com$request_uri; } } server { listen 443 ssl; listen [::]:443 ssl; server_name www.domain.com; ssl_certificate /etc/letsencrypt/live/www.domain.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/www.domain.com/privkey.pem; return 301 https://domain.com$request_uri; } server { listen 443 ssl; listen [::]:443 ssl; server_name domain.com; ssl_certificate /etc/letsencrypt/live/domain.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/domain.com/privkey.pem; index index.html index.htm; root /var/www/html; server_tokens off; } ``` 3. docker-compose 配置文件 ```yaml services: ngx: image: nginx:latest container_name: ngx ports: - "80:80" - "443:443" restart: always volumes: - /etc/letsencrypt:/etc/letsencrypt - ./certbot-webroot:/var/www/certbot-webroot - # 这里忽略其他 nginx 配置文件映射 ``` 4. 验证是否生效 ```shell $ sudo certbot certonly --key-type rsa --webroot -w ./certbot-webroot -d domain.com --dry-run # 提示 The dry run was successful. 字样说明成功了 ``` 5. 测试续签 ``` $ sudo certbot renew --dry-run --webroot -w ./certbot-webroot ``` ## 自动续签 使用 `crontab` 工具定时续签 ```shell # 编辑 crontab crontab -e # 添加每天凌晨2点执行续签命令,如果证书有更新时重启 Nginx 0 2 * * * /usr/bin/certbot renew --quiet --deploy-hook "docker restart ngx" >> /var/log/letsencrypt/renewal_log.txt 2>&1 ``` ## 参考 - https://letsencrypt.org/zh-cn/docs/ - https://certbot.eff.org/instructions?ws=other&os=ubuntufocal