nginx 拒绝非sni https请求

我想测试下nginx拒绝不携带servername字段过来ssl建联的https请求,即非sni的https请求
nginx的sni是开启的

img

服务器设置的nginx配置如下:

http {
    include       mime.types;
    default_type  application/octet-stream;
    log_format  main  '[$time_local]"$status"';
    sendfile        on;
    keepalive_timeout  65;
    server {
        #SSL 访问端口号为 443
        listen 443 ;
        ssl on;
        #填写绑定证书的域名
       server_name  caiyd2.8686c.com;
        #证书文件名称
        ssl_certificate caiyd2.8686c.com_bundle.crt;
        #私钥文件名称
        ssl_certificate_key caiyd2.8686c.com.key;
        ssl_session_timeout 5m;
        ssl_ciphers  HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers  on;
        location ~ /.+$  {
            root   html;
        }
        server {
                listen 80
                listen 443 default_server;
                return 403 "Wrong servername!";
        }
}

但是这样测试的话,https所有请求都无法建联,看上去是因为匹配到了默认的server(default_server),然后里面没证书导致无法建联。

img


我把默认的server注释掉,只留下一个server的话,不是caiyd2.8686c.com的域名也能建联成功。 在我看来sni是没起作用的。

我理解的是,sni开启的作用是在ssl证书交互环节,通过携带的server_name字段,确认应该用哪个server里面的证书来建联,但是现在看还是按照普通的逻辑:通过请求中的host字段来匹配server,匹配不到就选默认的server。

我想实现的是只有https请求中携带了servername字段为caiyd2.8686c.com的请求才接受,其他域名的https请求或者域名caiyd2.8686c.com的非sni请求,在ssl握手阶段就不让建联,请问是可以怎么实现呢,

我感觉我上面按照sni的逻辑来看的话,是应该实现的,希望有人指点下,谢谢。

sni的作用是允许nginx配置额外https域名的,可以允许多个域名使用https证书,作用是放开,不是拒绝啊。

其他域名的https请求,如果其他域名不支持https,用户访问https本身就不能访问啊,你没有配置也能访问?
caiyd2.8686c.com非https请求,一般是nginx自动配置转换成https,示例,你浏览器输入地址:http://www.baidu.com,url会自动变成:https://www.baidu.com

server里加
fastcgi_param HTTPS $fastcgi_https;

http {
 
     map $scheme $fastcgi_https { ## Detect when HTTPS is used
         default off;
         https on;
     }
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;
 
   
    ssi on;
 
    server {
        listen       80;
 
        root    /data/static;
         server_name   localhost;
 
        listen 443 ssl;
  
        fastcgi_param HTTPS $fastcgi_https;
 
        ssl_certificate 213469990410554.pem;
        ssl_certificate_key 213469990410554.key;
 
        
        charset utf-8;
 
        location = / {
            index index.html;
        }
 
        location / {
            index  index.html;
            proxy_pass http://127.0.0.1:9084;
        }
    
        location ~.*\.(js|css|png|gif|jpg|jpeg|bmp|html|rar|less|ico|ttf|woff|woff2|properties)?        $ {
            expires 4h;
        }
    }
 
 
}

TLS SNI support enabled就是支持域名证书。
你说的“只留下一个server的话,不是caiyd2.8686c.com的域名也能建联成功。 在我看来sni是没起作用的。”没理解?
你没有配置server_name参数指定的域名可以访问到你的服务吗?这不可能吧。

108 server {
109 listen 443 ssl ;
110 listen 80;
111 server_name http://www.linux.org/;
112 error_page 497 https://www.linux.org/ ; //error_page497 重定向
113 ssl_certificate /root/3;
114 ssl_certificate_key /root/dty_nopass.key;
115
116 ssl_session_cache shared:SSL:1m;
117 ssl_session_timeout 5m;
118 ssl on ;
119 ssl_ciphers HIGH:!aNULL:!MD5;
120 ssl_prefer_server_ciphers on;
121 location / {
122 root html;
123 index index.html index.htm;
124 }
125 }

强制只允许https访问

你可以采用多server处理。取消默认的server。比如监听443,但是server_name配置好你需要命中的域名;80的配置转443端口。这样就实现你要实现的拒绝其他域名。不需要开启sni。

TLS SNI support enabled就是支持域名证书。
这一块可以你去官网看看

用宝塔配置起来会方便点,TLS SNI support enabled就是支持域名证书。

Nginx开启多SSL证书支持--TLS SNI support。

img


翻译大致如下:
没有对等证书可用80
没有发送客户端证书
CA名称403NSSL握手读取了0字节,并写入了314字节新的,
(NONE), Cipher是(NONE)
不支持安全重协商

希望对题主有所帮助!

宝塔更方便