本文操作环境:

  • CentOS 7
  • Docker 1.12.5
  • Nginx:1.11.7-alpine
  • Let’s Encrypt
  • Acme-tiny

HTTP/2

Nginx支持

Nginx从1.9.5就已支持Http/2
Open Source NGINX 1.9.5 Released with HTTP/2 Support
截止目前Docker Hub上的版本为1.11.7

注意: 从图可以看出有两种Nginx的Image,必须选用alpine版本的,才能顺利开启Http/2。
另外一个官方推荐的Image使用Debian Jessie作为底包,其OpenSSL最新版本仅支持到 1.0.1t,但是只有从OpenSSL 1.0.2才开始才开始支持ALPN ALPN support,而其又是支持Http/2协议的必要条件。

HTTPS

Https大势所趋

到现在还在争论是否需要https已经是毫无意义的事情了。况且在WWDC 2016 开发者大会上,苹果宣布了一个最后期限:到2017年1月1日App Store中的所有应用都必须启用 App Transport Security安全功能。

顺便推荐大家可以去看一下Google I/O 2016的视频(Youtube)
Mythbusting HTTPS: Squashing security’s urban legends - Google I/O 2016

背景知识

证书类型

HTTPS 证书分为3类:

1、 DV 域名验证证书 2、 OV 组织机构验证证书 3、 EV 增强的组织机构验证证书

一般个人使用DV证书完全够了,浏览器表现为地址栏前会有绿色的小锁。所以本文介绍的也是这个。

证书有效期

Let’s Encrypt的证书有效期是90天,原因官方给了一篇解释的文章 Why ninety-day lifetimes for certificates?, 他们主要是从两方面考虑:

  1. They limit damage from key compromise and mis-issuance. Stolen keys and mis-issued certificates are valid for a shorter period of time.
  2. They encourage automation, which is absolutely essential for ease-of-use. If we’re going to move the entire Web to HTTPS, we can’t continue to expect system administrators to manually handle renewals. Once issuance and renewal are automated, shorter lifetimes won’t be any less convenience than longer ones.

生成和使用Let’s Encrypt证书

生成Let’s Encrypt帐号私钥

openssl genrsa 4096 > account.key

生成证书请求文件(CSR)

  1. 创建域名私钥文件
    openssl genrsa 4096 > domain.key
  2. 根据私钥文件,就可以生成 CSR 文件了(目前Let’s Encrypt不支持泛域名)
    1
    2
    3
    4
    #单个域名
    openssl req -new -sha256 -key domain.key -subj "/CN=yoursite.com" > domain.csr
    #多个域名
    openssl req -new -sha256 -key domain.key -subj "/" -reqexts SAN -config <(cat /etc/pki/tls/openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:yoursite.com,DNS:www.yoursite.com")) > domain.csr

进行签名操作

Let’s Encrypt会在你的服务器上生成一个随机验证文件,再通过创建CSR时指定的域名访问,如果可以访问则表明你对这个域名有控制权。

  1. 配置Nginx

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    mkdir -p /var/www/challenges/
    #example for nginx conf
    server {
    listen 80;
    server_name yoursite.com;
    location /.well-known/acme-challenge/ {
    alias /var/www/challenges/;
    try_files $uri =404;
    }
    }
  2. 执行脚本

    1
    2
    3
    wget https://raw.githubusercontent.com/diafygi/acme-tiny/master/acme_tiny.py
    python acme_tiny.py --account-key account.key --csr domain.csr --acme-dir /var/www/challenges/ > signed.crt

安装中间证书

1
2
wget -O - https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem > intermediate.pem
cat signed.crt intermediate.pem > chained.pem

配置Nginx加入证书

这个可以参考 Mozilla SSL Configuration Generator。这里生成的配置文件是业界最佳实践和结果,让 Nginx 打开了各种增加安全性和性能的参数。
Example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
server {
listen 80 default_server;
listen [::]:80 default_server;
# Redirect all HTTP requests to HTTPS with a 301 Moved Permanently response.
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
# certs sent to the client in SERVER HELLO are concatenated in ssl_certificate
ssl_certificate /path/to/signed_cert_plus_intermediates;
ssl_certificate_key /path/to/private_key;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
# Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits
ssl_dhparam /path/to/dhparam.pem;
# intermediate configuration. tweak to your needs.
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS';
ssl_prefer_server_ciphers on;
# HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months)
add_header Strict-Transport-Security max-age=15768000;
# OCSP Stapling ---
# fetch OCSP records from URL in ssl_certificate and cache them
ssl_stapling on;
ssl_stapling_verify on;
## verify chain of trust of OCSP response using Root CA and Intermediate certs
ssl_trusted_certificate /path/to/root_CA_cert_plus_intermediates;
resolver <IP DNS resolver>;
}

测试你的服务器SSL安全性

Qualys SSL Labs 提供了全面的 SSL 安全性测试,填写你的网站域名,给自己的 HTTPS 配置打个分。
本博测试结果:

测试你的网站是否开启Http/2

在Chrome浏览器中输入:chrome://net-internals/#http2,然后看HTTP/2 sessions表格里是否出现了你的网站即可。