从私有 NIC 访问时,Rails 显示 IP 为 127.0.0.1,但 Nginx 显示正确的 IP。公共 IP 可以正常转发

Posted

技术标签:

【中文标题】从私有 NIC 访问时,Rails 显示 IP 为 127.0.0.1,但 Nginx 显示正确的 IP。公共 IP 可以正常转发【英文标题】:Rails shows IP as 127.0.0.1 when accessed from private NIC, but Nginx shows the correct IP. Public IP gets forwarded fine 【发布时间】:2013-11-21 04:24:14 【问题描述】:

我们正在 Unicorn + nginx 上运行 Rails 应用程序。服务器有两个我们使用的 NIC。 eth0 处理公共互联网的请求,eth2 处理来自我们私有网络的请求。

当通过eth0 发出请求时,nginx 日志会显示公共 IP,Rails 日志也会显示此 IP。但是,当一个请求通过eth2 发出时,nginx 日志会正确显示私有 IP(例如 192.168.5.134),但 Rails 日志会显示127.0.0.1

因此,eth0 上的公共请求似乎正确设置了 X-Forwarded-For 标头,但eth2 上的请求不会发生这种情况。

我们的 nginx 配置非常基本:

upstream example.com 
  server unix://var/www/example.com/shared/sockets/unicorn.socket fail_timeout=0;


...

server 
  listen 443 ssl;
  ...

  location @example.com  
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Real_IP $remote_Addr;
    proxy_set_header X-Forwarded_For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_redirect off;

    if ($host ~* "^(.+)\.example.com$") 
      set $subdomain $1;
    

    proxy_pass http://example.com;
  

有什么想法吗?

【问题讨论】:

【参考方案1】:

问题在于 Rails 认为任何 192.168.x.x 地址都是私有地址,因此将它们从 X-Forwarded_For 标头中删除。

# IP addresses that are "trusted proxies" that can be stripped from
# the comma-delimited list in the X-Forwarded-For header. See also:
# http://en.wikipedia.org/wiki/Private_network#Private_IPv4_address_spaces
TRUSTED_PROXIES = %r
  ^127\.0\.0\.1$                | # localhost
  ^(10                          | # private IP 10.x.x.x
    172\.(1[6-9]|2[0-9]|3[0-1]) | # private IP in the range 172.16.0.0 .. 172.31.255.255
    192\.168                      # private IP 192.168.x.x
   )\.
x

查看相关的 Rails 源代码 here 和 here。

一种解决方案是将其添加到您的config/application.rb

config.action_dispatch.trusted_proxies = /^127\.0\.0\.1$/ # localhost

这样,您本地网络上的 IP 将不会被“127.0.0.1”替换。

【讨论】:

以上是关于从私有 NIC 访问时,Rails 显示 IP 为 127.0.0.1,但 Nginx 显示正确的 IP。公共 IP 可以正常转发的主要内容,如果未能解决你的问题,请参考以下文章

公网IP和私有IP

TCP/ip--基础知识

从已知的MAC地址获取网络接口卡(NIC)(并获取该NIC上的IP地址)

如何在Azure VM上配置IIS站点以接受来自其他外部IP地址的请求?

NAT原理

如何从 Java 枚举所有启用的 NIC 卡的 IP 地址?