如果要启用HTTPS,我们就需要从证书授权机构(以下简称CA) 处获取一个证书,Let’s Encrypt 就是一个 CA。我们可以从 Let’s Encrypt 获得网站域名的免费的证书。这篇文章也主要讲的是通过 Let’s Encrypt + Nginx 来让网站升级到HTTPS。
Certbot 是Let’s Encrypt官方推荐的获取证书的客户端,可以帮我们获取免费的Let’s Encrypt 证书。Certbot 是支持所有 Unix 内核的操作系统的,像centos、ubuntu、Debian等系统都是可以的安装使用的,我习惯用ubuntu系统,所以本文将以ubuntu系统为例,nginx配置ssl证书,使网站走上https的小康之路。
搬瓦工是有隐藏的优惠码的,博主写了脚本,每天去更新最新优惠码(最高6%以上折扣):搬瓦工优惠码
vultr购买也有优惠,注册送50刀,教程附上:vultr优惠购买和连接服务器(推荐)
sudo apt-get -y install certbot
certbot certonly --webroot -w /var/www/example -d example.com -d www.example.com
这个命令会为 example.com
和 www.example.com
这两个域名生成一个证书(当然,你也可以只写一个,多个域名根域名要相同),使用 --webroot
模式会在 /var/www/example
中创建 .well-known
文件夹,这个文件夹里面包含了一些验证文件,certbot 会通过访问 example.com/.well-known/acme-challenge
来验证你的域名是否绑定的这个服务器。这个命令在大多数情况下都可以满足需求,
但是有些时候我们的一些服务并没有根目录,这时候使用 --webroot
就走不通了。certbot 还有另外一种模式 --standalone
, 这种模式不需要指定网站根目录,他会自动启用服务器的443端口,来验证域名的归属。我们有其他服务(例如nginx)占用了443端口,就必须先停止这些服务,在证书生成完毕后,再启用。
certbot certonly --standalone -d example.com -d www.example.com
证书生成完毕后,我们可以在 /etc/letsencrypt/live/
目录下看到对应域名的文件夹,里面存放了指向证书的一些快捷方式。
下面以我的博客域名viencoding.com
做个示例:
我博客的根目录 /apps/vienblog/public
(也就是直接用域名加上该目录下资源文件名就可以访问到的目录,比如我在/apps/vienblog/public
下放一个test.txt文件,我直接访问 http://域名或者ip/test.txt
就可以访问到test.txt
这个文件,那么/apps/vienblog/public
就是根目录),然后只给viencoding.com
申请SSL证书:
certbot certonly --webroot -w /apps/vienblog/public -d viencoding.com
然后没问题的话根据提示输入内容,首先是邮箱,输入后回车,其次是告诉你一些霸王条款,是否同意,输入A
同意然后回车,再就是想给你发邮件问你乐意不乐意,输入Y
乐意,然后回车:
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator webroot, Installer None
Enter email address (used for urgent renewal and security notices) (Enter 'c' to
cancel): shavien1202@gmail.com
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must
agree in order to register with the ACME server at
https://acme-v02.api.letsencrypt.org/directory
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(A)gree/(C)ancel: A
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing to share your email address with the Electronic Frontier
Foundation, a founding partner of the Let's Encrypt project and the non-profit
organization that develops Certbot? We'd like to send you email about our work
encrypting the web, EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: Y
完事之后,会告诉你证书的存储位置、过期时间以及如何续费等信息:
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator webroot, Installer None
Obtaining a new certificate
IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/viencoding.com/fullchain.pem
Your key file has been saved at:
/etc/letsencrypt/live/viencoding.com/privkey.pem
Your cert will expire on 2020-01-30. 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"
- 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
通过以上信息我们得知,生成的两个文件分别在/etc/letsencrypt/live/viencoding.com/fullchain.pem
和/etc/letsencrypt/live/viencoding.com/privkey.pem
(通常情况下是在 /etc/letsencrypt/live/你的域名/
文件夹下),然后告诉我们会在 2020-01-30
过期,其实就是三个月时间,然后下面告诉我们可以用certbot renew
去续费所有申请过的证书(它会记录你在这台机器上申请证书的命令记录,然后帮你重新执行,到期前一个月内才可以申请新的证书)
至此,生成SSL证书的任务完成了,接下来就是配置我们的web服务器,启用HTTPS。
certbot certonly --preferred-challenges dns --manual -d *.域名 --server https://acme-v02.api.letsencrypt.org/directory
我使用的是Nginx 服务器来转发请求,这里贴一下我的Nginx配置(默认的配置是在/etc/nginx/sites-available/default
)
server {
listen 80;
server_name viencoding.com;
return 301 https://viencoding.com$request_uri;
}
server {
listen 443 ssl;
ssl on;
ssl_certificate /etc/letsencrypt/live/viencoding.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/viencoding.com/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;
root /apps/vienblog/public;
index index.php index.html index.htm;
server_name viencoding.com;
if ( $host != 'viencoding.com' ) {
rewrite ^/(.*)$ https://viencoding.com/$1 permanent;
}
client_max_body_size 1024M;
access_log /var/log/nginx/blog_access.log;
error_log /var/log/nginx/blog_error.log;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location ~* \.(?:manifest|appcache|html?|xml|json)$ {
expires -1;
}
location ~* \.(?:ttf|jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc)$ {
expires 1M;
access_log off;
add_header Cache-Control "public";
}
location ~* \.(?:css|js)$ {
expires 1y;
access_log off;
add_header Cache-Control "public";
}
}
主要是监听 443 端口,启用 SSL,并配置 SSL 的证书路径(公钥,私钥的路径)。 通过这些我们就已经成功的完成了 Https 的配置。其中证书的配置主要是如下两行:
ssl_certificate /etc/letsencrypt/live/viencoding.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/viencoding.com/privkey.pem;
也就是刚刚提示生成的文件,fullchain.pem
的目录填写在ssl_certificate
后面,privkey.pem
的目录填写在 ssl_certificate_key
后面。填写完成后,重新加载配置或者重启nginx:
sudo service nginx restart
或者
sudo /etc/init.d/nginx restart
或者
sudo nginx -s reload
以上,也便完成了NGINX服务器的ssl证书配置。现在,我们的网站已经可以用https访问并且有https的安全标识了。
Let’s Encrypt 提供的证书只有90天的有效期,我们必须在证书到期之前,续费证书,上面我们也提到了 certbot renew
可以续费所有申请过的证书。 通过这个命令,他会自动检查系统内的证书,并且自动更新这些证书。 我们可以运行这个命令测试一下
certbot renew --dry-run
如果你是用的是 --standalone
模式生成的证书,那运行的时候可能出现了这个错误:
Attempting to renew cert from /etc/letsencrypt/renewal/viencoding.com.conf produced an unexpected error: At least one of the required ports is already taken.. Skipping.
--standalone
模式,验证域名的时候,需要启用443端口,而NGINX占用了443端口,所以要先关掉nginx,解除占用,然后再重新执行:
sudo /etc/init.d/nginx stop
或
sudo service nginx stop
更新证书后,再开启nginx:
sudo /etc/init.d/nginx start
或
sudo service nginx start
证书是90天才过期,我们只需要在过期之前执行更新操作就可以了。 这件事情就可以直接交给定时任务来完成。linux 系统上有 cron 可以来搞定这件事情。
官方的建议是一天执行两次,不要等90天再执行,毕竟你也不想因为某些原因,恰巧到期最后一天没自动续订,导致你网站https挂掉。官方是这样说的:
Note: if you're setting up a cron or systemd job, we recommend running it twice per day (it won't do anything until your certificates are due for renewal or revoked, but running it regularly would give your site a chance of staying online in case a Let's Encrypt-initiated revocation happened for some reason). Please select a random minute within the hour for your renewal tasks.
那我们就按照官方建议来搞:
用以下命令打开定时任务的列表(如果第一次打开可能询问你用哪个编辑器,我选择的vim编辑器):
crontab -e
然后再末尾加入:
0 */12 * * * certbot renew --pre-hook "service nginx stop" --post-hook "service nginx start"
如果你没有用--standalone
模式,完全可以不用关闭nginx,只在最后重启一下nginx或者重新加载配置就好,你可以这样写
0 */12 * * * certbot renew --quiet --renew-hook "nginx -s reload"
--pre-hook
这个参数表示执行更新操作之前要做的事情, --post-hook
这个参数表示执行更新操作完成后要做的事情。
写完之后,保存退出编辑,系统就自动加载了这个定时任务。
至此,整个网站升级到HTTPS就完成了。
我们申请免费SSL证书升级网站HTTPS主要做了三件事:
最后,感谢 Let’s Encrypt 组织以及所有该组织的贡献者支持者 为我们提供 免费的安全证书。
viencoding.com版权所有,允许转载,但转载请注明出处和原文链接: https://viencoding.com/article/238