分模板网站和定制网站,外贸建站推广哪家好,凡科可以建设多个网站吗,网站建设 广州整理了一些网上的资料#xff0c;这里记录一下#xff0c;供大家参考
什么是SNI#xff1f; 传统的应用场景中#xff0c;一台服务器对应一个IP地址#xff0c;一个域名#xff0c;使用一张包含了域名信息的证书。随着云计算技术的普及#xff0c;在云中的虚拟机有了一…整理了一些网上的资料这里记录一下供大家参考
什么是SNI 传统的应用场景中一台服务器对应一个IP地址一个域名使用一张包含了域名信息的证书。随着云计算技术的普及在云中的虚拟机有了一个IP对应多个域名使用多张证书的应用场景SNI技术应运而生。SNIServer Name Indication即实现了一个服务器使用多个域名证书的TLS扩展支持用户配置多个域名证书。
SNI请求特点 HTTP请求的Host字段在请求的Header中。发起HTTPS请求时在TLS握手阶段还无法进行HTTP数据的解析此时TLS协议的Client Hello字段新增了一个Server Name字段请求的客户端可以通过这个字段填充请求的Host信息而服务端在TLS握手阶段就可以选择请求处理的证书实现SNI的功能。 各种工具对SNI的支持各种工具对SNI的支持https://en.wikipedia.org/wiki/Server_Name_Indication 1主流的浏览器 可以理解为客户端工具 2curl和wget之类的命令行工具 可以理解为客户端工具 curl和nginx关于SNI一些细节 已知的问题curl和jdk版本过低(客户端不支持SNI),导致ssl握手的SNI问题 3库和编程语言 可以理解为客户端工具 4web服务器 可以理解为服务端 默认SNI是开启的
Nginx支持的配置 Nginx支持SNI允许在同一个TLS服务端口下配置不同的域名用户通过请求不同的证书域名可返回相应的upstream响应结果。 本示例配置了一个证书域名为“lwl.test.com”的单向认证代理服务一个证书域名为“lwl.default.com”的双向认证代理服务使用相同的443端口具体配置如下
# Settings for a TLS enabled server. upstream lwl.test.com { server 192.168.58.196; } upstream default { server 192.168.58.195; } server { listen 443 ssl; listen [::]:443 ssl; server_name lwl.test.com; root /usr/share/nginx/html; ssl_certificate /etc/nginx/ssl_sni/server/lwl.test.com/server.crt; ssl_certificate_key /etc/nginx/ssl_sni/server/lwl.test.com/server.key; ssl_session_cache shared:SSL:1m; ssl_session_timeout 10m; ssl_ciphers HIGH:!aNULL:!MD5; ssl_prefer_server_ciphers on; # Load configuration files for the default server block. include /etc/nginx/default.d/*.conf; location / { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Cookie $http_cookie; proxy_pass http://lwl.test.com; } error_page 404 /404.html; location /40x.html { } error_page 500 502 503 504 /50x.html; location /50x.html { } } server { listen 443 ssl; listen [::]:443 ssl; server_name lwl.default.com; root /usr/share/nginx/html; ssl_certificate /etc/nginx/ssl_sni/server/lwl.default.com/server.crt; ssl_certificate_key /etc/nginx/ssl_sni/server/lwl.default.com/server.key; ssl_client_certificate /etc/nginx/ssl_sni/private/ca.crt; ssl_verify_client on; ssl_session_cache shared:SSL:1m; ssl_session_timeout 10m; ssl_ciphers HIGH:!aNULL:!MD5; ssl_prefer_server_ciphers on; # Load configuration files for the default server block. include /etc/nginx/default.d/*.conf; location / { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Cookie $http_cookie; proxy_pass http://default; } error_page 404 /404.html; location /40x.html { } error_page 500 502 503 504 /50x.html; location /50x.html { } }
单向认证测试 基于以上配置使用域名为“lwl.test.com”的证书进行单向认证的HTTPS访问请求如下# curl https://lwl.test.com:443 --cacert /etc/nginx/ssl_sni/private/ca.crt
返回的响应为 同时对当前的HTTPS请求进行抓包可以看到请求TLS握手阶段Client Hello请求中包含了Server Name为lwl.test.com的字段 双向认证测试 基于以上配置使用域名为“lwl.default.com”的证书进行双向认证的HTTPS访问请求如下
# curl --cert /etc/nginx/ssl_sni/users/client.crt:123456 --key /etc/nginx/ssl_sni/users/client.key https://lwl.default.com:443 --cacert /etc/nginx/ssl_sni/private/ca.crt
返回的响应为 同时对当前的HTTPS请求进行抓包可以看到请求TLS握手阶段Client Hello请求中包含了Server Name为lwl.default.com的字段 至此验证了Nginx可同时支持多个TLS证书的功能。
多证书配置 为支持多个SNI证书一种Nginx配置文件形式为每个证书配置单独一个server段此处以两个单向认证证书一个双向认证证书为例配置如下
# Settings for a TLS enabled server. upstream lwl.test.com { server 192.168.58.196; } upstream lwl.test1.com { server 192.168.58.194:8081; } upstream default { server 192.168.58.195; } server { listen 443 ssl; listen [::]:443 ssl; server_name lwl.test.com; root /usr/share/nginx/html; ssl_certificate /etc/nginx/ssl_sni/server/lwl.test.com/server.crt; ssl_certificate_key /etc/nginx/ssl_sni/server/lwl.test.com/server.key; ssl_session_cache shared:SSL:1m; ssl_session_timeout 10m; ssl_ciphers HIGH:!aNULL:!MD5; ssl_prefer_server_ciphers on; # Load configuration files for the default server block. include /etc/nginx/default.d/*.conf; location / { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Cookie $http_cookie; proxy_pass http://lwl.test.com; } error_page 404 /404.html; location /40x.html { } error_page 500 502 503 504 /50x.html; location /50x.html { } } server { listen 443 ssl; listen [::]:443 ssl; server_name lwl.test1.com; root /usr/share/nginx/html; ssl_certificate /etc/nginx/ssl_sni/server/lwl.test1.com/server.crt; ssl_certificate_key /etc/nginx/ssl_sni/server/lwl.test1.com/server.key; ssl_session_cache shared:SSL:1m; ssl_session_timeout 10m; ssl_ciphers HIGH:!aNULL:!MD5; ssl_prefer_server_ciphers on; # Load configuration files for the default server block. include /etc/nginx/default.d/*.conf; location / { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Cookie $http_cookie; proxy_pass http://lwl.test1.com; } error_page 404 /404.html; location /40x.html { } error_page 500 502 503 504 /50x.html; location /50x.html { } } server { listen 443 ssl; listen [::]:443 ssl; server_name lwl.default.com; root /usr/share/nginx/html; ssl_certificate /etc/nginx/ssl_sni/server/lwl.default.com/server.crt; ssl_certificate_key /etc/nginx/ssl_sni/server/lwl.default.com/server.key; ssl_client_certificate /etc/nginx/ssl_sni/private/ca.crt; ssl_verify_client on; ssl_session_cache shared:SSL:1m; ssl_session_timeout 10m; ssl_ciphers HIGH:!aNULL:!MD5; ssl_prefer_server_ciphers on; # Load configuration files for the default server block. include /etc/nginx/default.d/*.conf; location / { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Cookie $http_cookie; proxy_pass http://default; } error_page 404 /404.html; location /40x.html { } error_page 500 502 503 504 /50x.html; location /50x.html { } } 可以看到随着加载证书个数的增加Nginx配置篇幅增长较大不利于配置维护。
优化的配置方式 启用了sni的nginx如下变量会被赋值
$ssl_server_name默认SNI是开启的
检查nginx server端是否支持SNI扩展协议nginx -V 在1.7.0版本开始Nginx支持通过$ssl_server_name 变量获取TLS中的Server Name我们可以据此结合map映射指令提升配置的重用度一种优化后的配置方式如下
例子1
# Settings for a TLS enabled server. ssl_session_cache shared:SSL:1m; ssl_session_timeout 10m; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers HIGH:!aNULL:!MD5; ssl_prefer_server_ciphers on; map $ssl_server_name $ssl_string { lwl.test.com lwl.test.com; lwl.test1.com lwl.test1.com; default lwl.default.com; } upstream lwl.test.com { server 192.168.58.196; } upstream lwl.test1.com { server 192.168.58.194:8081; } upstream lwl.default.com { server 192.168.58.195; } server { listen 443 ssl; listen [::]:443 ssl; server_name $ssl_string; root /usr/share/nginx/html; ssl_certificate /etc/nginx/ssl_sni/server/$ssl_string/server.crt; ssl_certificate_key /etc/nginx/ssl_sni/server/$ssl_string/server.key; include /etc/nginx/default.d/*.conf; location / { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Cookie $http_cookie; proxy_pass http://$ssl_string; } error_page 404 /404.html; location /40x.html { } error_page 500 502 503 504 /50x.html; location /50x.html { } } 例子2 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关键字。
Module ngx_http_map_module
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/结束语 本文通过结合Nginx的 $ssl_server_name 变量与map指令提供了一种支持多个SNI证书配置的实现方式提高了配置维护的重用度。 参考
https://www.nginx.org.cn/article/detail/12416https://www.cnblogs.com/hugetong/p/11727275.htmlhttps://blog.csdn.net/wzj_110/article/details/110149984