AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / server / 问题 / 1090749
Accepted
Aquarion
Aquarion
Asked: 2022-01-22 09:00:50 +0800 CST2022-01-22 09:00:50 +0800 CST 2022-01-22 09:00:50 +0800 CST

代理时如何让 nginx 不覆盖 x-forwarded-for?

  • 772

我在负载均衡器后面有一个 nginx 服务器,nginx 服务器将请求传递给各种服务,但在本例中是一个运行 apache 的 docker 容器。负载均衡器正确设置了 X-Forwarded-For,但是当它到达 docker 容器时,X-Forwarded-For 已设置为 LB IP。

我在 nginx 配置中有这个:

/etc/nginx/conf.d/real_ip.conf
set_real_ip_from {{LB IP}};
real_ip_header X-Real-IP;
real_ip_recursive on;

这是虚拟主机:

server {
    listen 443 ssl;
    listen [::]:443 ssl;
    server_name *.domain domain;
    include /etc/nginx/snippets/domain_ssl.conf;

  add_header X-Nginx-Debug "hi";

  proxy_pass_request_headers on;

  location    / {
    proxy_pass_request_headers on;
    proxy_pass  http://container-php;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $http_host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Remote-Addr $remote_addr;
    proxy_set_header X-Real-IP $http_x_real_ip;
    proxy_set_header X-Header-Test "Hello World - $http_x_forwarded_for";
    proxy_set_header X-Forwarded-Proto $scheme;
  }
}

但我从容器中得到的是:

array(19) {
  ["Connection"]=>
  string(7) "upgrade"
  ["Host"]=>
  string(19) "domain"
  ["X-Forwarded-For"]=>
  string(12) "{{LB IP}}"
  ["X-Header-Test"]=>
  string(13) "Hello World -"
  ["X-Forwarded-Proto"]=>
  string(5) "https"
  ["cache-control"]=>
  string(9) "max-age=0"
  ["sec-ch-ua"]=>
  string(64) "" Not;A Brand";v="99", "Google Chrome";v="97", "Chromium";v="97""
  ["sec-ch-ua-mobile"]=>
  string(2) "?0"
  ["sec-ch-ua-platform"]=>
  string(9) ""Windows""
  ["upgrade-insecure-requests"]=>
  string(1) "1"
  ["user-agent"]=>
  string(114) "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36"
  ["accept"]=>
  string(135) "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"
  ["sec-fetch-site"]=>
  string(4) "none"
  ["sec-fetch-mode"]=>
  string(8) "navigate"
  ["sec-fetch-user"]=>
  string(2) "?1"
  ["sec-fetch-dest"]=>
  string(8) "document"
  ["accept-encoding"]=>
  string(17) "gzip, deflate, br"
  ["accept-language"]=>
  string(26) "en-GB,en-US;q=0.9,en;q=0.8"
}

值得注意的是 X-Real-IP、X-Fowarded-For 似乎没有设置,remote_addr 也没有。直接从 nginx 提供的文件已正确设置 x-forwarded-for,因此 LB 正在发送正确的标头。

我错过了一步吗?

nginx reverse-proxy nginx-reverse-proxy
  • 4 4 个回答
  • 4742 Views

4 个回答

  • Voted
  1. boleqs
    2022-02-02T01:40:33+08:002022-02-02T01:40:33+08:00

    我认为问题出在您的真实IP配置中。

    set_real_ip_from {{LB IP}};

    real_ip_header X-Real-IP;

    real_ip_recursive on;

    当 real_ip_header 应该(在你的情况下)设置为 X-Forwarded-For。我假设您的 LB 中的 X-Forwarded-For 标头如下所示:

    X-Forwarded-For: {{Original client ip}}, {{LB ip}}

    因此,当您将 real_ip_header(用于替换客户端 ip 的标头)设置为 X-Forwarded-For 时,它将匹配原始客户端 ip。原始客户端现在应该位于变量 $realip_remote_addr 下,您可以将其寻址到 proxy_set_header X-Forwarded-For :

    proxy_set_header X-Forwarded-For $realip_remote_addr

    如果我有任何帮助,请告诉我!

    • 2
  2. A. Darwin
    2022-01-22T09:12:58+08:002022-01-22T09:12:58+08:00

    这是覆盖 X-Forwarded-For 标头的语句:

    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

    假设您想在该标头中保留原始客户端 IP,您应该编写:

    proxy_set_header X-Forwarded-For $remote_addr;

    • 1
  3. wadge
    2022-01-27T10:16:33+08:002022-01-27T10:16:33+08:00

    根据您的描述,您的问题与 nginx 没有直接关系,而是与 apache 直接相关。

    根据您的配置,您的流量可能类似于:

    outside -> nginx -> apache -> php (running as fpm)

    或者

    outside -> nginx -> apache + php module

    您应该查看 apache 配置以确保在将请求传递给 PHP 时apache 没有丢弃x-forwarded-forand标头。x-real-ip

    如果您的流量与第一个示例一致,则您有 apache 将请求也代理到 php,如果 nginx 和 apache 不“同步”,这可能会导致更多问题。

    如果您仅使用 nginx 处理 php 代理,则只需将以下内容添加到您的 phplocation配置中:

    location ~ \.php$ {
            #...other rules
            fastcgi_param REMOTE_ADDR $http_x_real_ip;
            #...other rules
    }
    

    这样,PHPREMOTE_ADDR将被正确设置。


    关于你的 nginx 配置,如果你的 nginx{{LB IP}}是静态的,你可以直接在配置中设置它。

    /etc/nginx/conf.d/real_ip.conf
    set_real_ip_from {{LB IP}};
    real_ip_recursive on;
    

    您不需要real_ip_header X-Real-IP;在您的配置文件中。这将覆盖set_real_ip_from指令。

    请记住,您需要在 nginx 中启用 real_ip 模块才能使其正常工作。

    • 0
  4. Best Answer
    Aquarion
    2022-02-02T07:27:38+08:002022-02-02T07:27:38+08:00

    我最终以一种可行的方式解决了这个问题,但实际上并没有解决根本问题。据我所知,上游 LB 将“X-Forwarded-For”设置为远程地址,而 Nginx 的魔法尝试为反向代理正确设置总是出错并将其设置为 LB 地址或空细绳。

    相反,我为 LB->Server 位从 HTTP 切换到 PROXY 协议,在 /etc/nginx/proxy_params 中设置以下内容:

    proxy_set_header X-Real-IP       $proxy_protocol_addr;
    proxy_set_header X-Forwarded-For $proxy_protocol_addr;
    

    这在conf.d中:

     /etc/nginx/conf.d/real_ip.conf
    set_real_ip_from {{ LB_IP }};
    real_ip_header proxy_protocol;
    

    改编自:

    https://www.x33u.org/docs/kubernetes-stuff/hetzner-loadbalancer-setup/

    现在一切正常。

    • 0

相关问题

  • Gzip 与反向代理缓存

  • nginx 作为代理的行为

  • Nginx 学习资源 [关闭]

  • 提供 70,000 个静态文件 (jpg) 的最佳方式?

  • 在 Apache、LightTPD 和 Nginx Web 服务器上提供 PHP 5.x 应用程序的现状?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    新安装后 postgres 的默认超级用户用户名/密码是什么?

    • 5 个回答
  • Marko Smith

    SFTP 使用什么端口?

    • 6 个回答
  • Marko Smith

    命令行列出 Windows Active Directory 组中的用户?

    • 9 个回答
  • Marko Smith

    什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同?

    • 3 个回答
  • Marko Smith

    如何确定bash变量是否为空?

    • 15 个回答
  • Martin Hope
    Tom Feiner 如何按大小对 du -h 输出进行排序 2009-02-26 05:42:42 +0800 CST
  • Martin Hope
    Noah Goodrich 什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同? 2009-05-19 18:24:42 +0800 CST
  • Martin Hope
    Brent 如何确定bash变量是否为空? 2009-05-13 09:54:48 +0800 CST
  • Martin Hope
    cletus 您如何找到在 Windows 中打开文件的进程? 2009-05-01 16:47:16 +0800 CST

热门标签

linux nginx windows networking ubuntu domain-name-system amazon-web-services active-directory apache-2.4 ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve