使用 Let’s Encrypt 证书支持 Nginx https

863 阅读3分钟

Let’s Encrypt 是一个自由开放的证书颁发系统,有免费版和付费版。下面记录 Let’s Encrypt 生成证书,配合 Nginx 支持 https 访问的步骤。

环境

Ubuntu 16.04 Nginx 1.10.3 测试域名: test.domain.cn

安装 certbot

certbot 是一个自动获取 Let‘s Encrypt 证书的客户端,通过一些插件,比如 Nginx 插件,certbot 在自动安装证书的同时,还能帮我们自动更新 Nginx 配置文件。

sudo apt-get install certbot python-certbot-nginx 

由于我们 web server 是 Nginx,所以安装的是 python-certbot-nginx插件。如果 web server 是其他,比如 Apache,则需要安装其他插件。具体需要安装何种插件及安装方法,参见 certbot 文档 cerbot 安装

生成证书

sudo certbot --nginx -d test.domain.cn

生成证书命令会调用使用 Nginx 的80端口测试,因此要求 Nginx 配置文件正确,正常启动且80端口未被占用。可以通过 --server 选项更改测试地址。 上面的生成证书命令会更改 Nginx 配置文件,为了避免自己的配置文件被弄乱,我比较倾向于只安装证书,执行下面的命令不会更改 Nginx 配置文件。

sudo certbot --nginx certonly -d test.domain.cn

更改 Nginx 配置文件

Let'st Encrypt 默认安装在 /etc/letsencrypt/live/域名下,更新 Nginx 修改下面两行,指向新生成的证书文件

ssl_certificate  /etc/letsencrypt/live/beauty.yimeijian.cn/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/beauty.yimeijian.cn/privkey.pem;

完整的 Nginx https 配置:

server {
    listen 8000 default_server;
    listen [::]:8000 default_server;
    listen 443;
    ssl on;
    server_name test.domain.cn;
    ssl_certificate  /etc/letsencrypt/live/test.domain.cn/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/test.domain.cn/privkey.pem;
    ssl_session_timeout 5m;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;
    location / {
        proxy_pass http://localhost:8100; 
    }
}

根据 web 应用程序启动方式不同,配置也会不一样,但是都需要打开 ssl,即 ssl on

自动更新证书

Let's Encrypt 生成的证书默认只有90天有效期,要自动更新证书,执行下面命令

sudo certbot renew -d test.domain.cn

可以通过 cron 活 timer 增加定时任务更新。具体方法参见文末增加定时任务

实践笔记

1, certbot 从 v0.28.0 后开始移除对 TLS-SNI-01 的支持。如果版本过低,需要卸载重新安装最新版本。但是我在某些Ubuntu 16.04 上却怎么也安装不上最新版本(相同的系统某些机器可以,主要是python 包报异常No module named 'apt_pkg'导致,尝试很多方式还是会报这个错,参见How to stop using TLS-SNI-01 with Certbot)。目前我的解决方案是直接从GitHub 克隆源码,直接执行 ./certbot-auto

增加定时任务

cron 方式

crontab -e
* 12 * * * certbot -q renew
sudo service cron start

timer 方式 在 /usr/lib/systemd/system 目录下新建两个文件 certbot.service ,certbot.timer, 内容如下 certbot.service

[Unit]
Description=Certbot
Documentation=file:///usr/share/doc/python-certbot-doc/html/index.html
Documentation=https://letsencrypt.readthedocs.io/en/latest/
[Service]
Type=oneshot
ExecStart=/usr/bin/certbot -q renew
PrivateTmp=true

certbot.timer

[Unit]
Description=Run certbot twice daily

[Timer]
OnCalendar=*-*-* 00,12:00:00
RandomizedDelaySec=43200
Persistent=true

[Install]
WantedBy=timers.target

启动timer

sudo systemctl start certbot.timer

下次开机自启动timer

sudo systemctl enable certbot.timer