0x01 SSL配置


首先生成私钥文件

openssl genrsa -des3 -out ssl.key 1024

然后他会要求你输入这个key文件的密码。不推荐输入。因为以后要给nginx使用。每次reload nginx配置时候都要你验证这个PAM密码的。
由于生成时候必须输入密码。你可以输入后 再删掉。

mv ssl.key xxx.key
openssl rsa -in xxx.key -out ssl.key
rm xxx.key

然后根据这个key文件生成证书请求文件,CSR是一个证书签名请求,是客户的服务器软件所生成的一串文本字符。服务器在向CA注册的过程中首先要在WEB服务器上生成CSR,并把这串字符提供给证书认证中心。
openssl req -new -key ssl.key -out ssl.csr
最后根据这2个文件生成crt证书文件
openssl x509 -req -days 365 -in ssl.csr -signkey ssl.key -out ssl.crt
最后使用到的文件是key和crt文件。

然后修改Nginx配置

    server {
        listen       443 ssl;
        server_name  localhost;

        ssl_certificate      ssl.crt;
        ssl_certificate_key  ssl.key;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2 SSLv3;
        ssl_session_cache    shared:SSL:1m;
        ssl_session_timeout  5m;

        ssl_ciphers  HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers  on;

        location / {
            root   html;
            index  index.html index.htm;
        }
    }

首次配置需要重启nginx,reload不生效。
这里比较重要的配置是:

ssl_protocols TLSv1 TLSv1.1 TLSv1.2 SSLv3;
ssl_ciphers HIGH:!aNULL:!MD5;

0x02 SSL证书返回错误问题排查


运维同学反馈在IE 8和XP的环境下使用https访问chinaacc.com的时候,返回了cdeledu.com的证书。先验证下:
果然是提示证书不安全,然后查看证书,果然是访问chinaacc.com的时候,返回了cdeledu.com的证书。

经过了解,原来是服务器上配置了多个域名的SSL证书,使用低版本浏览器的时候默认返回了配置的第一个证书。
在HTTP协议中,请求的域名作为主机头(Host)放在HTTP Header中,所以服务器端知道应该把请求引向哪个域名,但是早期的SSL做不到这一点,因为在SSL握手的过程中,根本不会有Host的信息,所以服务器端通常返回的是配置中的第一个可用证书。因而一些较老的环境,可能会产生多域名分别配好了证书,但返回的始终是同一个。
直到后来出现了SNI(Server Name Indication),是一项用于改善SSL/TLS的技术,在SSLv3/TLSv1中被启用。它允许客户端在发起SSL握手请求时(具体说来,是客户端发出SSL请求中的ClientHello阶段),就提交请求的Host信息,使得服务器能够切换到正确的域并返回相应的证书。
这里我们抓一下SSL握手的包,看一下ClientHello的内容
发现使用Chrome访问的,证书正常,此时ClientHello中有SNI,如下图所示:

在XP系统使用IE浏览器的时候返回证书错误,发送的ClientHello包中没有SNI,所以会返回配置的第一个证书。
然后我在Window7下使用IE8测试,返回证书是正常的。看来跟操作系统也有关系。
需要注意SNI需要客户端和服务端同时支持才行。例如查看Nginx时候支持

[root@VM_1_112_centos sbin]# ./nginx -V
nginx version: nginx/1.6.3
built by gcc 4.4.7 20120313 (Red Hat 4.4.7-17) (GCC)
TLS SNI support enabled

TLS SNI support enabled表示支持SNI。

0x03 Nginx多SSL配置不生效问题


今天运维同事反馈XP系统IE6不能正常访问Https站点的问题。
低版本的IE默认配置是SSLv2和SSLv3。

抓包先看了下,握手失败。

然后用nmap跑了下证书支持的加密套件:

[root@server120 ]# nmap --script ssl-enum-ciphers -p 443 chinaacc.com

Starting Nmap 6.47 ( http://nmap.org ) at 2017-09-01 10:34 CST
Nmap scan report for chinaacc.com (59.151.113.79)
Host is up (0.034s latency).
PORT    STATE SERVICE
443/tcp open  https
| ssl-enum-ciphers: 
|   SSLv3: No supported ciphers found

发现站点不支持SSLv3。
然后看了下SSL配置
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
发现没有配置SSLv3
修改配置
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 SSLv3;
然后用nmap扫描了下发现还是不行,配置没有生效。

原因是如果一个反向代理Nginx上配置了多个https域名的话,默认会走第一个的SSL配置。
例如我的配置如下:

    server {
        listen       443 ssl;
        server_name  localhost;

        ssl_certificate      xx.crt;
        ssl_certificate_key  xx.key;
        ssl_protocols TLSv1;
        ssl_session_cache    shared:SSL:1m;
        ssl_session_timeout  5m;
        ssl_ciphers  HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers  on;

        location / {
            root   html;
            index  index.html index.htm;
        }
    }

    server {
        listen       443 ssl;
        server_name  192.168.192.120;

        ssl_certificate      xx.crt;
        ssl_certificate_key  xx.key;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_session_cache    shared:SSL:1m;
        ssl_session_timeout  5m;
        ssl_ciphers  HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers  on;

        location / {
            root   html;
            index  index.html index.htm;
        }
    }

第一个server配置ssl_protocols TLSv1;
第二个server配置ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
然后用nmap测试一下

[root@server144 ~]# nmap --script ssl-enum-ciphers -p 443 192.168.192.120

Starting Nmap 5.51 ( http://nmap.org ) at 2017-09-01 16:35 CST
Nmap scan report for localhost (192.168.192.120)
Host is up (0.00066s latency).
PORT    STATE SERVICE
443/tcp open  https
| ssl-enum-ciphers: 
|   TLSv1.0
|     Ciphers (13)
|       TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
|       TLS_DHE_RSA_WITH_AES_128_CBC_SHA
|       TLS_DHE_RSA_WITH_AES_256_CBC_SHA
|       TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
|       TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA
|       TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
|       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
|       TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
|       TLS_RSA_WITH_3DES_EDE_CBC_SHA
|       TLS_RSA_WITH_AES_128_CBC_SHA
|       TLS_RSA_WITH_AES_256_CBC_SHA
|       TLS_RSA_WITH_CAMELLIA_128_CBC_SHA
|       TLS_RSA_WITH_CAMELLIA_256_CBC_SHA
|     Compressors (1)
|_      uncompressed
MAC Address: 52:54:00:26:BE:A2 (QEMU Virtual NIC)

Nmap done: 1 IP address (1 host up) scanned in 91.34 seconds

可以看到只支持TLSv1,走的是第一个ssl_protocols的配置。

解决方案:
修改第一个SSL配置中

ssl_protocols TLSv1 TLSv1.1 TLSv1.2 SSLv3;