【问题标题】:Getting client ip address in flask在烧瓶中获取客户端IP地址
【发布时间】:2013-01-16 12:02:37
【问题描述】:

我试图在以下场景中获取服务器 Y 上的客户端 ip,

客户端请求服务器 X,服务器 X 将请求转发到服务器 Y。

而返回流程是Y->X->client

http头中的'REMOTE_ADDR'(实际上我是从request.environ['REMOTE_ADDR']得到的)有服务器X的IP。我从哪里可以得到服务器Y客户端的IP?

更新:

X 有一个公共 IP。 Y 在专用网络中,外部无法访问。现在我在同一个专用网络中使用客户端,我通过公共网络请求 X。

我只想知道标头是否已经包含我需要的内容,而无需在 X 处操作标头以包含客户端的 ip。

【问题讨论】:

  • 你在代理后面运行 Flask 的应用服务器吗?在这种情况下,很明显客户端实际上是代理。
  • 您是否使用app.run 运行您的应用程序? (顺便说一句,你应该只在开发中使用那个)
  • 是的,我正在这样做。我还在开发中。但这与这有什么关系:
  • 服务器 X 是否向服务器 Y 发送请求?

标签: http-headers ip client-server flask


【解决方案1】:

如果您的应用程序位于代理之后,那么在您的应用程序看来,请求的远程地址将来自代理,而不是实际的客户端。

http 规范中没有规定传递“真实”地址,但这样做的实际标准是让您的代理设置X-Forwarded-For header

Werkzeug 提供了一个fixer 来帮助解决这个问题,Flask docs 中有一个详细的示例,request.remote_addr 应该是你所期望的

【讨论】:

  • 如果我错了,请纠正我。基本上 X 不是代理。它是一个服务器,根据传入的请求找到要请求的服务器(其中一个是 Y)并将响应发送给客户端。
  • X-FORWARDED-For 在 Y 的标题中找不到。“我从 werkzeug.contrib.fixers 添加了 import ProxyFix app.wsgi_app = ProxyFix(app.wsgi_app)”。 request.remote_addr 给出了相同的结果,即服务器 Y 上服务器 X 的 ip。我只想知道标头是否已经具有我需要的内容,而无需操作标头。
【解决方案2】:

尽管您声称,X 基本上是一个代理,因为它根据用户发出的请求向 Y 发出自己的请求。所以REMOTE_ADDR 是 X 之一是完全有效的。

您必须在 X 的请求中添加自定义标头,例如 X-Original-User-IP 以使用户的 IP 可用于 Y。如果需要,您可以使用 ProxyFix,它会将 X-Forwarded-For 重写为 REMOTE_ADDR

你应该确保 Y 只对 X 可用并且不能被直接访问。否则,只需发送该自定义标头即可欺骗他的 IP 地址。

【讨论】:

  • 事实上,您需要确保 Y 仅对 X 可用 并且 Y 删除来自客户端的任何现有 X-Forwarded-For 标头.大多数代理的默认设置是附加到该标头并且 ProxyFix 选择第一个,因此除非您非常小心,否则您可以轻松地打开自己的 IP 欺骗。见esd.io/blog/flask-apps-heroku-real-ip-spoofing.html
猜你喜欢
  • 2019-01-14
  • 2013-07-07
  • 2011-05-26
  • 2019-11-13
  • 1970-01-01
  • 2011-01-08
  • 2014-12-29
  • 2010-09-10
  • 2010-11-22
相关资源
最近更新 更多