У меня есть приложение, которое не поддерживает SSL за nginx, поэтому мне нужно сделать следующее
http://example.com/f1/f2/page?next_page=http%3A//example.com/f3/new_page
должен измениться на
https://example.com/f1/f2/page?next_page=https%3A//example.com/f3/new_page
Итак, есть две вещи, которые нужно сделать: изменить схему, которую я смог, и изменить параметр URL-адреса, что мне в некоторой степени удалось, но это не работает полностью.
Я нашел страницу, которая сделала то, что я хочу сделать, но у меня она не работает: https://blog.imaginea.com/modifying-query-parameters-nginx-in-reverse-proxy-mode/
соответствующая часть моей конфигурации nginx:
server {
listen 443 ssl;
server_name example.com;
ssl on;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_certificate /path/to/bundle.crt;
ssl_certificate_key /path/to/bundle.key;
ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
ssl_prefer_server_ciphers on;
underscores_in_headers on;
rewrite_log on;
location / {
if ($args ~* (.*)(next_page=http%3A)(.*)) {
set $args $1next_page=https%3A$3;
rewrite ^(.*)$ $1;
}
proxy_pass http://127.0.0.1:80;
proxy_redirect http:// https://;
proxy_set_header Host $host;
proxy_set_header HTTPS "on";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Host $host:$server_port;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-Port 443;
}
}
nginx_error.log:
2017/09/20 13:48:13 [notice] 25115#0: *1 "(.*)(next_page=http%3A)(.*)" matches "next_page=http%3A//example.com/f3/new_page", client: X.X.X.X, server: example.com, request: "GET /f1/f2/page?next_page=http%3A//example.com/f3/new_page HTTP/1.1", host: "example.com"
2017/09/20 13:48:13 [notice] 25115#0: *1 "^(.*)$" matches "/f1/f2/page", client: X.X.X.X, server: example.com, request: "GET /f1/f2/page?next_page=http%3A//example.com/f3/new_page HTTP/1.1", host: "example.com"
2017/09/20 13:48:13 [notice] 25115#0: *1 rewritten data: "/f1/f2/page", args: "next_page=https3A//example.com/f3/new_page", client: X.X.X.X, server: example.com, request: "GET /f1/f2/page?next_page=http%3A//example.com/f3/new_page HTTP/1.1", host: "example.com"
2017/09/20 13:48:13 [notice] 25115#0: *1 "(.*)(next_page=http%3A)(.*)" does not match "next_page=https3A//example.com/f3/new_page", client: X.X.X.X, server: example.com, request: "GET /f1/f2/page?next_page=http%3A//example.com/f3/new_page HTTP/1.1", host: "example.com"
2017/09/20 13:48:13 [notice] 25115#0: *1 "(.*)(next_page=http%3A)(.*)" does not match "", client: X.X.X.X, server: example.com, request: "GET /f1/f2/cookie/++resource++baseimg/regio.ico HTTP/1.1", host: "example.com", referrer: "https://example.com/f1/f2/page?next_page=http%3A//example.com/f3/new_page"
Таким образом, схема изменяется с помощью proxy_redirect (мне нужно это сделать, поскольку иногда само приложение перенаправляет на какой-то http-URI), proxy_pass перенаправляет его на правильный сервер, и аргументы меняются, но запрос не делает. Что мне здесь не хватает?
URL-адрес, показанный в браузере:
https://example.com/f1/f1/page?next_page=http%3A//example.com/f3/new_page
кстати. Версия nginx - 1.10.1, и я не могу ее обновить на данный момент
Итак, что в итоге работало, менялось
if ($args ~* (.*)(next_page=http%3A)(.*)) {
set $args $1next_page=https%3A$3;
rewrite ^(.*)$ $1;
}
proxy_pass http://127.0.0.1:80;
proxy_redirect http:// https://;
к
if ($args ~* (.*)(next_page=http%3A)(.*)) {
set $args $1next_page=https%3A$3;
rewrite ^.*$ $1 redirect;
}
proxy_pass http://127.0.0.1:80$uri$is_args$args;
proxy_redirect http:// https://;
Одна из возможных проблем заключается в том, что nginx может не разрешать настройку переменных, которые он определяет сам. Я не знаю этого наверняка, это обоснованное предположение.
Это означает, что вы должны использовать другое имя для аргументов.
Еще лучше использовать map
возможность получить новые аргументы запроса.
в http
На уровне конфигурации добавьте следующую карту:
map $args $newargs {
default $args;
~^(.*)next_page=http:(.*)$ $1next_page=https:$2;
}
И в твоем server
блок, используйте следующие location
:
location / {
proxy_pass http://127.0.0.1:80$uri$is_args$newargs;
...
}
В любом случае, ваша установка выглядит странно, поскольку вы проксируете порт http, который, как я полагаю, работает на nginx на сервере ... Я бы просто сделал перенаправление на https
по всем запросам в http
порт.