如何从 nginx + Gunicorn 后面的 X-Forwarded-For 获取第一个客户端 IP? [复制]

Posted

技术标签:

【中文标题】如何从 nginx + Gunicorn 后面的 X-Forwarded-For 获取第一个客户端 IP? [复制]【英文标题】:How to get the first client ip from X-Forwarded-For behind nginx + Gunicorn? [duplicate] 【发布时间】:2016-02-22 11:02:42 【问题描述】:

nginx + Gunicorn 部署一个烧瓶应用程序,我需要从访问者那里获取真实的 ip。 (对于 Gunicorn 在 nginx 之后无法获取 REMOTE-ADDR)我尝试通过以下方式从 X-Forwarede-for 获取客户端 ip:

client_ip = request.headers.getlist("X-Forwarded-For")[0]

有时我会像这样正确获取 client_ip:

x-forwarded-for: 62.211.19.218

但有时我会像这样得到 client_ip 错误 - 结合代理 ip 地址(从一些不同的浏览器访问):

x-forwarded-for: 62.211.19.218, 177.168.159.85

nginx将两个ip地址转发给App时,如何只获取第一个客户端ip(没有代理地址177.168.159.85)?

【问题讨论】:

检查***.com/a/51928942/5588862 【参考方案1】:

一般X-FORWARDED-FOR形式如下:

X-Forwarded-For: client1, proxy1, proxy2, ...

但请记住,您不应该信任 X-Forwarded-For 或任何其他标头值,因为它们可以被不受信任的代理或其他东西操纵...

如果你使用nginx做反向代理,也可以查看request.environ['HTTP_X_REAL_IP']


编辑

根据flask documentation,client_ip = request.access_route[0] 将是您的答案。它将返回X-FORWARDED-FOR 中的IP 地址。检查这个wrekzeug/wrapper.py源代码

@cached_property
def access_route(self):
    """If a forwarded header exists this is a list of all ip addresses
    from the client ip to the last proxy server.
    """
    if 'HTTP_X_FORWARDED_FOR' in self.environ:
        addr = self.environ['HTTP_X_FORWARDED_FOR'].split(',')
        return self.list_storage_class([x.strip() for x in addr])
    elif 'REMOTE_ADDR' in self.environ:
        return self.list_storage_class([self.environ['REMOTE_ADDR']])
    return self.list_storage_class()

请注意,有些 http 服务器会将 localhost 或本地 IP 地址附加到 access_route 列表的第一项中。

【讨论】:

问题是我试图通过 request.headers.getlist("X-Forwarded-For")[0], [0] 获得第一个 client1 ip表格,但有时它会先获得第一个 client1,然后是 proxy1。这样另一个 App 就无法分析这两个组合的 IP 字符串。是的,我已经通过request.environ.get['HTTP_X_REAL_IP']得到了,谢谢! @rogwan 那你为什么不直接使用 split by , 分割结果呢? @mromo 我试过这个:> client_ip = request.headers.getlist("X-Forwarded-For").split(',')[0] 但它不起作用...... 追加新答案,检查一下。同样在您的最后评论中,将getlist 替换为get 将起作用。 完美!使用 'get' 而不是 'getlist' 效果很好,感谢您准确指出这个错误。

以上是关于如何从 nginx + Gunicorn 后面的 X-Forwarded-For 获取第一个客户端 IP? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

覆盖金字塔/ gunicorn中的请求超时

将 JSON 从 Nginx 传递到 Gunicorn

Gunicorn 不会从 nginx 记录真实 ip

如何使用 gunicorn 为 django 配置 nginx?

使用 nginx 和 gunicorn 运行烧瓶应用程序

nginx+gunicorn+flask部属web时,使用nginx如何指定多个静态文件路径