Nginx的。 我如何拒绝对不公开的ssl虚拟服务器的请求?

我有一个通配符SSL证书和在同一个IP上的几个子域。 现在我想让我的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; //} } 

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

它不会这样工作:SSL握手发生在HTTP之前,因此证书上的名称将在浏览器中进行评估,然后您可以在nginxconfiguration中redirect或执行其他任何操作。

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

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

注意:是的,一般来说if是恶的 ,这是真的,但if在这种情况下使用是安全的。 (如果你需要说服自己,请阅读链接页面。)

与build议相反,只是添加下面的块将不起作用:

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

因为与validname.domain.com匹配的SSL证书将不匹配一些随机的域名。 我已经尝试过了,nginx像块一样没有出现。

这也是行不通的:

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

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

我今天实施了上述解决scheme,并且运作良好。 所有未指定的URL现在都被删除。 在实际的虚拟服务器条目之前放置这个服务器代码是关键 – 所有不正确的URL现在都转到这个“默认”服务器。

 ... server { listen 443; server_name _; return 444; } server { listen 443; server_name [URL] 

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

 http { ... server { listen 80; listen 443 ssl; return 444; } server { server_name validname.domain.com; ... } } 

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

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

这是如何 – 你需要做这样一个捕获所有的服务器'default_server',并需要提供证书/密钥的path,以便它可以解密传入SSL请求并匹配主机头:

 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,并且因为它不能接受没有cert / key的ssl连接而失败。 可以使用任何证书/密钥,例如自签名。

另请参阅https://serverfault.com/a/841643/87439