Nginx。如何拒绝对未列出的SSL虚拟服务器的请求?


13

我在同一个IP上有一个通配符SSL证书和几个子域。现在,我希望我的nginx只处理提到的服务器名称,并断开与其他服务器的连接,以便看起来好像 nginx未运行未列出的服务器名称(不响应,拒绝,无效,没有单个字节作为响应)。我做以下

ssl_certificate         tls/domain.crt;
ssl_certificate_key     tls/domain.key;

server {
  listen 1.2.3.4:443 ssl;
  server_name validname.domain.com;
  //
}

server {
  listen 1.2.3.4:443 ssl;
  server_name _;
  // deny all;
  // return 444;
  // return 404;
  //location {
  //  deny all;
  //}
}

我已经尝试了最后一个服务器块中的几乎所有内容,但没有成功。我从已知的虚拟服务器收到有效响应或错误代码。请帮忙。

Answers:


7

这种方式不起作用:SSL握手发生在HTTP之前,因此证书的名称将在浏览器中得到评估,然后您才能在nginx配置中重定向或执行其他任何操作。


这不好,但必须承认)谢谢。
andbi 2012年

3
这是不正确的:您可以在较低级别上执行其他操作,例如断开连接而没有任何响应,如其他答案中所述。
collimarco 2014年

13

cjc的答案已经正确指出了启用SSL时尝试匹配主机名的问题。但是,可以这样做,如下所示:

server {
    ...

    if ($host !~* ^validname\.domain\.com$ ) {
        return 444;
    }
    ...
}

注意:是的,通常if是邪恶的,但if在这种情况下可以安全使用。(如果需要说服自己,请阅读链接的页面。)

与建议的相反,仅添加以下块将不起作用:

server {
    listen 80;
    listen 443 ssl;
    return 444;
}

因为匹配的SSL证书validname.domain.com不会匹配某些随机域名。我已经尝试过了,nginx表现得好像根本不存在该块。

这也行不通:

server {
    listen       443;
    server_name    _;
    return 444; 
}

因为它会使端口443上的每个 HTTPS连接失败,即使那些应该通过的HTTPS连接也会失败。我也尝试过这个。wget报告了SSL握手错误。


5

这里的大多数答案是关于为什么它不起作用,而不是如何使其起作用。

这是方法-您需要将这样的通用服务器设置为'default_server',并需要提供cert / key的路径,以便它可以解密传入的ssl请求并匹配Host标头:

server {
    listen 80 default_server;
    listen 443 ssl default_server;
    server_name _;
    ssl_certificate <path to cert>;
    ssl_certificate_key <path to key>;
    return 404;
}

注意那里的ssl_certificate / ssl_certificate_key。如果未指定它们,nginx仍将尝试使用此类default_server并失败,因为它无法接受带有证书/密钥的ssl连接。一个人可以使用任何证书/密钥,例如自签名。...

生成自签名证书:

openssl req -x509 -newkey rsa:4096 -nodes -out cert.pem -keyout key.pem -days 365 

另请参阅/server//a/841643/87439


1
你有尝试过吗?如何创建与服务器名称“ _”匹配的SSL证书?
蒂姆(Tim)

是的,此解决方案对我有用。我有一个完全相同的问题,并且从文档中得知nginx需要证书/密钥,因为它不查看TLS SNI。您可以使用任何证书/密钥,例如自签名。
andreycpp

1

我今天实现了上述解决方案,并且可以正常工作。现在,所有未指定的URL均已删除。在实际的虚拟服务器条目成为关键之前放置此服务器代码-现在,所有格式错误的URL都将到达此“默认”服务器。

... 
server {
     listen       443;
     server_name    _;
     return 444; }

server {
     listen       443;
     server_name  [URL]

0

您应该能够通过将处理未列出项目的服务器设置为配置中的第一个服务器块来处理此问题。

http {
    ...

    server {
        listen 80;
        listen 443 ssl;
        return 444;
    }

    server {
        server_name validname.domain.com;
        ...
    }
}

此服务器块将处理所有未明确标识的域。


1
它不起作用
AmirHossein '18
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.