2016-09-09 8 views
0

Короткая версия:Как получить Nginx для возврата 444, если запрос не соответствует пути?

Я хочу использовать NGINX в качестве обратного прокси-сервера, так что клиент доступа к URL общественного облицовочного получает служил данным API от внутреннего сервера Gunicorn сидит за прокси:

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

Я не получаю корректное отображение местоположения.

Длинная версия:

Я настраиваю NGINX в первый раз и пытаюсь использовать его в качестве обратного прокси-сервера для отдыха апи обслуживаемой Gunicorn. Api обслуживается в 127.0.0.1:8001, и я могу получить к нему доступ с сервера и получить соответствующие ответы, так что часть, на мой взгляд, работает правильно. Он постоянно работает с Supervisord.

Я хотел бы получить доступ к одной из конечных точек API извне на <static IP>/ABC/data. На сервере Gunicorn эта конечная точка доступна по адресу localhost:8001/data. В конце концов я хотел бы обслуживать другие веб-приложения через NGINX с такими корнями, как <static IP>/foo, <static IP>/bar и т. Д. Каждое из этих веб-приложений было бы из независимого приложения Python. Но в настоящее время, когда я пытаюсь получить доступ к конечной точке извне, я получаю код ошибки 444, поэтому я думаю, что я неправильно настраиваю NGINX.

Я собрал свою первую попытку конфигурации NGINX от config posted on the Guincorn site. Вместо одной конфигурации я разделил ее на глобальную конфигурацию и на конкретный сайт. Моя глобальная конфигурация на 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" 

Я думаю, что я как-то неправильно настроил маршруты. Мы ценим любые предложения.

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; 
}