分类目录归档:HTTPS

https 证书比较 geotrust globalsign verisign digicert

目前收费的证书有几个品牌: 来自于digicert旗下的 Geotrust 和 Digicert, 来自日本的globalsign

digicert: 其实是之前的verisign的替换,由于chrome拒绝掉了symantec的安全认证导致这个品牌的彻底消亡被digicert收购并重新签发证书

优点: 兼容性好,大品牌, RSA ECC双认证, 支持Windows XP SP3 +, iOS5 +, Firefox 2+, Android 1.5+

缺点: 贵, 如果要实现WinXP全兼容,需要Baltimore cross 认证

使用公司: weixin.qq.com www.sohu.com www.zhihu.com等

GeoTurs: 低端品牌, 由于被digicert收购后用新根签发,兼容性大增

优点:  便宜 兼容性好

缺点: 只支持RSA认证, 品牌认知度偏低

Globalsign: 来自日本的证书品牌, 2016年曾出现过中间证书异常吊销的事故,目前占据了越来越多的市场,目前百度 阿里 腾讯 京东 爱奇艺 搜狗都使用这个品牌

优点: 相对便宜,只有之前verisign的一半价格, 兼容性好

缺点:  2016年的事故让人有疑虑,签发过程会比digicert略微繁琐些

整体看: 目前几家商业证书的兼容性基本都在同一水平上, 只剩下品牌认知度的影响

globalsign其实是个非常合适的性价比之选

当然,对于非常计较成本的用户,当然是用免费证书

https://knowledge.digicert.com/generalinformation/digicert-root-compatibility.html

nginx 与 TLS1.3

TLS1.3支持了更优秀的SSL 新特性,可以有效降低https的协商时间,建议升级

本文使用了最新的nginx 1.14.1 (该版本修正了 1.14 H2 cpu/mem 攻击漏洞: low)

#wget https://www.openssl.org/source/openssl-1.1.1.tar.gz
#wget http://nginx.org/download/nginx-1.14.1.tar.gz

#spdy兼容补丁
#wget https://raw.githubusercontent.com/favortel/nginx_patch/master/nginx-1.14.0_spdy_h2.patch

#OKHTTP H2 头部动态压缩兼容补丁
#wget https://raw.githubusercontent.com/favortel/nginx_patch/master/fssnginx_1.14.0_dynamic_table_size.patch

#PCRE ZLIB等
#wget https://ftp.pcre.org/pub/pcre/pcre-8.42.tar.gz
#wget https://zlib.net/zlib-1.2.11.tar.gz

#tar -zxvf openssl-1.1.1.tar.gz
#tar -zxvf pcre-8.42.tar.gz
#tar -zxvf zlib-1.2.11.tar.gz
#tar -zxvf nginx-1.14.1.tar.gz

#cd nginx-1.14.1
#patch -p1 < ../fssnginx_1.14.0_dynamic_table_size.patch
#patch -p1 < ../nginx-1.14.0_spdy_h2.patch

./configure --prefix=/opt/itc/nginx --with-http_stub_status_module --with-http_realip_module --with-http_ssl_module --with-openssl=../openssl-1.1.1 --with-pcre=../pcre-8.42 --with-pcre-jit --with-zlib=../zlib-1.2.11 --with-http_v2_module --with-http_spdy_module
#make && make install

配置比较简单,就是ssl_protocols 增加TLSv1.3就好, ssl_ciphers 不用特意改动:

...
ssl_protocols               TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
ssl_ciphers                 ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256;
ssl_prefer_server_ciphers   on;
ssl_ecdh_curve              secp384r1;
...

比如本站,如果您是用chrome访问的是https协议,打开开发者工具-security,就能看到本站使用了TLS1.3了

nginx spdy patch for 1.14.0 1.13.12

spdy 协议由于安卓碎片化的存在 暂时还是需要保留一段时间的兼容性

准备升级到nginx1.14的时候发现 work process 会自动 退出, 同时系统日志有 nginx segfault的信息

修改配置,抓取coredump信息,需要做以下内容
nginx 增加

worker_rlimit_core 5000M;
working_directory /path/to/cores/;
$> ulimit -c unlimited
$> mkdir /opt/coredump/ && chown nobody.nobody /opt/coredump/ # 先建目录,还要确认nginx用户可以写此目录
$> echo “/opt/coredump/core-%e-%p-%h-%t” > /proc/sys/kernel/core_pattern

拿到coredump文件后使用gdb分析

gdb /path/to/nginx /path/to/cores/nginx.core
backtrace full

发现问题指向了
src/http/ngx_http_spdy.c:ngx_http_spdy_state_read_data 的
buf->last = ngx_cpymem(buf->last, pos, size);

简单调试发现buf->last是个0, ngx_cpymem会因为内存越界导致coredump

而分析代码 + gdb 断点调试 看到初始化r->request_body->buf的部分: ngx_http_spdy_init_request_body(r) 并未执行

打印r->request_body 内容发现这块被初始化了,对比nginx1.12.2和1.10.3版本发现旧版本则是未做初始化

翻了下调用的部分:ngx_http_request_body: ngx_http_read_client_request_body 可以看到在nginx 1.13.12版本开始会对r->request_body 做了初始化操作,这部分直接导致了SPDY 补丁 的不兼容

所以答案就很简单了,修改下判断条件即可

新补丁放在了:https://github.com/favortel/nginx_patch/blob/master/nginx-1.14.0_spdy_h2.patch
参考文档:
https://toontong.github.io/blog/nginx-gdb-coredump-segfault.html
https://www.nginx.com/resources/wiki/start/topics/tutorials/debugging/
http://lxr.nginx.org/source/src/http/ngx_http_request_body.c
http://lxr.nginx.org/source/src/http/ngx_http_request_body.c?v=nginx-1.12.2

ciphers suite的选择

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.0 支持

虽然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 https 入门配置

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

https 支持 IE6和 winXP

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证书

免费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 证书

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 部署和优化

本文主要介绍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的支持

先挖个坑,以后慢慢填