HTTPS ciphers suite 的选择要奉行一个原则: 安全 兼容 性能

可以参考https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_configurations 这个链接

Configuration Oldest compatible client
Modern Firefox 27, Chrome 30, IE 11 on Windows 7, Edge, Opera 17, Safari 9, Android 5.0, Java 8
Intermediate Firefox 1, Chrome 1, IE 7, Opera 5, Safari 1, Windows XP IE8, Android 2.3, Java 7
Old Windows XP IE6, Java 6

如果是个人网站,不需要考虑支持较老和古老的浏览器,直接选择Modern支持即可

对于大多数的网站来说,还是需要综合考量的,先假设只需要支持modern和Intermediate

Intermediate compatibility (default)

For services that don’t need compatibility with legacy clients (mostly WinXP), but still need to support a wide range of clients, this configuration is recommended. It is is compatible with Firefox 1, Chrome 1, IE 7, Opera 5 and Safari 1.

  • Ciphersuites: 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
  • Versions: TLSv1.2, TLSv1.1, TLSv1
  • TLS curves: prime256v1, secp384r1, secp521r1
  • Certificate type: RSA
  • Certificate curve: ‘None
  • Certificate signature: sha256WithRSAEncryption
  • RSA key size: 2048
  • DH Parameter size: 2048
  • ECDH Parameter size: 256
  • HSTS: max-age=15768000
  • Certificate switching: None

几个关键点:

  1.  RSA key 用2048的签名就可以了
  2.  DH 用2048
  3.  使用TLS1.0-1.2, 不要使用不安全的SSLv2-3
  4.  加密的cipher-suite 可以参考以上,也可以自己调整顺序,比如可以根据自己客户端是PC浏览器多还是移动端多,把CHACHA挪后…

 

参考资料:
https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_configurations

虽然spdy 协议早已被 HTTP2 取代,但是chrome 旧浏览器和 移动端基于chrome内核的应用还是挺多的,所以spdy 的兼容还是必要的

cloudflare 出了个spdy的补丁,可以兼容HTTP2和SPDY

https://blog.cloudflare.com/open-sourcing-our-nginx-http-2-spdy-code/

靠谱补丁 for nginx 1.10.3:
https://github.com/cujanovic/nginx-http2-spdy-patch/blob/master/nginx-spdy.patch
一般靠谱补丁:
https://github.com/cloudflare/sslconfig/tree/master/patches

打完补丁后, build的时候增加编译参数即可

–with-http_spdy_module #开启spdy 协议, 需要打上cloudflare的patch
–with-http_v2_module #开启HTTP2 协议,不需要任何补丁

nginx 相关配置可以参考nginx 配置文档
server {
listen 443 spdy http2;

}

nginx 版本选择,一般1.10 或者当前最新stable的1.12都没什么问题

编译参数:

--prefix=/opt/itc/nginx --with-http_ssl_module --with-http_v2_module --with-openssl=../openssl-1.1.0f --with-pcre=../pcre-8.38 --with-zlib=../zlib-1.2.11

其中:
openssl 可以选用1.0版本也可以选用1.1版本,性能会更强,可以在openssl.org下载
pcre zlib都需要自行在对方官网下载
另外, 这两个参数可以按需使用:


--with-openssl-opt=enable-weak-ssl-ciphers #openssl1.1版本开启weak_cipers
--with-http_spdy_module #开启spdy 协议,需要打上cloudflare的patch

配置:

server {
listen 443 spdy http2;
server_name www.4os.org;
root /opt/www/www.4os.org;
access_log logs/www.log main;

ssl_certificate ssl/your_site_key.crt; #公钥
ssl_certificate_key ssl/your_site_key.key; #私钥

ssl_dhparam ssl/dhparams.pem;
ssl_ciphers “ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!RC4:!MD5:!PSK:!aECDH:!DHE”;
ssl_prefer_server_ciphers on;
#ssl_ecdh_curve secp384r1;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

location / {

}
}

cipher_suite 的选择可以参考: https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_configurations

winXP + IE6 是非常非常古老的组合, 如果确实需要支持会稍微麻烦些
1. winXP 必须是更新到SP3的,之前的版本无法支持sha2 证书
2. 需要支持TLS_RSA_WITH_3DES_EDE_CBC_SHA 这个属于weak的cipher suite,如果编译的是openssl1.1 版本,则需要编译的时候加入 –with-openssl-opt=enable-weak-ssl-ciphers 参数以开启
3. SNI 不支持,因此IE6只会接收默认的证书,需要把需要支持的域名打到默认证书里边,并且首先加载这个默认虚机 (从测试看,谁先加载谁就是默认证书)
4. 需要开启SSLv3,这是非常不建议的操作
默认的IE6用户设置是没有勾选IE设置里边的TLS1.0的,只支持SSLv2 和 SSLv3

免费https证书,早期有startssl,现在有 let’s Encrypt

Let’s Encrypt 是 由非盈利组织 ISRG(Internet Security Research Group) 带来的免费 自动颁发 开放认证的HTTPS证书服务

Let’s Encrypt is a free, automated, and open certificate authority brought to you by the non-profit Internet Security Research Group (ISRG).

Let’s Encrypt发展到现在,兼容性已经得到非常长足的发展,足以媲美geotrust globalsign verisign等商业证书,由于该证书还是天然三级证书链,性能方面也有明显的优势,更难能可贵的是: 它免费提供RSA/ECC两个版本的证书.

缺点? 基于安全性,只有90天的有效期,需要定期续签,另外它不类似于startssl提供WEB界面给使用者,需要使用命令行工具自行签发,有一定的门槛

本文的目的就是推广Let’s Encrypt 并降低入门门槛

1. 创建身份认证私钥

这个证书就是Let’s Encrypt 辨认识别你的私钥

openssl genrsa 4096 > account.key

2. 创建证书签名请求文件

CSR(Certificate Signing Request,证书签名请求)文件

创建RSA域名私钥

openssl genrsa 4096 > domain.key

创建ECC域名私钥

openssl ecparam -genkey -name secp384r1 | openssl ec -out ecc.key

生成CSR文件

openssl req -new -sha256 -key domain.key -subj "/" -reqexts SAN -config <(cat /etc/ssl/openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:4os.org,DNS:www.4os.org")) > domain.csr
openssl req -new -sha256 -key ecc.key -subj "/" -reqexts SAN -config <(cat /etc/ssl/openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:4os.org,DNS:www.4os.org")) > ecc.csr

 

3. 配置nginx 支持let’s Encrypt 自动校验

let’s Encrypt 是通过自签名程序生成一个随机文件,并访问你的域名的URL来校验你是否拥有这个域名的所有权,所以需要配置一个特定的目录和nginx location 路径,如果你有多台分布,请确认都能正确的访问到该目录文件.

创建用于存放验证文件的目录,例如:

mkdir ~/www/challenges/

然后配置一个 HTTP 服务,以 Nginx 为例:

server {
    server_name www.4os.org 4os.org;

    location ^~ /.well-known/acme-challenge/ {
        alias /home/xxx/www/challenges/;
        try_files $uri =404;
    }

...
}

4.从Let’s Encrypt获取证书

下载证书自动校验签发工具

wget https://raw.githubusercontent.com/diafygi/acme-tiny/master/acme_tiny.py

校验并获取证书


python acme2_tiny.py --account-key ./account.key --csr ./domain.csr --acme-dir ~/www/challenges/  > ./signed.crt
python acme2_tiny.py --account-key ./account.key --csr ./ecc.csr --acme-dir ~/www/challenges/  > ./ecc.crt

现在获取下来的叫做站点证书, 为了浏览器能正确的识别证书的有效性,需要把中间证书一并下载下来并和站点证书合并


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

5.nginx双证书 配置


#RSA
ssl_certificate ssl/chained.pem;
ssl_certificate_key ssl/domain.key;
#ECC
ssl_certificate ssl/ecc_chained.pem;
ssl_certificate_key ssl/ecc.key;

需要特别留意下: nginx 1.11.1版本以后才支持双证书,如果低于此版本,建议只使用RSA证书即可

本文主要参考了jerryqu的个人网站,关于https jerryqu做了大量的研究,Let’s Encrypt,免费好用的 HTTPS 证书

Geotrust:
优点: 非常便宜
缺点: 品牌比较弱, 不兼容安卓4.x及以下平台,于是签发了equifax Secure CA的交叉认证导致证书多了一级
使用者: 搜狐 weixin.qq.com(微信公众号平台等)

globalsign:
优点: 性价比高, 天然三级, 兼容性好
缺点: 品牌稍弱, 不支持安卓2.3和之前的版本, XP需要更新根证书后才支持(系统自动完成的) 黑历史让人担忧 (2016.10出现过错误吊销中间证书的严重故障 )
使用者: 京东 淘宝 腾讯(xw.qq.com等 www.qq.com和news.qq.com 也在这张证书但是暂未提供https服务)

verisign:
优点: 品牌强大 兼容性好 可以直接使用三级 支持ECC加密性能更优
缺点: 贵 支持ECC双证书会更贵! 不支持安卓2.3和之前的版本
使用者: 搜狗 爱奇艺 百度 腾讯灯塔平台(beacon.qq.com,广告营销大数据分析等)

总结:
geotrust 的兼容性是通过交叉认证实现的,这导致每次请求都需要发多一张中间证书,这会带来一定的性能损失
除了黑历史, 京东 淘宝 腾讯都选择了globalsign, 除了性价比的因素,对方天然的三级证书优势也很明显
verisign 品牌悠久, 兼容性好,但是价格就不那么美好了,是个保守而稳定的选择

当然,以上都是要钱的,对于个人用户,选择免费证书是更好的选择,比如: https://letsencrypt.org/

本文主要介绍HTTPS 部署和优化, 构思中包括以下内容:

1. 证书的介绍和获取
1) 商业证书
介绍市面上主流的geotrust globalsign verisign三家证书签发机构
2) 免费证书
介绍Let’s Encrypt这家了不起的免费证书颁发机构
2. nginx start up配置
3. spdy 和 http2.0 支持
4. ciphers suite的选择
5. 为何不建议开启ocsp
6. HTTPS优化
7. ie6的支持

先挖个坑,以后慢慢填

本文已经过时并且存在大量不安全,请参阅最新文档   https://www.4os.org/index.php/category/https/
nginx 默认编译就是支持https的,只需要开启ssl就好
配置如下:
                listen                  443 ;
                server_name             4os.org *.4os.org;

                ssl                     on;
                ssl_certificate         gz.crt;
                ssl_certificate_key     gz.key;
                ssl_session_timeout     5m;
                ssl_protocols           SSLv2 SSLv3 TLSv1;
                ssl_ciphers             ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
                ssl_prefer_server_ciphers       on;
....

其中:
gz.crt是证书颁发机构给的证书(免费ssl-证书/)
gz.key是解密后的私钥

上文中提到的私钥是加密的,可以在startssl的工具箱里边解密,也可以自己做:

openssl  rsa -in gz.pri -out gz.key,输入私钥生成时设置的密码,出来的就是不加密的私钥了,nginx启动也不会要你输入密码了

补充:

1. “SSL_CTX_use_PrivateKey_file fail”之类的错误,通常都是私钥和证书不匹配造成的,请确认你生成证书与私钥匹配

2.firefox证书需要根证书信息:

wget http://www.startssl.com/certs/sub.class1.server.ca.pem

cat sub.class1.server.ca.pem >> gz.crt

不再推荐 startssl,推荐 let’s encrypt, 请参考文章免费HTTPS证书

一般来说,开启https服务总会涉及到证书问题,通常自签发的证书在浏览器会有”鲜红告警”,而CA的证书又颇贵
https://www.startssl.com/ 是一个免费的证书提供商,并支持ie,firefox,chrome等主流浏览器

1.注册,点击右上角的钥匙

选择sign-up,并输入要求填写的所有信息,由于是人工审核,请谨慎填写(必须是私人地址)

2. 注册成功后会收到封邮件(建议留gmail),点击链接会安装一份证书,以后就可以凭证书自动登录该网站了(上图Auth…)

3. 登录后到控制面板,有3个框:分别是工具箱/证书向导/验证向导

先点验证向导(validations wizard),分别验证邮箱和域名(确认该域名属于你,系统一般会发信给域名的postmaster或者你注册域名时留的邮箱)

4. 证书向导,点Certificats wizard,选择web Server SSL证书,下一步

5. 输入私钥的密码,请特别留意密码你清楚记得

6. 然后系统会提示你保存加密私钥(你稍后可以在工具箱里边解密之,不要现在做,请确认保存该密钥),下一步选择域名和子域名申请证书

7. 提交申请,稍等个大概10分钟,会收到邮件提示证书开通,在后台下载就可以了(Toolbox-Retrieve Certificate)

到这里,SSL 证书已经搞定,nginx配置可以参考http://www.4os.org/index.php/2012/05/09/nginx-ssl-https-%E8%AE%BE%E7%BD%AE/