如何让 drupal 看到 nginx 反向代理->Varnish->Apache 堆栈后面的客户端 IP?

How to make drupal see client IP behind nginx Reverse Proxy->Varnish->Apache stack?

我正在使用 nginx 作为反向代理,它处理端口 80 -> 443 重定向,然后进入与服务于 drupal (7.69) 的 Apache2.4 后端(端口 8182)对话的 varnish 缓存(端口 8181)网站。

我已将 nginx 配置为转发客户端 IP 为:

proxy_pass            http://127.0.0.1:8181;
proxy_read_timeout    90;
proxy_connect_timeout 90;
proxy_redirect        off;
proxy_set_header      X-Real-IP $remote_addr;
proxy_set_header      X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header      X-Forwarded-Proto https;
proxy_set_header      X-Forwarded-Port 443;
proxy_set_header      X-Forwarded-Host $remote_addr;
proxy_set_header      Host $host;

清漆 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;
  }
}

在 apache 中我安装了 remoteip 模块并设置了以下配置:

RemoteIPHeader X-Forwarded-For
RemoteIPTrustedProxy 127.0.0.1

在 drupal 中 settings.php 我有

$conf['reverse_proxy'] = True;
$conf['reverse_proxy_header'] = 'X-Forwarded-For';
$conf['reverse_proxy_addresses'] = array('127.0.0.1');

...但是 drupal 似乎仍然只看到和登录本地主机 (127.0.0.1) ip 而不是真正的客户端 IP。因此,表单被记录为不是来自真正的用户而是服务器本身提交的。

我想知道我的 varnish 配置是否关闭,因为我也从 nginx 代理并绕过 varnish 直接进入绕过 drupal(它是 SMF)但在相同的 apache 配置上运行的论坛;论坛正在记录从 nginx 发送的客户端 IP(使用相同的 header 更改和 apache remoteip 配置)就好了。

非常感谢您的指导/建议。

清漆

理论上,您 X-Forwarded-For 的 Varnish 配置是正确的。

实际上,您甚至不需要在 Varnish 中设置 X-Forwarded-For,因为 Varnish 会自动执行此操作。

Drupal 配置

就 Drupal 配置而言,它可能与 reverse_proxy_header 有关。我偶然发现了这段 Drupal 7 文档:https://api.drupal.org/api/drupal/includes%21bootstrap.inc/function/ip_address/7.x.

该页面上代码的关键部分如下:

$reverse_proxy_header = variable_get('reverse_proxy_header', 'HTTP_X_FORWARDED_FOR');

显然这个 ip_address() 函数可以通过配置参数了解 X-Forwarded-For header。

然而,header 格式不是官方的 HTTP 格式,而是 PHP $_SERVER 超全局存储它的方式。在这种情况下,格式为 HTTP_X_FORWARDED_FOR.

所以请尝试将 $conf['reverse_proxy_header'] = 'X-Forwarded-For'; 替换为 $conf['reverse_proxy_header'] = 'HTTP_X_FORWARDED_FOR';