Обратный прокси-сервер nginx с изменением параметров запроса

У меня есть приложение, которое не поддерживает 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"

Таким образом, схема get изменяется с помощью 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, и я не могу обновить ее на данный момент.

2 ответа

Решение

Итак, то, что в итоге работало, менялось

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 порт.

Другие вопросы по тегам