nginx配置SNI阻断IP扫描导致的域名泄漏
Author:zhoulujun Date:
在Nginx的默认SSL配置下,当客户端尝试建立TLS连接时发送的SNI不包含域名时,Nginx依旧会发送SSL/TLS证书给客户端,从而导致ip背后的域名信息泄露。
SNI
SNI(Server Name Indication),是为了解决一个服务器使用多个域名和证书的SSL/TLS扩展。在使用TLS的时候,http server希望根据HTTP请求中HOST的不同,来决定使用不同的证书。简单地说这个扩展使得在同一个IP上可以以不同的证书配置不同的域名
一句话简述它的工作原理就是:在连接到服务器建立SSL链接之前先发送要访问站点的域名(Hostname),这样服务器根据这个域名返回一个合适的证书。
由于HTTP的HOST字段在HTTP GET中。而TLS的握手以及证书验证都是在HTTP开始之前。这个时候,TLS协议的HELLO字段中增加了一个server name字段,让HTTP的client的可以提前 设置HOST,从而使server在tls的握手阶段可以选择证书。
然后,这个机制本身可以抛开http不关心,只要TLS client提前设置了server name,便可以实现SNI
nginx开启SNI
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**
当客户端不支持SNI时,请求到服务器,nginx服务器默认会返回第一个server的证书用来和客户端进行校验
而Nginx如果开启了TLS SNI support,就能支持多个SSL加密站点共同使用一个IP
查看nginx是否支持SNI
方法也很简单,首先先看看你现在的Nginx是否enable了这个功能
/usr/local/nginx/sbin/nginx -V
nginx: nginx version: nginx/1.1.0
nginx: TLS SNI support disable
nginx: configure arguments: –user=www –group=www –prefix=/usr/local/nginx –with-http_stub_status_module –with-http_ssl_module –with-http_gzip_static_module –with-ipv6
如果是TLS SNI support disable那你需要重新编译下Nginx,如果enable了,你直接修改配置文件就行
配置nginx支持SNI
为了阻止Nginx发送证书给不合法的客户端,以下三个模块是必须的。
--with-stream
--with-stream_ssl_module
--with-stream_ssl_preread_module
修改nginx配置文件
stream { map $ssl_preread_server_name $name { #根据ssl sni name选择策略 backend.example.com web; #把backend.example.com 改成你的 default block; #只要sni name 不正确就断开连接 } upstream web { server 127.0.0.1:444; #正常的Web服务 } upstream block { server 127.0.0.1:80; #用于阻止不合法请求 } server { listen 443 reuseport; listen [::]:443 reuseport; proxy_pass $name; ssl_preread on; #开启ssl_preread } } # server 配置 server { listen 80 default_server; listen [::]:80 default_server; server_name _; #不提供正确的域名直接断开连接 return 444; } server { listen 127.0.0.1:444 ssl http2; #端口号和stream中的要一样 ssl_certificate /path/to/example.crt; ssl_certificate_key /path/to/example.key; ssl_trusted_certificate /path/to/example.ca-bundle; ssl_protocols TLSv1.3 TLSv1.2; ssl_prefer_server_ciphers off; ssl_early_data on; ssl_session_cache shared:SSL:40m; ssl_session_timeout 4h; ssl_session_tickets off; ssl_stapling on; ssl_stapling_verify on; resolver 8.8.4.4; resolver_timeout 10s; ssl_dhparam /etc/nginx/nginx.pem; server_name example.com; add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always; }
参考文章:
https://carey.akhack.com/2017/05/03/nginx支持SNI/
不给SNI,就滚蛋! 防止ip扫描导致的域名泄漏 --Nginx版 https://www.johnrosen1.com/nginx-sni/
nginx使用SNI功能的方法 https://www.cnblogs.com/hugetong/p/11727275.html
转载本站文章《nginx配置SNI阻断IP扫描导致的域名泄漏》,
请注明出处:https://www.zhoulujun.cn/html/tools/webServer/nginx/2020_0407_8365.html