Let’s Encrypt是由互联网安全研究组(ISRG)授权开发的免费、自动化和开放的SSL证书。
Let’s Encrypt颁发的证书目前已得到各主流浏览器信任,每次签有都有 90 天的有效期。所以如果个人轻度使用,我们可以利用Let’s Encrypt来签发SSL证书。
本指南将逐步演示如何在 Ubuntu 20.04 上安装免费的加密 SSL 证书,并使用该证书在 Web 服务器Nginx上运行。除此之外,我们还将展示如何配置 Nginx 以使用 SSL 证书并启用 HTTP/2。
内容列表
先决依赖
在开始之前,请务必你的环境已经满足了以下的要求:
- 你有一个域名,并且有一个公共IP地址指向该域名,这里我以esharing.net为例
- 你的Ubuntu20.04已经安装了Nginx
- 确保你的防火墙已开放80与443端口
安装Certbot
我们将利用Cerbot这个工具来获取证书,并定期更新证书。
Certbot是一款功能全面并且容易使用的工具,可自动完成获取和更新“Let’s Encrypt” SSL证书。
Certbot已经在Ubuntu20.04的软件库里,所以我们可以直接运行以下命令进行安装:
sudo apt update
sudo apt install certbot
生成强DH(Diffie-Hellman)组
Diffie–Hellman Key Exchange(DH)是一种通过不安全的通信通道安全交换加密密钥的方法。
通过键入以下命令我们可以生成一组新的 2048 位 DH 参数:
sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
你也可以把2048改成4096,使得生成的是一个4096位的密钥,不过生成过程会耗时比较长,我试过将近30分钟才完成,这也取决于你的服务器性能。
获取Let’s Encrypt SSL 证书
域名所有权验证
- 对于单一域名证书,多数情况下推荐使用webroot插件,因为它可以在不影响你的既有web服务器的情况下生成证书。webroot工作原理为:通过既有的web服务器向外暴露访问接口(需要通过域名能访问得到),在运行certbot命令时指定需要向外暴露访问的目录(通过
--webroot-path
或-w
指定),cerbot在于Let‘s Encrypt通信过程中会将挑战文件放在指定文件夹(${webroot-path}/.well-known/acme-challenge
)下,然后Let’s Encrypt会通过域名访问该文件 - 通过DNS,如果你拥有该域名,那么Let’s Encrypt会让你在该域名下设置一个TXT记录,记录值设置成Let’s Encrypt所要求的(在运行certbot时会提示),做到这一点则可以证明你的确拥有对该域名的拥有权。这种方式通常用于通配符证书,certbot无需运行在域名指向的服务器上。
在这里,因为我们只生成单一域名证书,我们选用第一种验证方式,但我们更加简单把所有/.well-know/acme-challenge
的HTTP请求全部转到 /var/lib/letsencrypt
下面的命令是创建相关的文件夹设定Nginx服务有写入权限
sudo mkdir -p /var/lib/letsencrypt/.well-known
sudo chgrp www-data /var/lib/letsencrypt
sudo chmod g+s /var/lib/letsencrypt
为了避免重复的代码,我们将创建两个snippets文件,并放到Nignx服务器配置文件夹中
使用nano创建并编辑文件第一个snippets文件”letsencrypt.conf
“
sudo nano /etc/nginx/snippets/letsencrypt.conf
/etc/nginx/snippets/letsencrypt.conf
location ^~ /.well-known/acme-challenge/ {
allow all;
root /var/lib/letsencrypt/;
default_type "text/plain";
try_files $uri =404;
}
创建第二个snippets文件:ssl.conf,让其支持Mozillo要求的chippers,开启OCSP Stapling,HSTS(HTTP Strict Transport Security),强制不安全的HTTP Headers
sudo nano /etc/nginx/snippets/ssl.conf
/etc/nginx/snippets/ssl.conf
ssl_dhparam /etc/ssl/certs/dhparam.pem;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers on;
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 30s;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;
这两个snippets文件创建成功后,我们需要把这两个配置文件添加到Nignx的配置参数server下面:
sudo nano /etc/nginx/sites-available/esharing.net.conf
/etc/nginx/sites-available/esharing.net.conf
server {
listen 80;
server_name esharing.net www.esharing.net;
include snippets/letsencrypt.conf;
}
我们把这个配置文件生成一个软链接到/etc/nginx/sites-enabled文件夹中使其生效:
sudo ln -s /etc/nginx/sites-available/esharing.net.conf /etc/nginx/sites-enabled/
重启Nginx服务,使新的配置文件生效:
sudo systemctl restart nginx
获取自签SSL证书
上面的配置都完成后,我们就可以使用Cerbot及插件webroots来获取SSL 证书文件:
sudo certbot certonly --agree-tos --email admin@esharing.net --webroot -w /var/lib/letsencrypt/ -d esharing.net -d www.esharing.net
如果获取成功的话,你将来收到像下面一样的信息:
IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/esharing.net/fullchain.pem
Your key file has been saved at:
/etc/letsencrypt/live/esharing.net/privkey.pem
Your cert will expire on 2021-10-18. To obtain a new or tweaked
version of this certificate in the future, simply run certbot
again. To non-interactively renew *all* of your certificates, run
"certbot renew"
- Your account credentials have been saved in your Certbot
configuration directory at /etc/letsencrypt. You should make a
secure backup of this folder now. This configuration directory will
also contain certificates and private keys obtained by Certbot so
making regular backups of this folder is ideal.
- If you like Certbot, please consider supporting our work by:
Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
Donating to EFF: https://eff.org/donate-le
现在你就有你自己域名的SSL证书,存放在/etc/letsencrypt/live/esharing.net/里面。现在我们编辑我们域名的Nginx 配置文件:
sudo nano /etc/nginx/sites-available/esharing.net.conf
/etc/nginx/sites-available/esharing.net.conf
server {
listen 80;
server_name www.esharing.net esharing.net;
include snippets/letsencrypt.conf;
return 301 https://$host$request_uri;
}
//www跳转到non-www
server {
listen 443 ssl http2;
server_name www.esharing.net;
ssl_certificate /etc/letsencrypt/live/esharing.net/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/esharing.net/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/esharing.net/chain.pem;
include snippets/ssl.conf;
include snippets/letsencrypt.conf;
return 301 https://esharing.net$request_uri;
}
server {
listen 443 ssl http2;
server_name esharing.net;
ssl_certificate /etc/letsencrypt/live/esharing.net/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/esharing.net/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/esharing.net/chain.pem;
include snippets/ssl.conf;
include snippets/letsencrypt.conf;
# . . . other code
}
上面的配置我们已经把生成的证书加载进Nginx,并把www跳转到non-www.
最后重启Nginx生效所有新的配置
sudo systemctl reload nginx
打开浏览,以”https://“访问你的域名,如果地址栏的加密锁完好不报错,证明你已成功部署。
你也可以通过SSL证书测试网站 来验证,如果一切没有错的话,你将可以得到A+的得分!
自动更新证书有效期
由于我们获得的证书只有3个月有效期,如果每次到期后都需要人工去获取新的证书,那将是一个非常麻烦的事,所以我们可以通过自动化计划任务来定期获取SSL证书
我们先判断certbot是否正常运行:
sudo certbot renew --dry-run
如果显示下面信息则表示已正常运行:
...
Congratulations, all renewals succeeded.
...
那就编写cron脚 本,让自动运行更新命令:
sudo nano /etc/cron.d/certbot
/etc/cron.d/certbot
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
0 */12 * * * root test -x /usr/bin/certbot -a \! -d /run/systemd/system && perl -e 'sleep int(rand(3600))' && certbot -q renew --renew-hook "systemctl reload nginx"
以上脚本每天运行2次,但是只有在证书即将过期的时候才会真正执行renew操作。
写在最后
如果你想了解更多关于certbot的使用,请查看官方文档