AWS,Nginx和Django:默认服务器来防止虚假主机string

我们有一个使用AWS的服务器设置,必须满足以下要求:

1:必须允许源自负载平衡器的传入请求(具体来说,运行状况检查和延迟检查)到达Web服务器。

2:必须允许包含正确Hoststring的有效请求到达Web服务器。

3:所有其他的请求必须被拒绝,非标准的Nginx'444'拒绝,这意味着它们将被忽略。

另外,我们的网站有几个子域,每个子域对不同的客户端运行基本相同的代码。 我们设置Nginx将所有httpstream量redirect到这些子域名到https。 我将调用这些子域名“a.example.com”,“b.example.com”和“c.example.com”。

我们已经注意到,在我们的日志中,我们的Django代码由于虚假的主机string超过了Nginx而返回了大量的500个错误。 我们看到的每个请求的主机string是“* .example.com”,它匹配我们的任何一个子域,因此使它成为Django代码。 由于该主机string无法识别,Django返回500错误。

以下是我们的Nginx站点可用文件的近似近似值:

 # Repeat this for each subdomain: server { server_name a.example.com; listen 80; return 301 https://a.example.com$request_uri; } server { server_name a.example.com; listen 443; location / { set $my_host $host; if ($host ~ "\d+\.\d+\.\d+\.\d+") { set $my_host "elb.example.com"; } } } 

我们试图在Nginx中使用下面的“黑洞”服务器定义来捕获这个错误的主机string:

 server { server_name *.example.com; listen 80 default_server; listen 443 default_server; return 444 } 

但是,“* .example.com”主机string与https服务器定义中的一个相匹配,并被转发给Django代码。

我错过了什么?

在你尝试的configuration中,你需要改变的只是server_namevariables,而不能匹配任何其他服务器块,但是将是有效的,例如localhost ,它应该是服务器,如果它们不匹配任何其他服务器主机名(因为你把它标记为default_server – 这只会使得通配符主机名变得复杂)。

 server { server_name localhost; listen 80 default_server; listen 443 default_server; return 444 }