浏览器小绿锁——HTTPS 安全配置

水一篇教程来介绍一下 HTTPS 的一些配置吧,废话不多说,先看本博客的测试得分:
SSL_A+

蛐蛐大神的文章对本人有很大的启发,在此表示感谢。

HTTPS

超文本传输安全协议(Hypertext Transfer Protocol Secure,缩写:HTTPS,常称为 HTTP over TLS,HTTP over SSL或 HTTP Secure)是一种通过计算机网络进行安全通信的传输协议。HTTPS 经由 HTTP 进行通信,但利用 SSL/TLS 来加密数据包。HTTPS 开发的主要目的,是提供对网站服务器的身份认证,保护交换数据的隐私与完整性。

开启 HTTPS 只需要简单的证书及一些配置而已,本站使用的是付费的 Comodo ECC Wildcard 证书,当然你也可以使用免费的 Let’s Encrypt 证书。

首先生成一个 4096 位的 DH parameters 备用:

openssl dhparam -out /etc/ssl/dhparams.pem 4096  

利用 acme.sh 签发 Let’s Encrypt Wildcard 证书

Let’s Encrypt 提供很多方式,网上也有不少教程,但是都不方便操作,下面我们就介绍一款国人写的开源脚本 acme.sh

首先,进入服务器后获取 acme.sh 脚本:

curl https://get.acme.sh | sh

接着重新加载 Bash

source ~/.bashrc

然后可以执行 acme.sh --upgrade --auto-upgrade 获取 acme.sh 更新,并设置之后都自动更新 acme.sh 脚本

签发 Let’s Encrypt Wildcard 证书

首先在 DNS 服务商那边,给 example.com 增加一个 CAA 记录为 0 issue "letsencrypt.org" 这样可以告诉 Let’s Encrypt 的 CA ,你授权给他们签发 SSL 证书,国内支持 CAA 记录的不多,推荐 阿里云 和 CloudXNS。

acme.sh --issue -d example.com -d '*.example.com' --dns --ecc --ocsp

会显示类似如下的信息:

Domains have changed.
Registering account
Registered
ACCOUNT_THUMBPRINT='xxxxxxx'
Multi domain='DNS:example.com,DNS:*.example.com'
Getting domain auth token for each domain
Getting webroot for domain='example.com'
Getting webroot for domain='*.example.com'
Add the following TXT record:
Domain: '_acme-challenge.example.com'
TXT value: 'yyyyyyyy'
Please be aware that you prepend _acme-challenge. before your domain
so the resulting subdomain will be: _acme-challenge.example.com
Add the following TXT record:
Domain: '_acme-challenge.example.com'
TXT value: 'zzzzzzzz'
Please be aware that you prepend _acme-challenge. before your domain
so the resulting subdomain will be: _acme-challenge.example.com
Please add the TXT records to the domains, and re-run with --renew.
Please add '--debug' or '--log' to check more details.
See: https://github.com/Neilpang/acme.sh/wiki/How-to-debug-acme.sh

接着你需要给 _acme-challenge.example.com 增加两个 TXT 记录 "yyyyyyyy" 和 "zzzzzzzz",然后慢慢等 DNS 生效。生效后可以执行如下命令更新证书:

acme.sh --renew-all

获得证书后,在 Nginx 配置中加入如下简单配置即可:

443 端口 server 配置

server {
    listen              443 ssl http2 spdy fastopen=3 reuseport;
    server_name         xxx.com;
    root                /path/to/server/;                
    index               index.html index.php;
    ssl_certificate     /path/to/xxx.com.crt;
    ssl_certificate_key /path/to/xxx.com.key;
    ssl_dhparam         /etc/ssl/certs/dhparams.pem;
# 以下配置省略
}
  • 开启 Tcp Fast Open

TFO 需要内核版本在3.13以上。通过修改 /etc/sysctl.conf 来完成启用。

net.ipv4.tcp_fastopen = 3

调整完成后通过 sysctl -p 来启用选项。

80 端口 server 配置

将 HTTP 流量全部转到 HTTPS

server {
    server_name  xxx.com;
    return       301 https://xxx.com$request_uri;
}

测试网站 SSLLABS

TLS 1.3

增强性能,优化安全性

关于 TLS 1.3,推荐浏览 CloudFlare 的一篇介绍,非常的全面。

其主要特性如下:(来源:维基百科

移除脆弱和较少使用的命名椭圆曲线支持
移除MD5和SHA-224密码散列函数的支持
请求数字签名,即便使用之前的配置
集成HKDF和半短暂DH提议
替换使用PSK和票据的恢复
支持 1-RTT 握手和初步支持 0-RTT
放弃许多不安全或过时特性的支持,包括数据压缩、重新协商、非 AEAD 密码本、静态 RSA 和静态 DH密钥交换、自定义 DHE 分组、点格式协商、更改密码本规范的协议、UNIX 时间的 Hello 消息,以及长度字段 AD 输入到 AEAD 密码本
禁止用于向后兼容性的 SSL 和 RC4 协商
集成会话散列的使用
弃用记录层版本号和冻结数以改进向后兼容性
将一些安全相关的算法细节从标准移动到标准,并将 ClientKeyShare 降级到附录
添加 Curve25519 和 Ed25519 到 TLS 标准。

开启 TLS 1.3

  • 下载 OpenSSL 1.1.1 draft-23
wget https://www.openssl.org/source/openssl-1.1.1-pre2.tar.gz && tar zxf openssl-1.1.1-pre2.tar.gz && rm openssl-1.1.1-pre2.tar.gz
  • 编译 Nginx

在编译 nginx 的过程中,加入参数:--with-openssl=../openssl-1.1.1-pre2 --with-openssl-opt='enable-tls1_3 enable-ec_nistp_64_gcc_128 zlib no-idea no-shared'
如果你想支持 IE8 等过时浏览器,那么可以 enable-weak-ssl-ciphers 选项。

  • 配置文件中加入相关配置

在 Nginx 的站点配置中,以下几个参数需要修改:

ssl_protocols TLSv1.3 TLSv1.2;
ssl_ciphers 'HIGH:!PSK:!CAMELLIA:!aNULL:!SRP:!RSA:!AES128';
ssl_ecdh_curve P-384;
ssl_prefer_server_ciphers on;

签发证书的时候,如果是 RSA 证书 推荐 4096 位的 KEY,如果是 ECC 证书 则推荐 secp384r1
修改如上配置以后,你就可以轻松达到 4*100 的满分测试成绩啦。

验证是否支持 TLS 1.3

目前最新版 Chrome 和 Firefox 都支持 TLS 1.3,但需要手动开启:

  • Chrome,将 chrome://flags/#ssl-version-max 中的 Maximum TLS version enabled 改为 TLS 1.3
  • Firefox,将 about:config 中的 security.tls.version.max 改为 4

参考图如下:
tls1.3

HSTS

何为 HSTS

HTTP 严格传输安全(HTTP Strict Transport Security,缩写:HSTS)是一套由互联网工程任务组发布的互联网安全策略机制。网站可以选择使用HSTS策略,来让浏览器强制使用HTTPS与网站进行通信,以减少会话劫持风险。

简而言之,开启 HSTS 就是告诉浏览器:这个网站默认使用 HTTPS 访问,你甚至可以在 HSTS Preload 网站提交域名,让 Chrome Edge Firefox 等浏览器硬编译你的网站进入发行版,添加该特性同时意味着很长一段时间内,你的网站不能通过 HTTP 方式访问,所以是否开启需要谨慎,当然我肯定是开启啦。

开启方法

HSTS 是一个响应头,在 Nginx 配置文件当中直接添加即可,格式如下:

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

max-age,单位是秒,用来告诉浏览器在指定时间内,这个网站必须通过 HTTPS 协议来访问。也就是对于这个网站的 HTTP 地址,浏览器需要先在本地替换为 HTTPS 之后再发送请求。
includeSubDomains,可选参数,如果指定这个参数,表明这个网站所有子域名也必须通过 HTTPS 协议来访问。
preload,可选参数,用于提交 Preload List。

HSTS Preload List

可以看到 HSTS 可以很好的解决 HTTPS 降级攻击,但是对于 HSTS 生效前的首次 HTTP 请求,依然无法避免被劫持。浏览器厂商们为了解决这个问题,提出了 HSTS Preload List 方案:内置一份可以定期更新的列表,对于列表中的域名,即使用户之前没有访问过,也会使用 HTTPS 协议。

目前这个 Preload List 由 Chrome 维护,Chrome、Firefox、Safari、IE 11 和 MS Edge 都在使用。

开启 HPKP

HPKP 目前已经不再是潮流,不建议继续使用,Chrome 也将在未来版本中取消支持。

生成 Public Key 指纹并生成指纹:

我们一般用站点的中间证书生成 HPKP 指纹。

openssl x509 -in intermediate.pem -noout -pubkey | openssl asn1parse -noout -inform pem -out public.key
openssl dgst -sha256 -binary public.key | openssl enc -base64

按照同样方法,生成其它中间证书的备用指纹。

修改 Nginx 配置

add_header    Public-Key-Pins 'pin-sha256="EohwrK1N7rr3bRQphPj4j2cel+B2d0NNbM9PWHNDXpM="; pin-sha256="YLh1dUR9y6Kja30RrAn7JKnbQG/uEtLMkBgFF2Fuihg="; max-age=2592000; includeSubDomains' always;

两个指纹分别是 Comodo 和 Let’s Encrypt 的中间指纹。

OCSP Stapling

OCSP Stapling & OCSP Must Staple

OCSP装订(英语:OCSP Stapling),也称 OCSP 封套,是一个 TLS 证书状态查询扩展,作为在线证书状态协议的代替方法对 X.509 证书状态进行查询。服务器在TLS握手时发送事先缓存的 OCSP 响应,用户只需验证该响应的有效性而不用再向数字证书认证机构(CA)发送请求。

关于 OCSP Must Staple,讲道理这个东西草案都还在制定中,目前也只有 Let’s Encrypt 和 FireFox 支持,有一篇文章简单的介绍了一下什么是 OCSP Must Staple

开启方式

开启的方式也很简单,将证书链的中间证书和根证书(Comodo 证书不要添加AddTrustExternalCARoot.crt)合并成 chained.pem

  • 然后在 Nginx 配置中添加:
ssl_stapling            on;
ssl_stapling_verify     on;
resolver                8.8.8.8 valid=3600s;
ssl_trusted_certificate /path/to/chained.pem;
resolver_timeout        3s;

对于 Let’s Encrypt 的 OCSP Must Staple 特性,直接在签证书的时候加入 --must-staple 参数即可。

Last modification:May 18th, 2018 at 05:01 pm

Leave a Comment

One comment

  1. DCC

    打破 0 评论