linux

开启 HTTPS 并获得 ssllabs 满分的过程

发布时间:5年前热度: 5787 ℃评论数:

一、准备工作

确保你要申请证书的域名都解析到了这台服务器上,且能直接通过域名访问。

使用官网推荐的CertBot获取证书。

在CertBot官网选择一下环境(比如我选Nginx on Ubuntu 17.04)就可以看到入门教程了。

安装CertBot

[[email protected] ~]# apt-get update

[[email protected] ~]# apt-get install software-properties-common

[[email protected] ~]# add-apt-repository ppa:certbot/certbot

[[email protected] ~]# apt-get update

[[email protected] ~]# apt-get install python-certbot-nginx

二、获取证书

我是把几个域名都放到一张证书里的,这样可以支持一些比较旧的,不支持SNI的浏览器

[[email protected] ~]# certbot certonly --must-staple --rsa-key-size 4096 -d 域名1 -d 域名2...


这步的-rsa-key-size 4096是为了ssllabs满分,如果你不想弄这个可以不加,能略微提升网站访问速度。

每个-d后面跟一个域名,有多少个域名跟多少个

运行后它会让你选验证模式,我这里已经开启了nginx,因此选2,自己设置webroot

选1然后输入你的网站静态文件所在的目录,如我的Nginx默认是/var/www/html

之后每一个域名都需要设置,如果你所有域名都在一个目录,直接选2使用第一次输入的路径即可

输入完最后一个域名后,它会提示你申请结果,如果失败请检查失败原因后重试,如果成功继续下一步

我一开始因为用了国内的NS服务商,然后Let’s Encrypt访问不到就失败了,这货不会信任任何DNS服务器给出的服务器地址,必须要直接访问权威NS服务器查询的结果才可以,因此如果你因为这个失败了,建议更换一些国外的免费NS服务商。

如果成功会告诉你申请成功,并给出你的证书路径,比如我的:/etc/letsencrypt/live/zhl123.cn/fullchain.pem

记下这个路径(不包括fullchain.pem的部分,稍后用得着)

三、配置 DNS CAA

DNS CAA 可限制你的域名只有特定的证书签发机构可以签发证书,且无权签发的签发机构收到签发证书申请时会给你发邮件提醒

这步不影响ssllabs评分,可不做

你需要找一家支持CAA记录的NS服务商,国内似乎没有。。。

我找了半天找到一家国外的:https://www.1984hosting.com/


通过修改域名的NS记录接入到你选择的NS服务商

添加CAA记录,比如我的:

issue "letsencrypt.org"

iodef "[email protected]"


issue是允许哪家证书签发机构签发证书,iodef是你的邮箱地址


完成后可以通过dig caa 你的域名来验证是否添加成功


四、配置 nginx

编辑你每一个申请证书的域名的server配置,设置http直接跳到https


server {

  listen 80;

  server_name 域名;


  return 301 https://$host$request_uri;

}

配置每一个域名的 https

server {

  # 如果 http2 报错说明你的 nginx 版本比较低不支持,删掉即可

  listen 443 ssl http2;

  server_name 域名;


  ssl_certificate 证书路径/fullchain.pem;

  ssl_certificate_key 证书路径/privkey.pem;

  ssl_trusted_certificate 证书路径/chain.pem;


  # 强制域名使用 HTTPS 打开,且在证书不被信任时不允许用户跳过,这里设置的时间是 182.5 天

  # includeSubDomains 表示包含子域名

  # preload 表示允许被加入浏览器内置的强制 HTTPS 列表中

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

  # 在检测到 XSS 时阻止网页加载

  add_header X-XSS-Protection "1; mode=block";

  # 禁止网页被嵌入 frame(算是避免运营商劫持的办法之一)

  add_header X-Frame-Options DENY;


  # 后面可以写你的网站之前的代码,如 root /var/www/html;

}

配置 nginx.conf,删掉自带的 SSL 配置,用下面的覆盖

# 只支持 TLS1.2,如果`openssl`在`1.1.1`以上,且`nginx`在`1.13`以上,可再加入`TLSv1.3`

ssl_protocols TLSv1.2;

ssl_prefer_server_ciphers on;

ssl_session_timeout 1d;

ssl_session_cache shared:SSL:10m;


ssl_buffer_size 4k;


ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA';


ssl_ecdh_curve sect571r1:secp521r1:brainpoolP512r1:secp384r1:brainpoolP384r1:sect571k1;


ssl_stapling on;

ssl_stapling_verify on;

开启session_ticket


在 nginx 配置目录下执行

[[email protected] ~]# mkdir ssl

[[email protected] ~]# openssl rand 80 > ssl/ticket.key

编辑nginx.conf,在SSL配置后面加入下面两行

ssl_session_ticket_key ssl/ticket.key;

ssl_session_tickets on;

使用4096位加密


在 nginx 配置目录下执行

openssl dhparam -out ssl/dhparam.pem 4096

编辑nginx.conf,在SSL配置后面加入下面两行


ssl_dhparam ssl/dhparam.pem;

五、一些额外的配置

开启 HPKP

HPKP可以检查你的证书是不是指定的证书签发机构签的,如果不是会阻止访问,也可配置出现问题时向指定地址报告等

在你的浏览器访问https://www.ssllabs.com/ssltest/analyze.html?d=你的域名

等测试结束后,在页面搜索Certification Paths

点击下面的展开

把第一行不是你的域名的Pin SHA256的值记录下来

换一个免费证书,再来一次,比如腾讯云可以申请赛门特克的免费证书

把你刚刚记下来的几个值(至少4个,无顺序要求),按下面的格式写入你每一个域名的server配置中


# 如果有更多按照格式加就行

add_header Public-Key-Pins 'pin-sha256="第一个值"; pin-sha256="第二个值"; pin-sha256="第三个值"; pin-sha256="第四个值"; max-age=15768000; includeSubDomains';


申请浏览器内置HSTS

HSTS可以要求用户访问你的网站必须用HTTPS协议,然而需要至少访问一次才会生效,这一次仍然有可能被劫持,而且有可能被一些更无良的运营商给HTTPS强转HTTP,用户永远不会把你加进HSTS名单

为了解决这个尴尬的问题,浏览器商们推出了一个申请地址,符合要求的域名可以申请把自己加入浏览器的源代码中,这样用户首次访问的时候也会强制用HTTPS访问

请一定注意,一旦申请成功,就没有回头路了,如果哪天你不想用HTTPS了,那就只能换个域名了。


确保你申请证书的时候包含你的主域名,如我的是zhl123.cn,不能带任何子域名,如www.zhl123.cn无效

确保你照做了上面的4.2

访问申请页面,输入你的主域名,提交即可,稍后的提示确认,打勾后再提交即可

耐心等待审核,一般一个月内可审核完成,审核完成之前请不要修改网站配置。

六、自动重新签发证书

Let’s Encrypt申请的证书只有3个月有效期,每隔3个月都手动来重新签发一次。

通过crontab在每月1号自动重新签发证书

执行crontab -e,添加下面一行保存即可

0 0 1 * * certbot renew --force-renew && /etc/init.d/nginx reload

开启,获得,满分,过程

手机扫码访问