Назад | Перейти на главную страницу

Varnish ACL за балансировщиком нагрузки на основе IP-адреса клиента

В следующей настройке:

Client -> LB -> Varnish

Я хотел бы настроить Varnish acls для выполнения определенных действий в зависимости от IP-адреса клиента. LB отправляет IP-адрес клиента в переменной с именем «ClientIP», которую Varnish может читать через req.httpd.ClientIP. Я пробовал это:

acl admin_net {
  "10.10.1.160"/27;
}

sub vcl_deliever {
  if (req.http.ClientIP ~ admin_net) {
  // do something ... 
  }  
}

но компиляция VCL завершается неудачно с сообщением «Ожидаемый CSTR получил 'admin_net'» (C String?). Я могу обойти это req.http.ClientIP ~ "10.10.1.*"), но я должен закомментировать строки ACL.

Есть ли другой способ заставить это работать с ACL? я смотрел на client.ip а также переменная только для чтения. В приведенной выше настройке он содержит IP-адрес LB, а не IP-адрес клиента.

Это можно сделать с помощью std.ipпри условии, что заголовок ClientIP уже установлен в vcl_recv (). Например:

vcl 4.0;
import std;

acl admin_net {
  "10.10.1.160/27";
}

sub vcl_deliver {
  if (std.ip(req.http.ClientIP,"0.0.0.0") ~ admin_net) {
  // do something ... 
  }  
}

Фактически Varnish обрабатывает client.ip как другой тип данных, поэтому вы можете использовать ACL для этого значения. Это не работает с текстовыми значениями, такими как req.http.ClientIP (или всеми параметрами req.http. *). Таким образом, регулярное выражение с этим текстовым значением кажется хорошим решением.

В качестве альтернативы вы можете использовать специальный модуль для установки client.ip. Я нашел это например: http://lassekarstensen.wordpress.com/2013/07/22/setting-client-ip-in-varnish-vcl-with-libvmod-ipcast/

Ответ от alexus на самом деле правильный ответ, если ваш Loadbalancer поддерживает протокол "PROXY", как описано здесь: https://info.varnish-software.com/blog/topic/proxy-protocol

С протоколом PROXY ваш Loadbalancer проинформирует Varnish о реальном IP-адресе клиента и соответственно установит client.ip.

Код Alexus работает:

acl e410 {
    "5.9.0.0"/16;
}

sub vcl_recv {
    ...
    if (client.ip ~ e410) {
        error 410;
    }
    ...
}

Приведенный выше пример кода сделает именно то, что вы хотите. Балансировщики, поддерживающие протокол PROXY, включают:

  • HA-прокси
  • NginX
  • Apache HTTPD
  • Балансировщик эластичной нагрузки Amazon

.. Просто назвать несколько. Вот более полный список: https://www.haproxy.com/blog/haproxy/proxy-protocol/

Вот как я использую acl в своем лаке:

acl e410 {
    "5.9.0.0"/16;
}

sub vcl_recv {
    ...
    if (client.ip ~ e410) {
        error 410;
    }
    ...
}

попробуйте заглянуть внутрь varnishlog и разместите вывод, будет легче понять, что не так ...