Обратный прокси Nginx на другом веб-сервере с перенаправлением

Компоненты системы: конфигурация nginx
(источник: snag.gy)
:

  • "сервер nginx" - А
  • "Сторонний сервер" - B
  • "Пользовательский ПК" (браузер) - C

Сервер «А» и пользовательский ПК «С» подключены к одной и той же сети «Сеть А», но сервер «А» и сторонний компьютер «В» подключены к сети «Сеть В». Цель состоит в том, чтобы получить доступ к сторонней машине «B» из пользовательского браузера «C» через сервер «A». Для этого сервер «А» должен использовать обратный прокси стороннего контента. Сервер Nginx установлен и настроен на сервере «А». Правило для обратного прокси:

location ~* ^/3rdparty/(.*)___(.*)___(.*)___(.*)$ {
    proxy_pass https://$1.$2.$3.$4?$args;
    proxy_redirect     off;
    proxy_set_header   Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

Используя правило, мы хотели бы сделать обратный прокси для URL: http:///3rdparty/‹3RD_PARTY_IP_URL> => https://‹3RD_PARTY_IP_ADDRESS> Например:

http:// 192.168.237.208/3rdparty/192___168___237___222 => https://192.168.237.222

На самом деле, мы хотим, чтобы все добавленное к URL-адресу было перенаправлено. Например:

http://192.168.237.208/3rdparty/192___168___237___222/blah/blah => https://192.168.237.222/blah/blah

Эта конфигурация работает для нас для какой-то другой настройки, но проблема в этом случае заключается в следующем: на сторонней машине «B» есть другой веб-сервер, который выполняет некоторые перенаправления:

https://192.168.237.222 => https://192.168.237.222/users/sign_in

Итак, окончательный результат, когда мы помещаем нужный URI в браузер:

http://192.168.237.208/3rdparty/192___168___237___222 

веб-сервер на «B» берет имя хоста URL-адреса и добавляет правило перенаправления (users/sign_in), в результате чего браузер запрашивает следующий URL-адрес:

https://192.168.237.208/users/sign_in

который недоступен на сервере "A" (на самом деле он есть на "B") => мы получили код ошибки http 302 (временно перемещен). Есть ли какие-то отсутствующие правила конфигурации, которые мы не применили? Или любые другие параметры заголовка http-запроса должны быть обновлены/перенаправлены?


person Aleksandar    schedule 14.04.2014    source источник


Ответы (1)


Внутреннее соединение с 192.168.237.222 прозрачно для клиента, который подключен только к 192.168.237.208.

Когда сервер B (бэкенд) отправляет обратно перенаправление /users/sign_in, оно обратно передается клиенту, который применяет его к серверу, к которому он подключен, т. е. к серверу A (шлюз/прокси), что приводит к ошибочному запросу /users/sign_in на 192.168.237.208. Вы должны иметь в виду, что перенаправления распространяются обратно и обрабатываются клиентом, а не шлюзом/прокси.

Я бы сделал что-то вроде следующего:

location ~* ^/3rdparty/([0-9]{1-3})___([0-9]{1-3})___([0-9]{1-3})___([0-9]{1-3})(/.*)?$ {
    proxy_pass https://$1.$2.$3.$4$5$is_args$args;
    proxy_redirect     off;
    proxy_set_header   Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

Подробности:

  1. Изменение вашего регулярного выражения, чтобы оно также соответствовало запросам с /blah/blah, добавленным к внутреннему IP-адресу, и их копирование и вставка в конце директивы proxy_pass с использованием другой переменной (5 долларов США)
  2. Использование $is_args встроенной переменной nginx вместо вопросительного знака (избегая в запросе, если бэкенду не нужно передавать аргументы)
  3. Попытка уточнить синтаксис регулярного выражения для соответствия номерам IP-адресов (быстро и грязно, тот, который я вам привожу, по-прежнему приводит к неправильным совпадениям, но, по крайней мере, лучше, чем подстановочные знаки)

Теперь вам нужно перенаправить клиентов с сервера B (192.168.237.222) на /3rdparty/192___168___237___222/users/sign_in, который является местом, которое можно запросить для сервера A (192.168.237.208, единственный сервер, к которому подключены клиенты) и успешно перенаправить на нужный сервер.

==========

Вы также можете полагаться на директиву nginx proxy_redirect, а не отключать ее. и сделайте так, чтобы ваш внутренний сервер выдавал ответы на перенаправление, такие как https://192.168.237.221/users/sign_in. proxy_redirect позволит вам переписать эти проксированные ответы на правильный URI против 192.168.237.208.

Для этого попробуйте что-то вроде (осторожно, я все еще использую ленивую маску IP-адреса):

    proxy_redirect     ~*^https://([0-9]{3}).([0-9]{3}).([0-9]{3}).([0-9]{3})(/.*)?$ http://192.168.237.208/3rdparty/$1___$2___$3____$4$5;

Интересно, переменные вроде $is_args и $args работают в этом контексте:

    proxy_redirect     ~*^https://([0-9]{3}).([0-9]{3}).([0-9]{3}).([0-9]{3})(/.*)?$ http://192.168.237.208/3rdparty/$1___$2___$3____$4$5$is_args$args;
person Bernard Rosset    schedule 15.04.2014
comment
В документах для proxy_redirect прямо указано, что аргумент «по умолчанию» не может использоваться, когда proxy_pass «указывается с использованием переменных», как в случае с Александром. Я полагаю, именно поэтому он был выключен из первых рук. - person Bernard Rosset; 15.04.2014