У меня Varnish работает за обратным прокси (работает на локальном хосте для разгрузки SSL). Прокси устанавливает заголовок X-Forwarded-For или добавляет себя к нему, если заголовок уже существует.
Когда я провожу проверку ACL, я, конечно, хочу проверять IP-адрес исходного клиента, а не IP-адрес моего прокси, поэтому я не могу использовать поле client.ip
. С помощью vmod std
я могу сделать следующее:
vcl 4.0;
import std;
sub vcl_recv {
if (std.ip(regsub(req.http.X-Forwarded-For, ", 127.0.0.1$", ""), "0.0.0.0") ~ my_acl) {
...do stuff...
}
}
Другими словами, я удаляю IP-адрес прокси (127.0.0.1) из заголовка, прежде чем пропустить его через std.ip
и сравнивая его с моим ACL. Это работает нормально, кроме ...
Это не удается, если заголовок X-Forwarded-For уже установлен до того, как он достигнет моего прокси. В этом случае заголовок XFF содержит три или более IP-адресов. Обрезка последнего по-прежнему оставляет более одного, и std.ip
подавляется этим, задерживая запрос на несколько секунд и, конечно, не проверяя ACL.
Мне нужно убедиться, что заголовок XFF содержит только один IP (IPv4 или IPv6) после I ' Я отключил прокси. Это должен быть IP-адрес клиента.
Например:
X-Forwarded-For: 10.10.1.1, 10.10.2.2, 2001:a031:100a:dead:beef:1234:1234:1234, 127.0.0.1
должен стать
X-Forwarded-For: 2001:a031:100a:dead:beef:1234:1234:1234, 127.0.0.1
Поскольку я не могу доверять никаким заголовкам XFF, которые приходят извне, я бы хотел отбросить все, кроме IP-адреса клиента, который мой прокси видел. Мой прокси-сервер не поддерживает изменение заголовка XFF, поэтому мне нужно сделать это в Varnish.
Первая точка в потоке Varnish, когда я могу взаимодействовать с заголовками, находится в vcl_recv ()
и при этом point Varnish уже добавил client.ip
в конец списка.
Я надеялся использовать регулярное выражение для захвата двух последних элементов (IPv4 или IPv6) в пронумерованную группу захвата ( $ 1) и просто замените заголовок группой захвата. Примерно так:
vcl 4.0;
import std;
sub vcl_recv {
set req.http.X-Forwarded-For = regsub(req.http.X-Forwarded-For, "([a-f0-9:.]+, [a-f0-9:.]+)$", "\1");
}
Третий аргумент (строка, заменяющая символы, соответствующие регулярному выражению) не работает. Результирующий заголовок точно такой же, как и раньше, даже несмотря на то, что регулярное выражение захватывает только два последних IP-адреса.
Как я могу выбросить что-либо, кроме двух последних IP-адресов из заголовка XFF?
Ваше регулярное выражение в порядке. Единственное, что я вижу, это то, что вы запрашиваете замену самой группы.
Это должно сработать, если вы добавите ^ (. *)
в начало вашего регулярного выражения и замените второй аргумент на \ 2
set req.http.X-Forwarded-For = regsub(req.http.X-Forwarded-For, "^(.*)([a-f0-9:.]+, [a-f0-9:.]+)$", "\2");
}
При этом я не думаю, что менять заголовок XFF - хорошая идея. Более стандартным должно быть добавление заголовка, а не изменение удаления информации, переданной промежуточными прокси.