accelsnow

Let's Encrypt! HTTPS化心得
这两天全站HTTPS化的过程中遇到了不少问题,不过最后换来小绿锁还是很值得的~(看起来逼格好高( •̀ᄇ• ́)ﻭ...
扫描右侧二维码阅读全文
17
2018/02

Let's Encrypt! HTTPS化心得

这两天全站HTTPS化的过程中遇到了不少问题,不过最后换来小绿锁还是很值得的~(看起来逼格好高( •̀ᄇ• ́)ﻭ✧)


HTTPS化的意义

HTTP(Hypertext Transporting Protocol)是一种长期以来被广泛使用的服务器与客户端浏览器之间的通信协议。因为它使用明文方式传输所有数据,所以第三方只要能截获数据就能直接获取通讯信息(比如银行卡号和网站账户密码)。HTTPS在HTTP的基础上多了一层secure,也就是使用SSL/TSL来加密传输内容,并根据安全机构颁布的CA证书来确认网站身份。SSL/TSL加密可以通过openssl等密钥生成服务来生成,然而通常情况下CA证书都是收费的。虽然这个博客只是个很小的站点,但是安全逼格也是绝对不能被忽视的!于是乎我便选择为数不多的全免费证书颁发机构 - Let's Encrypt 来为小站的https化奠基。


1. HTTPS化准备 - 获得Let's Encrypt证书

第一步首先要申请到颁发给域名的CA证书。Let's Encrypt提供一个集成了证书创建,验证和颁布的官方安装客户端certbot,其安装可以直接通过

apt-get install certbot

简单完成。随后就可以使用certbot的--webroot--standalone模式来创建证书,前者适用于存在根目录的网站服务,后者适用于没有根目录的一些微服务。绝大多数情况下都可以使用前者来进行验证颁布,以我的accelsnow.com的域名和yuki.accelsnow.com的子域名为例,命令如下

certbot certonly --webroot -w /usr/share/nginx/accelsnow.com -d accelsnow.com www.accelsnow.com -w /usr/share/nginx/yuki.accelsnow.com -d yuki.accelsnow.com

该命令会在域名根目录下创建.well-known目录用于certbot验证域名和网站的关联性。随后会默认在/etc/letsencrypt/live下分域名文件夹来存储各个域名的证书。比如主域名accelsnow.com的证书就会存储在/etc/letsencrypt/live/accelsnow.com目录下,而子域名yuki.accelsnow.com的证书则是存储在/etc/letsencrypt/live/accelsnow.com-00x目录下。x代表该子域名的序号。


2. HTTPS化启动 - Nginx配置HTTPS

证书创建完毕之后需要配置nginx服务对应站点的conf文件来监听HTTPS使用的443端口,定义使用的SSL证书路径(公钥以及私钥)以及重定向80端口到301端口。网站conf文件位于/etc/nginx/conf.d/目录下。在网站上搜索了很多教程之后,我自己总结文件定义如下

server {
  listen 80;
  server_name accelsnow.com;
  return 301 https://$server_name$request_uri;
}

server {
  server_name accelsnow.com;
  listen 443 ssl;
  ssl on;

  ssl_certificate /etc/letsencrypt/live/accelsnow.com/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/accelsnow.com/privkey.pem;
  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
  add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;

  root /usr/share/nginx/accelsnow.com/;
  index index.php index.html index.htm index.nginx-debian.html;

  location / {
    index index.html index.php;

    if (-f $request_filename/index.html) {
    rewrite (.*) $1/index.html break;
    }
    if (-f $request_filename/index.php) {
    rewrite (.*) $1/index.php;
    }
    if (!-f $request_filename) {
    rewrite (.*) /index.php;
    }
    try_files $uri $uri/ /index.php;
  }
}

子域名配置与之类似,只需要更改域名和证书地址即可。配置更改完毕后运行

systemctl reload nginx

重置nginx服务来激活SSL设置。


3. HTTPS化进阶 - 设置HSTS & SSL证书自动更新

第二步nginx配置其中的

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;

会给传输的数据加上一段定义HSTS(Http Strict Transport Security)的header,在第三步的时候会用到。这个Header会强制浏览器在接下来一年(31536000秒)以HTTPS发送任何属于该域名或者该域名的子域名的网站请求,如果SSL/TLS证书验证失败则会直接强制终止访问。
preload关键词则会将你的网站站点上传到知名浏览器(Google Chrome、Firefox、Internet Explorer和Microsoft Edge)的预置HSTS列表,保证任何即使是第一次访问网站的用户也能受到HSTS的保护强制通过HTTPS访问网站。但是要实现该preload,还需要将主域名放在hstspreload.org上面进行HTTPS的安全性检查。满足要求后网站就会被上传到浏览器的预加载列表里,真正保证小站100%通过HTTPS进行数据传输。

另外一点需要注意的是Let's Encrypt发布的SSL证书有效期只有三个月,在设置了HSTS的情况下如果证书到期却没有及时更新 +1s +1s +1s 就会让站点无法访问。更新证书的代码如下

certbot renew

如果需要自动更新,则需要创建一个无后缀文件,内容如下

0 0,12 * * * python -c 'import random; import time; time.sleep(random.random() * 3600)' && certbot renew --pre-hook "service nginx stop" --post-hook "service nginx start"

这段代码会在每天的12点和0点更新证书,并且在更新前暂时停止Nginx服务,并在更新完成时重启nginx服务。然后运行

crontab 创建的文件名

来加载该任务。


4. HTTPS化后话 - 遇到的一些问题和注意事项

小站使用的是Ubuntu 17.10 + Nginx + Mariadb + PHP7.2。

HTTPS化后添加子域名

刚刚开始HTTPS化的时候只有主域名,后来完成之后因为要部署ariang所以创建了一个子域名,但是访问子域名的时候总是显示

SSL证书验证错误,HSTS强制禁止访问

后来搜索了一些资料才发现是因为子域名没有SSL证书,主域名的全站HSTS强制用了HTTPS来访问还没有SSL证书的子域名,所以强制终止了访问。解决方法只需要用以上介绍的certbot为子域名也创建一个SSL证书,并且定义在子域名的nginx配置文件里即可。

HTTPS化后的资源加载

在HTTPS化完成之后,需要保证网站使用的所有资源引用和网址链接全部HTTPS化(图链,网站页面链接等),否则会被浏览器提示HTTPS不完全存在安全隐患。




感谢由 Let's Encrypt 提供的免费SSL证书
感谢由 certbot 提供的自动化证书创建及部署工具



版权声明:本文为原创文章,版权归 SHIROのYUKI 所有。
本文链接:https://accelsnow.com/index.php/coding/vps-ss-ssr.html
本文章采用 知识共享署名-非商业性使用 4.0 国际许可协议 进行许可。您可以自由的转载和修改,但请务必注明文章来源于本站以及转载内容是否经过修改,并且不可用于商业目的。

Last modification:July 13th, 2018 at 04:55 am

Leave a Comment