Вопрос или проблема
Я настраиваю обратный прокси перед сервисом, используя 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
Ответ или решение
Ваша проблема с обратным проксированием в Nginx в основном связана с настройкой конфигурации, когда вы добавляете подкаталог, например, /read/
. В случае изменения пути указывается, что конфигурация работает некорректно, и вы сталкиваетесь с ошибками. Давайте подробно разберем вашу ситуацию, используя метод TEA (Теория, Пример, Применение), чтобы выявить возможные причины и предложить решения.
Теория
Настройка обратного прокси в Nginx предполагает, что сервер будет пересылать запросы к другому серверу (в вашем случае— Podman). В стандартной конфигурации запрошенный путь должен соответствовать тому, что ожидает приложение— это касается и корневого каталога /
. Однако, когда вы пытаетесь добавить подкаталог, например, /read/
, возникают разные ситуации обработки контекста URL, что может вызвать перенаправления, ожидаемые приложением на конечном сервере.
Основные причины проблемы могут включать:
- Перенаправления и относительные пути: Ваше приложение может ожидать, что все пути начинаются с корневого
/
, и не учитывает, что запросы будут приходить с подкаталога. - Конфигурация проксирования в Nginx: Несоответствие правил проксирования, где внутренние URL-адреса приложения остаются относительными и не учитывают внешний подкаталог.
- Куки и директории: В случае, когда куки завязаны на пути
/
, добавление подкаталога может приводить к потере контекста сессии.
Пример
Давайте рассмотрим конкретный пример конфигурации и ответа, который вы привели.
При запросе через curl
на URL http://127.0.0.1:8080/read/
вы получаете ответ 303 (See Other), вместе с заголовком Location
, который указывает на перенаправление на страницу /login
. Это говорит о двух моментах:
- Приложение, возможно, требует аутентификации или не находит ресурс в ожидаемом месте.
- Путь
/read/
не признается или обрабатывается приложением как отдельный ресурс, не связанный с основным контентом.
Применение
Для решения этой проблемы можно предпринять ряд шагов:
-
Изменение пути в
proxy_pass
: Попробуйте изменить строкуproxy_pass
для удаления конечного слэша/read/
, например:location /read/ { proxy_pass http://127.0.0.1:8000; ... }
Это может помочь в согласовании относительных путей между Nginx и приложением.
-
Переписывание путей: Используйте директиву
rewrite
в Nginx, чтобы переписать пути и привести их к форме, понятной для вашего бэкенда:location /read/ { rewrite ^/read/(.*) /$1 break; proxy_pass http://127.0.0.1:8000; ... }
-
Проверка версий приложений и совместимости: Убедитесь, что ваше приложение и Nginx поддерживают необходимые технологии и возможности для работы с подкаталогами.
-
Аутентификация и сессии: Проверьте обработку сессий и куки в вашем приложении; возможно, потребуется настройка для поддержки проксирования через подкаталоги.
-
Тестирование и логирование: Рассмотрите возможность детального ведения логов и отладочного вывода как на уровне Nginx, так и на уровне приложения для более глубокого анализа проблемы.
В конечном итоге, решение зависит от специфики вашего приложения и его работы с относительными путями. Удачной настройки!