如果请求与路径不匹配,如何让 Nginx 返回 444?

问题描述 投票:0回答:3

简短版本:

我想使用 NGINX 作为反向代理,以便访问面向公众的 URL 的客户端从代理后面的内部 Gunicorn 服务器获取 API 数据:

external path (proxy) => internal app
<static IP>/ABC/data  => 127.0.0.1:8001/data

我的位置映射不正确。

长版

我是第一次设置 NGINX,并尝试将其用作 Gunicorn 提供的 REST API 的反向代理。该 API 在

127.0.0.1:8001
提供,我可以从服务器访问它并获得适当的响应,因此我相信该部分工作正常。它使用 Supervisord 持续运行。

我想从外部访问位于

<static IP>/ABC/data
的 API 端点之一。在 Gunicorn 服务器上,此端点位于
localhost:8001/data
。最终,我想通过 NGINX 为其他 Web 应用程序提供服务,其根如
<static IP>/foo
<static IP>/bar
等。这些 Web 应用程序中的每一个都来自一个独立的 Python 应用程序。但目前,当我尝试从外部访问端点时,收到 444 错误代码,因此我认为我没有正确配置 NGINX。

我从 Guincorn 网站上发布的 config 中整理了我第一次尝试的 NGINX 配置。我没有将其分为单个配置,而是将其分为全局配置和特定于站点的配置。我的全局配置在 etc/nginx/nginx.conf

 看起来像:

user ops; worker_processes 1; pid /run/nginx.pid; error_log /tmp/nginx.error.log; events { worker_connections 1024; # increase if you have lots of clients accept_mutex off; # set to 'on' if nginx worker_processes > 1 use epoll; # 'use epoll;' to enable for Linux 2.6+ # 'use kqueue;' to enable for FreeBSD, OSX } http { include mime.types; # fallback in case we can't determine a type default_type application/octet-stream; access_log /tmp/nginx.access.log combined; sendfile on; server_tokens off; server { # if no Host match, close the connection to prevent host spoofing listen 80 default_server; return 444; } gzip on; gzip_disable "msie6"; include /etc/nginx/conf.d/*.conf; include /etc/nginx/sites-enabled/*; }

然后我的站点特定配置位于

/etc/nginx/sites-available

 (并在 
/etc/nginx/sites-enabled
 中符号链接)是:

upstream app_server { # fail_timeout=0 means we always retry an upstream even if it failed # to return a good HTTP response # for UNIX domain socket setups # server unix:/tmp/gunicorn_abc_api.sock fail_timeout=0; # for a TCP configuration server 127.0.0.1:8001 fail_timeout=0; } server { # use 'listen 80 deferred;' for Linux # use 'listen 80 accept_filter=httpready;' for FreeBSD listen 80 deferred; client_max_body_size 4G; # set the correct host(s) for your site server_name _; keepalive_timeout 100; # path for static files #root /path/to/app/current/public; location /ABC { # checks for static file, if not found proxy to app try_files $uri @proxy_to_app; } location @proxy_to_app { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # enable this if and only if you use HTTPS # proxy_set_header X-Forwarded-Proto https; proxy_set_header Host $http_host; # we don't want nginx trying to do something clever with # redirects, we set the Host: header above already. proxy_redirect off; proxy_pass http://app_server; } # error_page 500 502 503 504 /500.html; # location = /500.html { # root /path/to/app/current/public; # } }

配置通过了

service nginx checkconfig

,但我最终在访问日志中看到以下内容:

XXX.XXX.X.XXX - - [09/Sep/2016:01:03:18 +0000] "GET /ABC/data HTTP/1.1" 444 0 "-" "python-requests/2.10.0"

我认为我没有正确配置路由。任何建议将不胜感激。

更新

我现在可以使用它,只需进行一些更改。我注释掉了以下块:

server { # if no Host match, close the connection to prevent host spoofing listen 80 default_server; return 444; }

除非有有效的路由,否则我无法弄清楚如何获得返回 444 的行为。我很愿意,但我仍然停留在这一部分。该块似乎会吃掉所有传入的请求。我还将应用程序配置更改为:

upstream app_server { server 127.0.0.1:8001 fail_timeout=0; } server { # use 'listen 80 deferred;' for Linux # use 'listen 80 accept_filter=httpready;' for FreeBSD listen 80 deferred; client_max_body_size 100M; # set the correct host(s) for your site server_name $hostname; keepalive_timeout 100; location /ABC { # checks for static file, if not found proxy to app try_files $uri @proxy_to_app; } location @proxy_to_app { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # enable this if and only if you use HTTPS # proxy_set_header X-Forwarded-Proto https; proxy_set_header Host $http_host; # we don't want nginx trying to do something clever with # redirects, we set the Host: header above already. proxy_redirect off; rewrite ^/ABC/(.*) /$1 break; proxy_pass http://app_server; } }

基本上,我似乎必须明确设置

server_name

 并使用 
rewrite
 来获取到应用程序服务器的正确映射。

nginx reverse-proxy gunicorn
3个回答
2
投票
这对我来说效果很好,仅当没有其他服务器名称匹配时才返回 444(挂断连接):

server { listen 80; server_name ""; return 444; }
    

0
投票
在服务器块内添加此行*将 facebook 替换为您的域名

if ( $http_host !~* ^(facebook\.com|www\.facebook\.com)$ ) { return 444;
}


0
投票
我通过简单地将“/”设置为返回 444 就可以让它工作了。后续的“位置”不受影响并且完美工作!

location / { return 444; }


    

© www.soinside.com 2019 - 2024. All rights reserved.