[nginx] nginx使用SNI功能的方法

SNI是什么

在使用TLS的时候,http server希望根据HTTP请求中HOST的不同,来决定使用不同的证书。

 

SNI细节

由于HTTP的HOST字段在HTTP GET中。而TLS的握手以及证书验证都是在HTTP开始之前。

这个时候,TLS协议的HELLO字段中增加了一个server name字段,让HTTP的client的可以提前

设置HOST,从而使server在tls的握手阶段可以选择证书。

 

然后,这个机制本身可以抛开http不关心,只要TLS client提前设置了server name,便可以实现SNI

 

nginx的配置

检测nginx是否支持sni,http://nginx.org/en/docs/http/configuring_https_servers.html#Server%20Name%20Indication

$ nginx -V
...
TLS SNI support enabled
...

 

启用了sni的nginx,如下变量会被赋值

$ssl_server_name

证书命令ssl_certificate,也可以通过变量进行设置,形如:

ssl_certificate     $ssl_server_name.crt;
ssl_certificate_key $ssl_server_name.key;

 

于是我们可以通过 nginx config中的嵌入逻辑,完成sni的完整配置。

如:

stream {
       upstream test {
               server 127.0.0.1:50001;
       }

       map $ssl_server_name $sni_string {
               test1.www.local test1;
               test2.www.local test2;
               test3.www.local test3;
               default test1;
       }

       map $ssl_server_name $sni_string445 {
               test1.www.local test4451;
               test2.www.local test4452;
               test3.www.local test4453;
               default test4451;
       }


       server {
               listen 444 ssl;
               ssl_certificate /data/sni/sni_${sni_string}.cer;
               ssl_certificate_key /data/sni/sni_${sni_string}.key;
               proxy_pass test;
       }
       server {
               listen 445 ssl;
               ssl_certificate /data/sni445/sni_${sni_string445}.cer;
               ssl_certificate_key /data/sni445/sni_${sni_string445}.key;
               proxy_pass test;
       }

}

 

注意,如果希望map命令支持host的最长匹配与正则,需要再添加hostnames关键字。

http://nginx.org/en/docs/http/ngx_http_map_module.html#map

map命令的本质,可以理解为通过旧的变量定义出了一个新的变量。

 

 模拟tcp客户端的方法:

openssl s_client -connect t9:5000 -CAfile ~/Keys/https/root/root.cer -servername test2.www.local

[openssl][nginx] 使用openssl模拟ssl/tls客户端测试nginx stream

 

模拟http客户端的方法:

curl --cacert ~/Keys/https/root/root.cer -vvvv  https://test1.tls.local/
curl --cacert ~/Keys/https/root/root.cer -vvvv  https://test2.tls.local/
curl --cacert ~/Keys/https/root/root.cer -vvvv  https://test3.tls.local/
curl --cacert ~/Keys/https/root/root.cer -vvvv  https://test3.www.local/

 

posted on 2019-10-23 16:54  toong  阅读(10874)  评论(0编辑  收藏  举报