配置Let's Encrypt & certbot

来自个人维基
跳转到导航 跳转到搜索

由于我们拥有服务器的命令行访问权限,故直接使用 Certbot ACME 客户端。 它可以在不下线您的服务器的前提下自动执行证书颁发和安装。 对于不需要自动配置的用户,Certbot 还提供专家模式。

官网:https://certbot.eff.org

Apache环境

安装依赖包

sudo apt update
sudo apt install python3 python3-venv libaugeas0
  • Debian7只支持python3.2,而python3-venv要3.3或以上版本才支持,故无法安装。

设置安装环境:

sudo python3 -m venv /opt/certbot/
sudo /opt/certbot/bin/pip install --upgrade pip

安装

sudo /opt/certbot/bin/pip install certbot certbot-apache

配置软链接,便于执行命令:

sudo ln -s /opt/certbot/bin/certbot /usr/bin/certbot

获取证书并使用

运行此命令获取证书并让Certbot自动编辑您的Apache配置以使用它(如果担心风险,可以在执行此步骤前备份 sites-enabled/000-default 和 sites-enabled/default-ssl):

sudo certbot --apache #只申请主域名
sudo certbot --apache -d example.com -d www.example.com #多个别名一起申请
  • 如果这里报错“ValueError: Invalid version. The only valid version for X509Req is 0.”,则是 pyOpenSSL版本不匹配(如 pyOpenSSL 23.2.0),需要指定版本:
/opt/certbot/bin/pip install pyOpenSSL==23.1.1

至此,应该新的ssl证书就生效了(一般有效期是3个月)。
可以用以下检测ssl证书包含的域名:

openssl x509 -in /etc/letsencrypt/live/example.com/cert.pem -noout -text | grep DNS

设置自动更新证书任务

echo "0 0,12 * * * root /opt/certbot/bin/python -c 'import random; import time; time.sleep(random.random() * 3600)' && sudo certbot renew -q" | sudo tee -a /etc/crontab > /dev/null

当然,也可以手动强制更新:

certbot renew --force-renewal
  • 注意这里renew时会完全按上次申请时的config进行renew(如之前申请时包含多个子域名,则renew时也将包含)

定期(官方建议Monthly)更新 certbot

sudo /opt/certbot/bin/pip install --upgrade certbot certbot-apache

如果出错:
If this step leads to errors, run sudo rm -rf /opt/certbot and repeat all installation instructions.

Ngnix环境

在 Nginx + Django 的架构上配置 Let's Encrypt 证书,最稳定、最推荐的方式是使用 Certbot 的 Nginx 插件。它会自动修改 Nginx 配置来完成 SSL 握手,然后将加密后的流量安全地传递给后端的 Django 应用 。

整个配置流程可以分为以下三个核心步骤:

1. 准备工作

在开始之前,请确保满足以下条件,否则 Certbot 会验证失败:

域名解析:确保你的域名(例如 example.com)已经解析到了服务器的公网 IP。

开放端口:确保服务器防火墙(如 ufw)和云服务商的安全组已放行 80 (HTTP) 和 443 (HTTPS) 端口 。

Nginx 配置:确保你已有一个监听 80 端口的 Nginx 配置文件,并且可以通过 HTTP 正常访问你的网站。

2. 安装 Certbot 并自动获取证书

这是最关键的步骤,我们将使用 Certbot 的 Nginx 插件,它会自动处理 SSL 证书的申请和 Nginx 配置的修改。

安装 Certbot 及 Nginx 插件:
在 Ubuntu/Debian 系统上,运行以下命令安装:

bash
sudo apt update
sudo apt install certbot python3-certbot-nginx -y

注:这个 python3-certbot-nginx 插件是实现自动化配置的关键 。

运行 Certbot 获取证书:
执行以下命令,Certbot 将自动识别 Nginx 配置中的 server_name,为你获取证书并修改配置。

bash
sudo certbot --nginx -d example.com -d www.example.com

注:将 example.com 和 www.example.com 替换为你自己的域名。

按提示完成交互:

输入你的邮箱地址(用于接收证书过期提醒和安全通知)。

同意 Let's Encrypt 的服务条款。

3. 配置 Django 以识别 HTTPS

Certbot 虽然修改了 Nginx,但 Django 默认认为来自代理的流量是 HTTP。如果不做调整,Django 可能会生成 http 开头的链接,甚至导致安全错误。

在你的 Django 项目的 settings.py 文件中,找到或添加以下代码:

python
# settings.py

# 1. 将你的域名添加到允许列表
ALLOWED_HOSTS = ['example.com', 'www.example.com']

# 2. 告诉 Django 信任 Nginx 传递的 HTTPS 头信息
# 这行代码非常关键,它告诉 Django:如果请求头里包含 HTTP_X_FORWARDED_PROTO,并且它的值是 https,就认为请求是安全的
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')

# 3. 确保 Cookie 只通过 HTTPS 传输
CSRF_COOKIE_SECURE = True
SESSION_COOKIE_SECURE = True

# 4. (可选)如果 Nginx 已经处理了重定向,这里建议设为 False,避免无限重定向循环
# SECURE_SSL_REDIRECT = False

注意:如果你的 Nginx 配置中 Certbot 已经帮你设置了 return 301 https://... 的重定向规则,则不需要在 Django 中再开启 SECURE_SSL_REDIRECT,否则可能会造成重定向循环 。

修改完 settings.py 后,需要重启 Django 应用服务(如 gunicorn 或 uwsgi)使配置生效。

4. 验证与自动续期

验证:
打开浏览器,访问 https://yourdomain.com,检查地址栏是否有小锁标志;
你还可以运行以下命令来测试证书的自动续期功能是否正常:

sudo certbot renew --dry-run

自动续期:Let's Encrypt 证书有效期为 90 天。Certbot 安装后会自带一个 systemd timer 或 cron 任务,每天自动检查并续期,你无需额外操心。续期后,Certbot 会自动重载 Nginx 配置 。