Назва містить слово redirect, тому його вставляють у блок location, коли backend за VPN недосяжний. Нічого не змінюється, і очевидний висновок — директива зламана або потребує іншого синтаксису. Насправді сталося простіше й менш приємно: proxy_redirect працює з відповіддю, яка вже повернулася, а в цьому розгортанні жоден запит туди не дійшов.

Дві директиви, два моменти в одному запиті

HTTP-запит через зворотний проксі по черзі проходить кілька рішень, і дві директиви стоять на протилежних кінцях цієї послідовності. Одна вибирає, куди піде запит. Інша редагує певні заголовки у відповіді, яка повертається.

DirectiveWhen it actsWhat it can change
proxy_passBefore any bytes leave the proxyWhich upstream receives the request
proxy_redirectAfter the upstream respondsMatching Location and Refresh text

Цей порядок і є вся відповідь. Якщо другий рядок ніколи не виконується, бо перший не спрацював, друга директива не налаштована неправильно — вона просто недосяжна. Скільки не переписуй другий рядок, відповідь, яку він мав редагувати, не з'явиться. Діагностуйте від першого рядка назовні, і заплутана поведінка зводиться до відсутнього маршруту або відхиленого з'єднання.

Вибір upstream належить proxy_pass

Припустімо, NGINX працює на публічному вхідному хості й через свій VPN досягає застосунку за адресою 10.40.0.20:8080. Фрагмент, який вибирає цей застосунок, виглядає так, усередині наявного блоку server:

location / {
    proxy_pass http://10.40.0.20:8080;
}

Використовуйте реальну схему, адресу й порт і ставтеся до цього як до фрагмента, а не як до розгортання. Вхідний хост також має тримати маршрут VPN, дозволений шлях пересилання й робочий зворотний трафік до цієї служби, бо проксі, який на папері досягає адреси, все одно потребує згоди ядра.

Довідка модуля proxy тримає вибір upstream окремо від переписування заголовків відповіді й зауважує, що значення proxy_pass з URI змінює те, як замінюється відповідний префікс location. Додавати або прибирати компоненти шляху, не перевіряючи URL, який очікує застосунок, — надійний спосіб отримати 404, що виглядає як збій маршрутизації.

proxy_redirect виправляє відповіді, що розкривають приватну адресу

Щойно трафік пішов, backend може відповісти заголовком Location, у якому вказано його приватну адресу. Браузер, що йде за цим заголовком, залишає публічну точку входу й намагається досягти того, що не може розв'язати. Навмисно налаштоване переписування відповіді зіставляє приватний URL з публічним:

proxy_redirect http://10.40.0.20:8080/ https://app.example.com/;

Замініть обидві сторони реальними значеннями. Зрозумійте й вузький обсяг: відповідний текст заголовків Location і Refresh переписується, а URL, вбудовані в HTML, JavaScript або завантажені файли, ні.

Якщо застосунок будує абсолютні посилання всюди, тривале рішення — його власна конфігурація зовнішнього URL, а не зростаючий список правил переписування на проксі. Додавання правил, доки вивід не виглядатиме правильно, дає конфігурацію, яка падає на першій сторінці, яку ніхто не перевірив. Одне правильне налаштування застосунку замінює весь набір.

Чого переписування заголовка не може виправити

Кілька сусідніх проблем виглядають як проблеми перенаправлення, але ними не є. Заголовок Host, що надсилається в upstream, може мати відповідати віртуальному хосту backend. TLS upstream може вимагати конкретного імені сервера й перевірки сертифіката, і переписування заголовка відповіді не допомагає ні тому, ні тому.

Обсяг cookie та атрибути домену належать застосунку та його конфігурації. Проксі може цілий день викидати або переписувати заголовки й усе одно створити сесію, яка падає на другому запиті, бо cookie видано для хоста, який браузер ніколи не відвідував. Цей збій виглядає періодичним, тому він так довго живе в черзі заявок. Читання домену cookie зазвичай завершує розслідування за хвилину.

Тримайте автентифікацію й вибір backend обмеженими передбаченим застосунком. Публічний зворотний проксі має відкривати один застосунок через VPN сервера, а не ставати універсальним шлюзом до кожної приватної адреси, до якої цей хост може дістатися. Один загальний location, який пересилає все, що попросить виклик, перетворює один відкритий сервіс на карту вашої приватної мережі. Назвіть upstream явно й тримайте його там.

Перевіряйте в тому порядку, у якому йде запит

Підтвердьте три речі по черзі: NGINX вибрав потрібний location, завершив запит до backend, а браузер пішов за будь-яким наступним перенаправленням і завантажив підресурси. Кожен крок має власні рядки логу, і читання їх по порядку перетворює розпливчасту 502 на конкретну знахідку.

Потрібна вам відмінність — між невдалим з'єднанням з upstream і браузером, надісланим на недосяжне приватне ім'я. Перше з'являється в логу помилок проксі; друге виглядає як запит, що ніколи не надходить, а браузер скаржиться на хост, який не може розв'язати. Дві різні проблеми, два різні файли, і лише одна з них узагалі стосується proxy_redirect.

Схожі статті