nginx динамический proxy_pass на основе url pa

В настоящее время в моем файле конфигурации nginx есть следующее определение прохода прокси:

location /pass/ {
    proxy_pass http://localhost:9999/pass/;
    proxy_redirect     off;
    proxy_set_header   Host $host;
}

Это работает, как ожидалось - запросы / pass перенаправляются в приложение, работающее на порту 9999.

Теперь я хочу сделать динамическую часть переадресации портов следующим образом:

location /pass/<input> {
    {a $port variable here that is evaluated via a script (php?)}
    proxy_pass http://localhost:$port/pass/;
    proxy_redirect     off;
    proxy_set_header   Host $host;
}

Запросы к / pass / ABCD1234 следует пересылать на порт 9898, а запросы к / pass / ABCD5678 следует пересылать на порт 9797.

Обратите внимание, что поток является динамическим - поэтому сопоставление от ABCD1234 к 9898 должно происходить с помощью какого-то сценария (возможно, PHP?), И на основе вывода сценария (порта) proxy_pass должен перенаправить запрос на этот порт.

Пожалуйста, помогите в этом отношении.

ОБНОВИТЬ :

Вместо того, чтобы получать порт proxy_pass из ввода URI, я хотел бы получить это с помощью файла cookie. Итак, вот обновленный блок кода:

location /pass/ {
    add_header X-debug-message $host always;
    add_header X-debug-message $cookie_sdmport;
    set $proxyurl http://127.0.0.1:$cookie_theport/pass/;
    add_header X-debug-message $proxyurl;
    proxy_pass $proxyurl;
    proxy_redirect     off;
    proxy_set_header   Host $host;
}

С помощью этого кода выполняется повторное перенаправление 301 в браузер. В тот момент, когда я снова переключаюсь на статический порт, он снова работает! странный! $ Proxyurl в сообщении X-debug выглядит в браузере правильно. Итак, интересно, почему proxy_pass делает 301!

ОБНОВЛЕНИЕ 2:

Наконец, пересылка работает со следующей настройкой:

    set $targetIP 127.0.0.1;
    set $targetPort $cookie_passport;
    proxy_pass http://$targetIP:$targetPort$request_uri;

Не уверен, почему решение, представленное выше, продолжает вращаться с 301 - я думаю, что nginx не любит смешивать динамические и статические части в параметре proxy_pass

Спасибо.


person oxfordian    schedule 29.08.2018    source источник


Ответы (1)


Вы можете сделать это с помощью модуля auth_request. Хотя он не построен по умолчанию, вы можете узнать, есть ли он у вас, выполнив следующее:

nginx -V 2>&1 | grep -qF -- --with-http_auth_request_module && echo ":)" || echo ":("

Если вы видите смайлик, тогда все готово.

location ~* /pass/(.*) { <- regex capture for your variable
    auth_request /auth;  <- location to process request
    auth_request_set $proxyurl http://localhost:$upstream_http_x_port/pass/; <- set $proxyurl using value returned in x-port header of your php script
    add_header x-my-variable $1; <- Pass variable from regex capture to auth location
    proxy_pass $proxyurl;
}

Затем место для обработки подзапросов аутентификации:

location /auth {
    internal; <- make location only accessible to internal requests from Nginx
    proxy_set_header x-my-variable $http_x_my_variable; <- pass variable to php
    proxy_pass_request_body off; <- No point sending body to php
    proxy_set_header Content-Length "";
    proxy_pass http://your-php-script/file.php;
}

Этот модуль на самом деле предназначен для управления доступом, поэтому, если ваш php-скрипт возвращает код ответа 200, тогда клиенту будет разрешен доступ, если он вернет 401 или 403, тогда доступ будет запрещен. Разве вас это не волнует, тогда просто установите его так, чтобы он всегда возвращал 200.

Выполните любую оценку, которая вам нужна, и ваш php вернет порт в заголовке, определенном ранее:

header('X-Port: 9999');

Теперь это устанавливает переменную для номера порта вашей директивы proxy_pass, а Nginx сделает все остальное.

person miknik    schedule 29.08.2018
comment
:) :) :) - конечно у меня auth_request_module. Приятное прикосновение. - person oxfordian; 30.08.2018
comment
Я пытаюсь сделать это немного по-другому, используя вместо этого файл cookie. большая часть потока работает нормально, однако запросы продолжают перенаправляться обратно в браузер после создания URL-адреса proxy_pass. Мой исправленный блок кода ‹br /› location /pass/ { proxy_pass http://localhost:$cookie_theport/pass/; proxy_redirect off; proxy_set_header Host $host; } - person oxfordian; 30.08.2018
comment
Используя заголовки отладки, я вижу, что URL-адрес построен правильно, но прокси-сервер каким-то образом просто перенаправляет обратно в браузер - person oxfordian; 30.08.2018
comment
Печенье определенно установлено? В обновленном вопросе вы также указываете $cookie_sdmport, это актуально? Лично я бы не советовал этого делать, риск может быть небольшим, но вы подвергаете маршрутизацию своей инфраструктуры запросов механизму, который может быть использован на стороне клиента. Используйте auth_request, сохраните IP-маршрутизацию клиента в Memcache, запустите скрипт php, что угодно, но оставьте этот процесс внутренним и не открытым для вмешательства на стороне клиента. - person miknik; 30.08.2018
comment
Конечно, я не собираюсь помещать информацию о порте или хосте в $ cookie_XXX - как только я получу базовый поток, я намерен использовать способ auth_request для транспонирования токена на фактический порт в php - person oxfordian; 31.08.2018
comment
Кстати, я наконец-то заставил его работать с набором портов, как указано в update2 выше. Кроме того, теперь будет реализован бит auth_request для завершения потока и отправки в случае возникновения каких-либо проблем. - person oxfordian; 31.08.2018