2016-09-09 52 views
0

短版:如果請求與路徑不匹配,如何讓Nginx返回444?

我想用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爲其他網絡應用程序提供服務,例如<static IP>/foo,<static IP>/bar等。這些網絡應用程序中的每一個都來自獨立的Python應用程序。但目前,當我嘗試從外部訪問端點時,出現444錯誤代碼,所以我認爲我沒有正確配置NGINX。

我把我第一次嘗試從config posted on the Guincorn site的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; 
    # } 
} 

的CONFIGS通過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" 

我想我沒有正確配置路由。任何建議,將不勝感激。

UPDATE

我現在有一些變化的工作。我註釋掉以下塊:

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以獲得正確映射到應用服務器。

+1

你只要求服務器的HTTP代碼444返回到所有請求。刪除「返回444」;在服務器部分:) – vcarel

+0

@vcarel我以爲它只會返回444,如果沒有其他路線匹配,這是我想要的。問題是它不匹配'/ABC/data'。 – JoshAdel

回答

0

這工作對我很好,返回444(掛斷連接),只有在沒有其他的服務器名稱匹配:

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