HTTPS-SSL/TSL与SNI的关系以及同IP多域名虚拟主机的SSL/TSL认证

早期的SSLv2根据经典的公钥基础设施PKI(Public Key Infrastructure)设计,它默认认为:一台服务器(或者说一个IP)只会提供一个服务,所以在SSL握手时,服务器端可以确信客户端申请的是哪张证书。

但是让人万万没有想到的是,虚拟主机大力发展起来了,这就造成了一个IP会对应多个域名的情况。解决办法有一些,例如申请泛域名证书,对所有*.yourdomain.com的域名都可以认证,但如果你还有一个yourdomain.net的域名,那就不行了。

在HTTP协议中,请求的域名作为主机头(Host)放在HTTP Header中,所以服务器端知道应该把请求引向哪个域名,但是早期的SSL做不到这一点,因为在SSL握手的过程中,根本不会有Host的信息,所以服务器端通常返回的是配置中的第一个可用证书。因而一些较老的环境,可能会产生多域名分别配好了证书,但返回的始终是同一个。

根据HTTPS的工作原理,浏览器在访问一个HTTPS站点时,先与服务器建立SSL连接,建立连接的第一步就是请求服务器的证书。而服务器在发送证书的时候,是不知道浏览器访问的是哪个域名的,所以不能根据不同域名发送不同的证书。

既然问题的原因是在SSL握手时缺少主机头信息,那么补上就是了。

SNI(Server Name Indication)是为了解决一个服务器使用多个域名和证书的SSL/TLS扩展。定义在RFC 4366。是一项用于改善SSL/TLS的技术,在SSLv3/TLSv1中被启用。它允许客户端在发起SSL握手请求时(具体说来,是客户端发出SSL请求中的ClientHello阶段),就提交请求的Host信息,使得服务器能够切换到正确的域并返回相应的证书。一句话简述它的工作原理就是,在连接到服务器建立SSL链接之前先发送要访问站点的域名(Hostname),这样服务器根据这个域名返回一个合适的证书。目前,大多数操作系统和浏览器都已经很好地支持SNI扩展,OpenSSL 0.9.8已经内置这一功能,据说新版的nginx也支持SNI。

要使用SNI,需要客户端和服务器端同时满足条件,幸好对于现代浏览器来说,大部分都支持SSLv3/TLSv1,所以都可以享受SNI带来的便利。

用代码来演示:

server {
    listen          443;
    server_name     www.example.com;
    ssl             on;
    ssl_certificate www.example.com.crt;
    ...
}

server {
    listen          443;
    server_name     www.example.org;
    ssl             on;
    ssl_certificate www.example.org.crt;
    ...
}

使用上面的配置,不论浏览器请求哪个主机,都只会收到默认主机www.example.com的证书。这是由SSL协议本身的行为引起的——先建立SSL连接,再发送HTTP请求,所以nginx建立SSL连接时不知道所请求主机的名字,因此,它只会返回默认主机的证书。

最古老的也是最稳定的解决方法就是每个HTTPS主机使用不同的IP地址:

server {
    listen          192.168.1.1:443;
    server_name     www.example.com;
    ssl             on;
    ssl_certificate www.example.com.crt;
    ...
}

server {
    listen          192.168.1.2:443;
    server_name     www.example.org;
    ssl             on;
    ssl_certificate www.example.org.crt;
    ...
}

那么,在同一个IP上,如何配置多个HTTPS主机呢?

nginx支持TLS协议的SNI扩展。不过,SNI扩展还必须有客户端的支持,另外本地的OpenSSL必须支持它。

如果启用了SSL支持,nginx便会自动识别OpenSSL并启用SNI。是否启用SNI支持,是在编译时由当时的 ssl.h 决定的(SSL_CTRL_SET_TLSEXT_HOSTNAME),如果编译时使用的OpenSSL库支持SNI,则目标系统的OpenSSL库只要支持它就可以正常使用SNI了。

nginx在默认情况下是TLS SNI support disabled。如果需要支持,编译时需要增加:

--with-http_ssl_module --with-openssl=./openssl-1.0.1e --with-openssl-opt="enable-tlsext" 

但是我用的nginx/1.10.1,在编译时没有添加--with-open-opt="enable-tlsext",就可以支持SNI了,所以最新版本默认是开启的?

时间: 2024-10-28 10:03:16

HTTPS-SSL/TSL与SNI的关系以及同IP多域名虚拟主机的SSL/TSL认证的相关文章

apache实现多域名虚拟主机的SSL认证

#/etc/httpd/conf.d/ssl.conf 配置如下: LoadModule ssl_module modules/mod_ssl.so Listen 443 NameVirtualHost 109.109.109.109:443 AddType application/x-x509-ca-cert .crt AddType application/x-pkcs7-crl    .crl SSLPassPhraseDialog  builtin SSLSessionCache    

HTTPS+基于域名虚拟主机设置

#/etc/httpd/conf.d/ssl.conf #grep -v ^# /etc/httpd/conf.d/ssl.conf | grep -v ^$ NameVirtualHost 172.16.254.101:443 *********************定义基于域名虚拟主机 <VirtualHost 172.16.254.101:443> *********************baidu.comDocumentRoot "/var/www/html/baidu&

Apache虚拟目录、用户认证、基于端口/IP/域名的虚拟主机、SSL

环境配置: 配置DNS以便域名解析 安装Bind软件包. yum install -y bind 2. 修改Bind配置文件. vim /etc/named.conf listen-on port 53 { 192.168.200.101; }; allow-query { any; }; vim /etc/named.rfc1912.zones zone "a.com" IN { type master; file "a.com.localhost"; allow

13_搭建Nginx服务器、配置网页认证、基于域名的虚拟主机、ssl虚拟主机

官方yum源:[nginx]name=nginx repobaseurl=http://nginx.org/packages/centos/$releasever/$basearch/gpgcheck=0enabled=1 pc71. 安装nginx]# yum -y install nginx]# nginx]# nginx -Vnginx version: nginx/1.16.1]# netstat -anptu | grep nginx]# curl http://10.10.11.10

Apache2.4版本环境下基于虚拟主机、ssl、用户控制

环境说明:此篇博客是基于编译安装httpd2.4博客基础上进行的 一.虚拟主机: 1.1基于host [[email protected] apache]# vim/etc/httpd24/httpd.conf Include/etc/httpd24/extra/httpd-vhosts.conf   #开启虚拟主机 #DocumentRoot"/www/htdocs"    #将中心主机注释掉 [[email protected] apache]# cd/etc/httpd24/ex

虚拟主机配置ssl

在微信应用中,需要证书中的三个文件全部引入,否则会出现白屏. 原文地址:https://www.cnblogs.com/xiaochongzi/p/8274260.html

httpd-2.4.9编译安装与配置(CGI、虚拟主机、https、deflate压缩)

1.准备好软件: pcre及pcre-devel pcre是一个perl库,包含perl所兼容的正则表达式库.由于httpd服务具有CGI功能,而大多数的CGI都是基于perl的,所以需要安装这个库. apr-1.5.1 apr是Apache可移植运行库,此库可以使httpd跨平台使用.是Apache必须依赖的库.httpd-2.4的event模块apr必须是1.5.x以上的 apr-util-1.5.3 基于apr的更高级的库,名字类似是apr的工具 httpd-2.4.9 今天要编译配置的主

httpd高级配置(虚拟主机,https,访问控制)

一下的实验环境都是在httpd-2.4上完成 虚拟主机的配置 虚拟主机就是在同一台物理机上,部署多个站点.虚拟主机的实现方式有3种:基于端口,基于IP地址,基于主机名.由于浏览器的默认访问端口是80,以及目前ipv4的紧缺,所以目前应用最广泛的是基于主机名的虚拟主机.基于端口的虚拟主机通过监听的端口不同,区分对不同主机的访问.基于IP地址的虚拟主机通过访问的IP地址的不同来区分.基于主机名的虚拟主机是通过http请求报文的host首部来区分不同的请求(同一个物理机上的虚拟主机,IP地址相同,主机

[从零开始搭网站六]为域名申请免费SSL证书(https),并为Tomcat配置https域名所用的多SSL证书

点击下面连接查看从零开始搭网站全系列 从零开始搭网站 由于国内的网络环境比较恶劣,运营商流量劫持的情况比较严重,一般表现为别人打开你的网站的时候会弹一些莫名其妙的广告...更过分的会跳转至别的网站. 那么为了解决这种情况,那么我们就要申请SSL证书,并且配置服务器. 并且,我准备再学习并写一个微信小程序,而微信小程序所有接口都需要走https,那么全线https就势在必行. 目前免费https其实有很多家,我之前出过一个教程是 用Let's Encrypt实现Https(Windows环境+To