缘起
想做个微信小程序,把娃们的网站,在微信里展现给老人看,而做微信小程序,要求网站是 https 的,我也舍不得买证书,于是就打算使用 Let's Encrypt 提供的免费证书。
环境
- Ubuntu 16.04.1 LTS
- NGINX 1.10
- kernel 4.9.4-040904-generic
步骤
安装软件
apt-get -y install letsencrypt;
# letsencrypt 是 Let's Encrypt 官方软件
# certbot 在 Ubuntu 16.04 上的名字
获取证书
letsencrypt certonly \
--webroot \
-w /opt/www/blog.xiaoyuer.cn \
-d blog.xiaoyuer.cn;
letsencrypt certonly
--webroot \
-w /opt/www/blog.lukeyang.us \
-d blog.lukeyang.us;
# 这里 blog.xiaoyuer.cn 和 blog.lukeyang.us 是娃的网站
# 其实支持在一条命令里用多个 -w 参数配合 -d 参数,
# 为什么没有这样做而是单独一条命令一个域名这么做呢,
# 主要是不想把所有证书放在一起......
#
# 获取证书过程中会弹出个窗口让输入邮件地址,
# 输入一个常用的即可
Generate Strong Diffie-Hellman Group(optional)
openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048;
# 密钥交换时使用更强的 2048 位密钥
配置 NGINX 的 ssl 参数(optional)
cat <<EOF >/etc/nginx/snippets/ssl-params.conf
# from https://cipherli.st/
# and https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
ssl_ecdh_curve secp384r1;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
#resolver 8.8.8.8 8.8.4.4 valid=300s;
#resolver_timeout 5s;
# Disable preloading HSTS for now. You can use the commented out header line that includes
# the "preload" directive if you understand the implications.
#add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains";
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
EOF
# 如果没有做上一步,最后 ssl_dhparam 那句请注释掉
NGINX 的虚拟机配置
vim /etc/nginx/sites-enabled/blog.xiaoyuer.cn;
在 server {} 配置块中添加如下内容:
listen 443 ssl http2 default_server;
include snippets/ssl-params.conf;
ssl_certificate /etc/letsencrypt/live/blog.xiaoyuer.cn/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/blog.xiaoyuer.cn/privkey.pem;
location ~ /.well-known {
allow all;
}
同样的,
vim /etc/nginx/sites-enabled/blog.lukeyang.us;
在 server {} 配置块中添加如下内容:
listen 443 ssl http2;
include snippets/ssl-params.conf;
ssl_certificate /etc/letsencrypt/live/blog.lukeyang.us/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/blog.lukeyang.us/privkey.pem;
location ~ /.well-known {
allow all;
}
注意:
这个配置里的 listen 443 ssl httpd2 一行并没有 default_server 字样,那是一个端口因为只能有一个 default_server,前面那个虚机已经在 443 端口上指定了 default_server,所以这里不能重复指定了
重启 NGINX 服务
systemctl restart nginx.service;
配置自动更新证书
由于 Let's Encrypt 的证书会在三个月后过期,但是官方工具提供了自动更新的功能,我们只需要用 cron 定时调用即可。
cat <<EOF >/etc/cron.d/renew_ssl
25 3 * * 3 root /usr/bin/letsencrypt renew>/var/log/le-renew.log"
35 3 * * 3 root /bin/systemctl reload nginx
EOF
这里的逻辑是每周(三)检查一次是否需要更新证书,如果需要,则自动更新证书。检查完,再做一次 nginx 的 reload 操作,重新载入新证书(如果有的话)。