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 / 问题 / 947835
Accepted
Daniel Compton
Daniel Compton
Asked: 2019-01-07 16:03:18 +0800 CST2019-01-07 16:03:18 +0800 CST 2019-01-07 16:03:18 +0800 CST

不知道中间代理 IP 地址时使用 Nginx real_ip

  • 772

Nginx 的real_ip 模块允许您$remote_addr根据特定标头字段中发送的值设置变量。它对header有特殊的理解,X-Forwarded-For能够将header中最右边的untrusted值作为连接IP地址。

我想使用 real_ip 模块来设置$remote_addr连接 IP 地址。我遇到的问题是我知道从末尾返回多少跳X-Forwarded-For,但不知道中间代理的 IP 地址。据我了解,这意味着我不能set_real_ip_from用来指定代理的 IP 地址。

我想要做的是配置 nginx 选择列表中倒数第二个地址作为$remote_addr. 似乎 real_ip 模块仅在您拥有知道代理 IP 地址的基础架构时才有效。

有没有办法用 real_ip 模块做到这一点?我已经制定了一个基于正则表达式的解决方案,但如果可能的话,我更愿意使用 real_ip 模块。

我不认为这是nginx real_ip_header 的欺骗,而 X-Forwarded-For 似乎是错误的或类似的问题。重申问题:

  • 我知道连接IP地址从末端有多少跳。
  • 我不知道连接 IP 和我的服务器之间的中间代理的可信 IP 地址,所以我不能使用set_real_ip_from.

有关细节的更多详细信息:

我在 Google Cloud HTTP 负载均衡器后面的 Google Cloud 中运行 nginx。Google Cloud使用标X-Forwarded-For头指示 Google Cloud 网络的入口点。我知道X-Forwarded-For列表中倒数第二个值是我想要的值,但我不知道最后一个值(代理)的 IP 地址是什么。即使我可以为代理枚举所有 Google Cloud 的地址空间(没有指定 GCLB 仅在 GCP 的地址空间内运行),这也会为任何其他可以在该地址空间内获取服务器的用户打开它。

nginx
  • 2 2 个回答
  • 1031 Views

2 个回答

  • Voted
  1. Best Answer
    Daniel Compton
    2021-10-26T01:59:44+08:002021-10-26T01:59:44+08:00

    我最终使用了基于正则表达式的版本。从我的 nginx 配置中:

    http {
        # Regexes are:
        # (?<connecting_ip>\d+\.\d+\.\d+\.\d+), (?<proxy_ip>\d+\.\d+\.\d+\.\d+)$ # IPv4 only
        # (?<connecting_ip_x>[0-9a-f:.]+),\s*(?<proxy_ip>[0-9a-f:.]+)$ # IPv6 and IPv4, and more robust
        #
        # The last IP address is the one from the GCP front end load balancer
        # The second to last IP address in the list is the connecting IP address (i.e. user IP address)
        # We capture both of them. X-Forwarded-For is separated by commas, hopefully whitespace as well
        # but we don't want to trust that too much.
        #
        # Note that ~ at the start of the string in Nginx marks it as a regex. It's not part
        # of the regex.
        #
        # Test cases for regex101
        # 1.1.1.1, 2.2.2.2
        # 1.1.1.1, 2.2.2.2, 3.3.3.3
        # 1.1.1.1
        # ::ffff:130.211.1.102, 2.2.2.2
        # 2001:0db8:85a3:0000:0000:8a2e:0370:7334, 2.2.2.2
        # 2001:41d0:8:e8ad::1, 2600:1901:0:2ad2::
        # 1.1.1.1,2.2.2.2,3.3.3.3
        #
        # It would be better to use the real_ip module, if that is possible
        # https://serverfault.com/q/947835/334330 might get answered for this.
    
    
        # Get the IP address of the connecting IP. If we get a direct connection from
        # GCP's health checkers, there won't be an X-Forwarded-For header. We shouldn't
        # be getting any direct connections from other sources without XFF header.
        map $http_x_forwarded_for $connecting_ip {
            # Capture the proxy IP and connecting_ip_x, then assign the connecting_ip_x
            "~(?<connecting_ip_x>[0-9a-f:.]+),\s*(?<proxy_ip>[0-9a-f:.]+)$" $connecting_ip_x;
            default               $remote_addr;
        }
      # ...
    }
    

    然后我在我的服务器定义中使用 $connecting_ip :

    server {
      # ...
      location / {
        proxy_set_header X-Real-IP $connecting_ip;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-Host "";
        proxy_redirect off;
        proxy_next_upstream error;
      }
    }
    
    • 1
  2. Arnau C.
    2020-11-20T05:00:05+08:002020-11-20T05:00:05+08:00

    这不能用它本身来完成,因为正如's descriptionngx_http_realip_module中所指定的那样,只有头字段中的最后一个地址(即您的 GFE,当设置为 时)或最后一个不受信任的地址(即客户端的地址,当设置为) 将匹配到 replace ,因此即使您从字符串操作中获得了前一个代理的地址并将其设置为它,模块也不会更改。real_ip_recursiveoffon$remote_addr$http_x_forwarded_for$set_real_ip_from$remote_addr

    因此,看起来您将不得不$remote_addr像您提到的那样使用正则表达式手动重新定义自己,或者使用另一个模块。

    话虽如此,值得注意的是负载均衡器的 GFE 地址应始终与35.191.0.0/16或130.211.0.0/22 CIDRs匹配。

    • 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