Здесь в конференции неоднократно поднималась проблема перескока проксирования за пределы location, в которой оно производится:
http://forum.nginx.org/read.php?21,240642,240642#msg-240642
http://forum.nginx.org/read.php?11,239231,239231#msg-239231
http://forum.nginx.org/read.php?21,242647,242671#msg-242671
Просьба к светочам нашей жизни внести ясность по данному поводу.
Возможно, можно что-то придумать с корректировкой заголовков (через subs_filter?) или с реврайтами.
Пожалуйста, помогите разобраться!
Предложение с перечислением поддиректорий - "location ~ ^(/supervision|/nagios)" - никак не выход для подобных ситуаций. Кроме того, это выдаёт ошибку:
nginx: [emerg] "proxy_pass" cannot have URI part in location given by regular expression, or inside named location, or inside "if" statement, or inside "limit_except" block in /usr/local/etc/nginx/sites/test.conf:50
В моём случае используется nginx-1.4.1,1
Общие установки проксирования nginx (имеющие отношение к делу):
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
Конфигурация тестовой location:
------------------
1-й вариант.
------------------
location /online {
rewrite ^/online/?(.*)?$ /$1 break;
rewrite_log on;
proxy_pass https://10.22.33.44:83;
proxy_redirect https://10.22.33.44:83 /online;
}
------------------
2-й вариант. (По одному необычному интернетовскому примеру.)
------------------
location /online {
rewrite ^/online/?(.*)?$ /__online__/$1 last;
rewrite_log on;
}
location /__online__ {
internal;
proxy_pass https://10.22.33.44:83;
break;
}
------------------
Оба варианта одинаковым образом не срабатывают.
Очень странно, что proxy_redirect (в первом варианте) почему-то не отрабатывает.
Это видно по логу:
10.xxx - - [03/Dec/2013:13:23:32 +0400] "GET /online HTTP/1.1" 302 137 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)"
Здесь прокси даёт редирект на свою локальную директорию: /logon
Пользовательский браузер получает этот редирект именно как /logon, а не как /online/logon
10.xxx - - [03/Dec/2013:13:23:32 +0400] "GET /logon HTTP/1.1" 301 236 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)"
В результате происходит этот самый перескок за пределы проксируемой location.
При этом "curl -v -k" выдаёт:
> GET /online HTTP/1.1
> User-Agent: curl/7.31.0
> Host: 10.xxx
> Accept: */*
>
< HTTP/1.1 302 Found
< Server: nginx
< Date: Tue, 03 Dec 2013 09:41:52 GMT
< Content-Type: text/html; charset=utf-8
< Content-Length: 137
< Connection: keep-alive
< Keep-Alive: timeout=10
< Cache-Control: private
< Location: /logon
<
<html><head><title>Object moved</title></head><body>
<h2>Object moved to <a href="/logon?ReturnUrl=%2f">here</a>.</h2>
</body></html>
Попутный вопрос. Я прописал реврайт, чтобы из location на проксируемый бакэнд уходили запросы не "GET /online", а "GET /".
rewrite ^/online/(.*) /$1 break;
Однако есть альтеренативный вариант реврайта:
rewrite ^/online/?(.*)?$ /$1 break;
По логам, они отрабатывают одинаково правильно:
2013/12/03 12:40:15 [notice] 71288#0: *12543662 "^/online/?(.*)?$" matches "/online", client: 10.xxx, server: testserver.ru, request: "GET /online HTTP/1.1", host: "testserver.ru"
2013/12/03 12:40:15 [notice] 71288#0: *12543662 rewritten data: "/", args: "", client: 10.xxx, server: testserver.ru, request: "GET /online HTTP/1.1", host: "testserver.ru"
Но из-за перескока последующих запросов за пределы проксируемой location не видно правильно ли всё работает в конечном счёте.
Какой вариант будет лучше?