SNI: 让Nginx在一个IP上使用多个证书
近几天,准备在nginx给多个域名配证书,原想着在不同的server下配不同的证书是多么自然的一件事情啊。
然后老大跟我说不能,这样会收不到请求,我说为啥呢?
在 这篇 文章中,我们可以看到,
SSL其实位于TCP/IP协议层中,应用层和运输层之间,尚未到达HTTP这一层,但是又位于TCP之上。
我们知道,Nginx支持在一个IP上服务多个域名,原因就在于,HTTP协议里有一个字段是 Host
,通过匹配
这个字段的值和 nginx.conf
中的 server_name
,Nginx就可以方便的把请求转发到对应的内容服务器上去。
但是对于HTTPS却行不通,为什么呢?上面说过,SSL位于HTTP协议和TCP协议之间,也就是说,一个请求到来, 在握手阶段,SSL并不知道这个请求到底是请求哪个Host。而要知道Host,就需要解密HTTP请求,但是SSL这一层正是 为了加密HTTP的。于是就陷入了一种先有鸡还是先有蛋的问题。
所以有了SNI:Server Name Indication,工作原理是在SSL握手的阶段,浏览器把Host字段一起发过去。这样 Nginx便可以在一个IP上服务多个HTTPS服务。但是这个技术有三个要求:
- Nginx编译时需要允许这个设定,可以通过
nginx -V
查看 - Nginx动态链接的openssl要支持这个功能,也可以通过
nginx -V
看,如果没有异常信息,就是支持的,此外openssl从 0.9.8f开始支持这个功能 - 用户所使用的浏览器支持这个功能
老大所说的不能,其原因就是因为有一部分用户还在使用非常非常老的浏览器 :(
参考:
- https://www.ruby-forum.com/topic/186664
- http://nginx.org/en/docs/http/configuring_https_servers.html#sni
- https://en.wikipedia.org/wiki/Server_Name_Indication#Support
更多文章
本站热门
- socks5 协议详解
- zerotier简明教程
- 搞定面试中的系统设计题
- frp 源码阅读与分析(一):流程和概念
- 用peewee代替SQLAlchemy
- Golang(Go语言)中实现典型的fork调用
- DNSCrypt简明教程
- 一个Gunicorn worker数量引发的血案
- Golang validator使用教程
- Docker组件介绍(二):shim, docker-init和docker-proxy
- Docker组件介绍(一):runc和containerd
- 使用Go语言实现一个异步任务框架
- 协程(coroutine)简介 - 什么是协程?
- SQLAlchemy简明教程
- Go Module 简明教程