因此没有辦法设置 HTTP/HTTPS 混合服务器。于是 Nginx 新增了监听命令 listen参数 ssl 來解决这个问题,Nginx 現代版本的ssl命令并不推荐使用
基于服务器名称(name-based)的 HTTPS 服务器
一个常见的问题就是当使用同一个 IP 地址去配置两个或更多的 HTTPS 服务器的时候,出现证书不匹配的情況:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
server {
listen 443 ssl;
server_name www.example.com;
ssl_certificate www.example.com.crt;
#...
}
server {
listen 443 ssl;
server_name www.example.org;
ssl_certificate www.example.org.crt;
#...
}
|
这种情况下浏览器会获取默认的服务器证书(如上面例子的 www.example.com.crt)而忽视请求的服务器名,如输入网址:www.example.org,服务器会发送 www.example.com.crt 的证书到客戶端,而不是 www.exaple.org.crt。
这是因为 SSL 协议行为所致,SSL 连接在浏览器发送 HTTP 请求之前就被建立,Nginx 并不知道被请求的服务器名字,因此 Nginx 只会提供默认的服务器证书。
解決这个问题最原始最有效的方法就是为每个 HTTPS 服务器分配独立的 IP 地址:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
server {
listen 192.168.1.1:443 ssl;
server_name www.example.com;
ssl_certificate www.example.com.crt;
#...
}
server {
listen 192.168.1.2:443 ssl;
server_name www.example.org;
ssl_certificate www.example.org.crt;
#...
}
|
更多解決方案
除此之外,官方还介绍了两个方法:泛域证书和域名指示(SNI)
其实 OpenSSL 在 0.9.8f版本就支持 SNI 了,只要在安裝的时候加上 --enable-tlsext 选项就可以。到了 0.9.8j版本,这个选项在安裝的时候会默认启用。如果创建 Nginx 的时候支持 SNI,可以在 Nginx 版本信息查到以下的字段:
1
|
TLS SNI support enabled
|
因此,如果较新版本的 Nginx 使用默认的 OpenSSL 库,是不存在使用 HTTPS 同时支持基于名字的虚拟主机的时候同 IP 不同域名证书不匹配的问题。
注意:即使新版本的 Nginx 在创建时支持了 SNI,如果 Nginx 动态加载不支持 SNI 的 OpenSSL 库的话,SNI 扩展将不可用
有兴趣的朋友可以看下:
An SSL certificate with several names && Server Name Indication
总结
OK,我们简单总结一下在 Nginx 下配置 HTTPS 的关键要点:
- 获得 SSL 证书
- 通过 OpenSSL 命令获得 example.key 和 example.csr 文件
- 提供 example.csr 文件给第三方可靠证书颁发机构,选择适合的安全级别证书并签署,获得 example.crt 文件
- 通过 listen 命令 SSL 参数以及引用 example.key 和 example.crt 文件完成 HTTPS 基础配置
- HTTPS优化
- 减少 CPU 运算量
- 使用 keepalive 长连接
- 复用 SSL 会话参数
- 使用 HSTS 策略强制浏览器使用 HTTPS 连接
- 添加 Strict-Transport-Security 头部信息
- 使用 HSTS 预加载列表(HSTS Preload List)
- 加强 HTTPS 安全性
- 使用迪菲-赫尔曼密钥交换(D-H,Diffie–Hellman key exchange)方案
- 添加 X-Frame-Options 头部信息,减少点击劫持
- 添加 X-Content-Type-Options 头部信息,禁止服务器自动解析资源类型
- 添加 X-Xss-Protection 头部信息,防XSS攻击
- 减少 CPU 运算量
- HTTP/HTTPS混合服务器配置
- 基于服务器名称(name-based)的 HTTPS 服务器
- 为每个 HTTPS 服务器分配独立的 IP 地址
- 泛域证书
- 域名标识(SNI)
其实简单的个人博客,如果没有敏感数据交互的话,使用 http 协议通讯,一般都夠用了,页面速度还会更快,但正如文章开头所说,戴上『绿锁』,更专业更安全~~有兴趣的同学可以去深入了解折腾下)
发表评论