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

Регистрация IP-адреса клиента с помощью Nginx / Varnish / Apache

У меня Nginx прослушивает порт 443 в качестве терминатора SSL и проксирует незашифрованный трафик на Varnish на том же сервере. Varnish 3 обрабатывает этот трафик, и трафик поступает непосредственно на порт 80. Весь трафик передается в незашифрованном виде экземплярам Apache на других серверах в кластере. Экземпляры Apache используют mod_rpaf для замены зарегистрированного IP-адреса клиента содержимым заголовка X-Forwarded-For.

Моя проблема в том, что если трафик идет через Nginx, в то время как «правильный» IP-адрес клиента регистрируется в журналах VarnishNCSA, похоже, что Varnish (что вполне понятно) заменяет заголовок X-Forwarded-For Nginx на 127.0.0.1 нисходящего потока, и это регистрируется с помощью Apache. Есть ли простой простой способ остановить Varnish, переписывающий X-Forwarded-For, если он уже заполнен?

Абсолютно; Лаковая обработка X-Forwarded-For фактически просто определено по умолчанию vcl_recv функция.

if (req.restarts == 0) {
    if (req.http.x-forwarded-for) {
        set req.http.X-Forwarded-For =
    req.http.X-Forwarded-For + ", " + client.ip;
    } else {
        set req.http.X-Forwarded-For = client.ip;
    }
}

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

Установить vcl_recv по этим линиям:

sub vcl_recv {
    /* Your existing logic goes here */
    /* After that, we'll insert the default logic, with the X-Forwarded-For handling removed */
    /* The return (lookup); at the end ensures that the default append behavior won't have an impact */

    if (req.request != "GET" &&
      req.request != "HEAD" &&
      req.request != "PUT" &&
      req.request != "POST" &&
      req.request != "TRACE" &&
      req.request != "OPTIONS" &&
      req.request != "DELETE") {
        /* Non-RFC2616 or CONNECT which is weird. */
        return (pipe);
    }
    if (req.request != "GET" && req.request != "HEAD") {
        /* We only deal with GET and HEAD by default */
        return (pass);
    }
    if (req.http.Authorization || req.http.Cookie) {
        /* Not cacheable by default */
        return (pass);
    }
    return (lookup);
}

Редактировать:

Поскольку Varnish также обрабатывает некоторые соединения напрямую, лучшим подходом может быть выборочная установка заголовка. Вы все равно захотите включить полный vcl_recv так что по умолчанию не применяется собственный заголовок, а включается его вверху:

if (req.restarts == 0) {
    if (!req.http.x-forwarded-for) {
        set req.http.X-Forwarded-For = client.ip;
    }
}