nginx обратный прокси работает только, когда location установлен на корень.

Вопрос или проблема

Я настраиваю обратный прокси перед сервисом, используя Podman на Fedora.
Проблема возникает, когда я устанавливаю location на /, тогда все работает нормально, но когда я добавляю подкаталог, например, /read/, возникают различные ошибки.
Вот конфигурация nginx:

user  nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    server {
        listen 80 default_server;
        listen [::]:80 default_server;
        error_log  /var/log/nginx/err.log notice;
        access_log  /var/log/nginx/acc.log;

location /read/ {
            proxy_pass http://127.0.0.1:8000/read/;
            proxy_set_header  X-Forwarded-Host 127.0.0.1:8080;
            proxy_set_header  X-Real-IP         $remote_addr;
            proxy_set_header  Host              $host;
            proxy_set_header  X-Forwarded-For   $proxy_add_x_forwarded_for;
            proxy_set_header  X-Forwarded-Proto $scheme;
        }
    }
}

и ответ при попытке доступа к сервису:

curl --noproxy "127.0.0.1" -v http://127.0.0.1:8080/read/
*   Trying 127.0.0.1:8080...
* Connected to 127.0.0.1 (127.0.0.1) port 8080
> GET /read/ HTTP/1.1
> Host: 127.0.0.1:8080
> User-Agent: curl/8.6.0
> Accept: */*
>
< HTTP/1.1 303 See Other
< Server: nginx/1.27.3
< Date: Fri, 24 Jan 2025 21:57:28 GMT
< Content-Length: 0
< Connection: keep-alive
< Cache-Control: private
< Content-Security-Policy: base-uri 'none'; default-src 'self'; font-src 'self'; form-action 'self'; frame-ancestors 'none'; img-src 'self' data:; media-src 'self' data:; object-src 'none'; report-uri http://127.0.0.1:8080/logger/csp-report; script-src 'report-sample' 'nonce-89583bebc2e348ba85f0ef7463e3162c' 'unsafe-inline'; style-src 'report-sample' 'nonce-89583bebc2e348ba85f0ef7463e3162c' 'unsafe-inline'
< Location: http://127.0.0.1:8080/login?r=%2Fread%2F
< Permissions-Policy: interest-cohort=()
< Referrer-Policy: same-origin, strict-origin
< Set-Cookie: sxid=MTczNzc1NTg0OHwwajkzbFhpXzVtc2ZQVnh6bWNJdEllbWlrcm5pVl9Zb1pvZkl1TjN1U1MwZDVNN2ZOQ1F0WHRDT214dTNsY1RPRUl2RHg3UmRlSlB2SVFSWm1UdGQwcm9zSEF1bkFGdVB4dlJpU2p0M1dnPT18HfAf2yi5rBri3VK6LK5cOogYr1mqjogyBFa4Z8BM-2I=; Path=/; Expires=Thu, 01 Jan 1970 00:00:01 GMT; Max-Age=0; HttpOnly; SameSite=Lax
< Vary: Accept-Encoding
< X-Content-Type-Options: nosniff
< X-Frame-Options: DENY
< X-Robots-Tag: noindex, nofollow, noarchive
< X-Xss-Protection: 1; mode=block
<
* Connection #0 to host 127.0.0.1 left intact

Ввод http://127.0.0.1:8080/read/ в веб-браузере

Ответ или решение

Ваша проблема с обратным проксированием в Nginx в основном связана с настройкой конфигурации, когда вы добавляете подкаталог, например, /read/. В случае изменения пути указывается, что конфигурация работает некорректно, и вы сталкиваетесь с ошибками. Давайте подробно разберем вашу ситуацию, используя метод TEA (Теория, Пример, Применение), чтобы выявить возможные причины и предложить решения.

Теория

Настройка обратного прокси в Nginx предполагает, что сервер будет пересылать запросы к другому серверу (в вашем случае— Podman). В стандартной конфигурации запрошенный путь должен соответствовать тому, что ожидает приложение— это касается и корневого каталога /. Однако, когда вы пытаетесь добавить подкаталог, например, /read/, возникают разные ситуации обработки контекста URL, что может вызвать перенаправления, ожидаемые приложением на конечном сервере.

Основные причины проблемы могут включать:

  1. Перенаправления и относительные пути: Ваше приложение может ожидать, что все пути начинаются с корневого /, и не учитывает, что запросы будут приходить с подкаталога.
  2. Конфигурация проксирования в Nginx: Несоответствие правил проксирования, где внутренние URL-адреса приложения остаются относительными и не учитывают внешний подкаталог.
  3. Куки и директории: В случае, когда куки завязаны на пути /, добавление подкаталога может приводить к потере контекста сессии.

Пример

Давайте рассмотрим конкретный пример конфигурации и ответа, который вы привели.

При запросе через curl на URL http://127.0.0.1:8080/read/ вы получаете ответ 303 (See Other), вместе с заголовком Location, который указывает на перенаправление на страницу /login. Это говорит о двух моментах:

  • Приложение, возможно, требует аутентификации или не находит ресурс в ожидаемом месте.
  • Путь /read/ не признается или обрабатывается приложением как отдельный ресурс, не связанный с основным контентом.

Применение

Для решения этой проблемы можно предпринять ряд шагов:

  1. Изменение пути в proxy_pass: Попробуйте изменить строку proxy_pass для удаления конечного слэша /read/, например:

    location /read/ {
        proxy_pass http://127.0.0.1:8000;
        ...
    }

    Это может помочь в согласовании относительных путей между Nginx и приложением.

  2. Переписывание путей: Используйте директиву rewrite в Nginx, чтобы переписать пути и привести их к форме, понятной для вашего бэкенда:

    location /read/ {
        rewrite ^/read/(.*) /$1 break;
        proxy_pass http://127.0.0.1:8000;
        ...
    }
  3. Проверка версий приложений и совместимости: Убедитесь, что ваше приложение и Nginx поддерживают необходимые технологии и возможности для работы с подкаталогами.

  4. Аутентификация и сессии: Проверьте обработку сессий и куки в вашем приложении; возможно, потребуется настройка для поддержки проксирования через подкаталоги.

  5. Тестирование и логирование: Рассмотрите возможность детального ведения логов и отладочного вывода как на уровне Nginx, так и на уровне приложения для более глубокого анализа проблемы.

В конечном итоге, решение зависит от специфики вашего приложения и его работы с относительными путями. Удачной настройки!

Оцените материал
Добавить комментарий

Капча загружается...