Обратный прокси-сервер NGINX не загружает ресурсы
Я пытаюсь поставить обратный прокси-сервер перед несколькими внутренними веб-сервисами.
Nginx настроен и работает правильно для обслуживания запроса. Если бы я только служить одному location /
в моем файле conf он успешно загружает цель proxy_pass, т.е.
location / {
proxy_pass https://internal.ip:port/;
}
Просмотр по https://public_proxy_address/ загружает этот внутренний ресурс.
Однако, поскольку у меня есть несколько внутренних приложений, я хочу проксировать их все через nginx. Итак, в моем тестировании я изменил conf следующим образом:
location /app1 {
proxy_pass https://internal.ip:port/;
}
Имея это в виду, я получаю главную / стандартную внутреннюю индексную страницу приложения, но источник представления показывает, что никакие таблицы стилей ссылок, js или другие ресурсы не переписываются. Поэтому все содержимое страницы не загружается. В Apache я бы наверное написал proxyhtmlurlmap ^/resource/ /app1/resource R
, Я не могу найти способ добиться этого в nginx, хотя.
Я также попробовал это, но безрезультатно:
location /app1 {
rewrite /resource(.*?) /app1/resource$1 break;
proxy_pass https://internal.ip:port/;
}
Как мне получить nginx для правильного добавления целевого местоположения (app1) к запрошенным URL ресурсов, чтобы они загружались?
5 ответов
Поскольку у меня недостаточно кредитов, я не могу комментировать записи, поэтому мой ответ представлен в виде отдельной записи.
Я не знаю, почему ФП не согласен, но я думаю, что Мартин Фьордвал правильно определяет проблему и предлагает правильные вещи. Я бы предложил немного изменить его фрагмент, как показано ниже;
location /app1/ {
proxy_set_header Host $http_host/app1;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_redirect off;
add_header Pragma "no-cache";
add_header Cache-Control "no-cache";
proxy_pass http://internal.ip:port/;
sub_filter 'action="/' 'action="/app1/';
sub_filter 'href="/' 'href="/app1/';
sub_filter 'src="/' 'src="/app1/';
sub_filter_once off;
}
Итак, если вы уверены, что все ваши относительные URL-адреса, начинающиеся с "/", нуждаются в перенаправлении, приведенное выше добавит к ним "/app1/" и перехватит их в блоке "location /app1/" при обращении к ним. Затем вы можете просмотреть исходный код страницы и подтвердить, что происходит перезапись.
Вам также, вероятно, понадобится весь или хотя бы часть шабанга proxy_set_header, особенно бит proxy_set_header Host $ http_host / app1.
В итоге я просто использовал прокси на основе поддоменов. Основы выглядят так:
server {
listen 443 ssl;
ssl on;
ssl_cert <cert>;
ssl_key <key>;
server_name appname1.public.com;
location / {
proxy_pass https://internalapp1.ip:port
}
}
server {
listen 443 ssl;
ssl on;
ssl_cert <cert>;
ssl_key <key>;
server_name appname2.public.com;
location / {
proxy_pass https://internalapp2.ip:port
}
}
Это устраняет необходимость в прямой переписке URL или ресурсов.
Если я правильно понимаю вашу проблему, похоже, проблема в том, что ваше приложение считает, что оно находится в корневом каталоге /
в то время как это на самом деле размещено в /app1
и просто не говорят об этом. Nginx обычно не изменяет реакцию ваших бэкендов, что вы ожидаете, однако это возможно.
Сначала вы хотите проверить, есть ли в вашем приложении параметр конфигурации, в котором вы можете определить корневой URI. Если есть настройка, то это, безусловно, самое простое решение.
Если вы не можете ничего найти, вы можете использовать модуль замещения, чтобы заменить URL в HTML. Обратите внимание, что для того, чтобы это работало, вам необходимо отключить кодировку GZIP на сервере, чтобы nginx мог видеть несжатый HTML.
Пример того, как может выглядеть ваш подфильтр
location /app1 {
sub_filter '<a href="/resource/' '<a href="/app1/resource/';
sub_filter_once off;
proxy_pass https://internal.ip:port/;
}
Вы указали один абсолютный URL-адрес в своем местоположении, а не URL-адрес страницы и всех ресурсов, которые использует страница. Вам нужно указать регулярное выражение, которое начинается с этого URL. Нечто подобное может работать (я не проверял)
location ~ /app1(/.*) {
proxy_pass https://internal.ip:port/;
}
У меня такая же проблема; страница индекса загружалась, но все ресурсы получили 404.
Я заметил, что в месте у меня было: try_files $uri $uri/ =404;
Это возвращает 404 для всех ресурсов. Просто удали это.
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
# try_files $uri $uri/ =404; <---- Comment out this line.
# Uncomment to enable naxsi on this location
# include /etc/nginx/naxsi.rules
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}