Итак, у меня есть такая настройка, как Nginx -> varnish -> apache2. Если я получаю запрос со статическим файлом, он отправляется через nginx для varnish и снова обратно в nginx, так как это намного быстрее, чем позволить серверу apache2. Моя проблема в том, что когда я
sub vcl_fetch {
set beresp.http.X-Tabulex-Client = client.ip;
чтобы узнать, какой у клиентов IP-адрес, мне говорят его 127.0.0.1 (X-Tabulex-Client 127.0.0.1). В vcl_recv у меня есть:
sub vcl_recv {
if ((!req.url ~"^/typo3temp/*" && !req.url ~"^/typo3/*") &&req.url ~"\.(jpg|css|gif|png|js)(\?.*|)$"){
set req.backend = aurum;
set client.identity = req.http.X - Forwarded - For;
} elseif(client.ip == "192.168.3.189") {
/* Traffic from the other Varnish server, serve using real backends */
set req.backend = balance;
/* Set client.identity to the X-Forwarded-For (the real IP) */
set client.identity = req.http.X - Forwarded - For;
} else{
/* Traffic coming from internet, use the other Varnish as backend */
set req.backend = iridium;
}
}
Конфигурация nginx содержит
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_intercept_errors on;
при отправке в лак первый раз и ничего при повторном получении из лака.
Я не уверен, в чем проблема. Я ожидал, что client.ip будет содержать внешний IP-адрес, чтобы я мог использовать его для acl. Любые идеи?
Значение client.ip
является 127.0.0.1
так как nginx
это клиент. Для Varnish было бы бессмысленно маскировать это значение - даже в таких ситуациях, как ваша, когда Varnish находится за прокси-сервером, вы часто хотите принимать решения на основе IP-адреса того, что действительно подключается к Varnish.
Что вы действительно хотите сделать, так это иметь nginx
поместите IP-адрес удаленного клиента в специальный заголовок (что вы уже делаете с X-Real-IP
) и используйте это для принятия решений о подключении. Мы делаем именно это в нашей среде, где Apache предоставил SSL-соединение перед varnish
, а затем мы используем этот заголовок для принятия решений о доступе.
Это не так хорошо, как использовать client.ip
(вы не можете сопоставить его, используя acl
с), но это работает. Делаем примерно так:
if (! (
req.http.X-Real-IP ~ "^10\." ||
req.http.X-Real-IP ~ "^100\.100\." ||
req.http.X-Real-IP ~ "^200\.200\."
)) {
error 403 "Forbidden";
}
Varnish не предоставляет собственный механизм для переопределения client.ip
с настраиваемым заголовком, но это возможно чтобы решить проблему в любом случае, потому что вы можете вставить произвольный код C в свою конфигурацию.
Вот это пример, который точно соответствует вашей ситуации, который включает пример замены client.ip
с другим значением, чтобы его можно было использовать в ACL Varnish.
Если в вашем запросе доступен req.http.X-Real-IP, вы можете использовать функцию ip () модуля std для преобразования строки (например, req.http.X-Real-IP) в тип IP, а затем используйте оператор ~, чтобы сравнить его со списком ACL. Это более эффективно, чем сравнение нескольких значений времени с некоторыми строками IP.
acl aclRestricted {
"1.1.1.1";
"2.2.2.2";
}
if (std.ip(req.http.X-Real-IP, "0.0.0.0") ~ aclRestricted ) {
...
}
Эталонный лак V4.1: https://varnish-cache.org/docs/4.1/reference/vmod_std.generated.html#func-ip
Если вы используете Varnish в качестве интерфейсного веб-сервера (наш бэкэнд - NGINX) за Rackspace Cloud Load Balancer, то вам необходимо использовать следующий шаблон:
if (!(
req.http.X-Forwarded-For ~ "1\.2\.3\.4" ||
req.http.X-Forwarded-For ~ "2\.3\.4\.5"
)) {
# IP-based Rules
}
Rackspace Cloud Load Balancer не передает ничего, кроме 127.0.0.1
лакировать как client.ip
. Кроме того, я попытался использовать более строгий шаблон, например ^2\.3\.4\.5$
но это не совпадет. Я думаю, что балансировщик нагрузки добавлял лишние символы в X-Forwarded-For
заголовок.