Varnish client.ip говорит 127.0.0.1

Поэтому у меня есть настройки, такие как Nginx -> varnish -> apache2. Если я получаю запрос со статическим файлом, он отправляется через nginx для лака и снова возвращается в 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. Есть идеи?

3 ответа

Решение

Значение 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";
}

Лак не обеспечивает нативный механизм для переопределения client.ip с пользовательским заголовком, но проблему можно решить в любом случае, потому что вы можете вставить произвольный код C в свою конфигурацию.

Вот пример, который точно соответствует вашей ситуации, который включает пример замены client.ip с другим значением, чтобы его можно было использовать в Varnish ACL.

Если в вашем запросе доступно 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

Если вы используете 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 заголовок.

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