V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
secsilm
V2EX  ›  Python

flask 获取客户端 IP

  •  
  •   secsilm ·
    secsilm · 2019-03-26 16:35:55 +08:00 via Android · 6428 次点击
    这是一个创建于 2098 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我用 flask 写的服务,服务部署在公司没网,没有 nginx,如果请求来自内网,那就没问题,如果请求来自外网,那就只能获取到一个固定的内网 IP。

    获取 IP 用的是 request.remore_addr,请教下大家这有可能是什么问题造成的?

    17 条回复    2019-03-26 19:45:43 +08:00
    foxyier
        1
    foxyier  
       2019-03-26 16:45:47 +08:00
    "服务部署在公司没网, 没有 nginx" 没看懂
    mayorbryant
        2
    mayorbryant  
       2019-03-26 16:51:25 +08:00
    你是 127 启动的还是 0.0.0.0
    ebingtel
        3
    ebingtel  
       2019-03-26 16:51:48 +08:00
    这个固定的内网 IP 就是 nginx 那台机器的地址吧?需要设置一下 nginx,让它真实的 IP 设置到某个 request header,
    flask 再读取这个 header
    Abbeyok
        4
    Abbeyok  
       2019-03-26 16:53:16 +08:00
    try:
    ip = request.headers['X-Forwarded-For'].split(',')[0]
    except:
    ip = request.remote_addr
    Latin
        5
    Latin  
       2019-03-26 16:53:22 +08:00
    外网访问跑到了内网的网关去了呗,还是套个 nginx 拿比较实在
    arrow8899
        6
    arrow8899  
       2019-03-26 16:54:02 +08:00
    部署在内网,你外网用什么访问的,肯定是网关做了端口转发的吧,固定的 IP 就是网关的 IP
    secsilm
        7
    secsilm  
    OP
       2019-03-26 16:59:24 +08:00 via Android
    @Abbeyok 这个尝试了,还是那个固定内网 IP
    secsilm
        8
    secsilm  
    OP
       2019-03-26 17:04:41 +08:00 via Android
    @Latin @arrow8899 感谢提醒,估计是这个原因,如果是这样的话该咋办呢,让他们把 IP 带上给我?
    ThirdFlame
        9
    ThirdFlame  
       2019-03-26 17:14:03 +08:00
    应该不是端口转发。 如果是端口转发的话,那么源 ip 还是 客户的 IP 不是防火墙 /路由器的 IP。
    应该是一个类似于 nginx 的 反代或者是应用层代理。

    建议抓下包,看下 http 头部中有没有 XFF 等字段。如果没有那就得沟通 上级做所谓端口映射的设备了。
    fucker
        10
    fucker  
       2019-03-26 17:16:02 +08:00
    9L 正解
    fucker
        11
    fucker  
       2019-03-26 17:17:48 +08:00
    @foxyier #1
    "secsilm · 40 分钟前用 Android 发布 · 187 次点击"
    "服务部署在公司没网,没有 nginx"
    估计是九宫格输入法,没网 => 内网
    Abbeyok
        12
    Abbeyok  
       2019-03-26 17:42:20 +08:00
    @secsilm 你确定 request.headers['X-Forwarded-For'].split(',')[0] 这个不行? nginx 反代之后,我一直都用这个
    wuyifar
        13
    wuyifar  
       2019-03-26 18:25:53 +08:00
    二楼说的方法试了吗,host = 0.0.0.0 启动
    xpresslink
        14
    xpresslink  
       2019-03-26 18:59:38 +08:00
    楼主这个问题从你自己这里无解。

    从外网访问的用户都会通过你们网关服务器接入内网的,所以你的 web 服务器得到的都是网关的 IP。
    除非你找网管来解决,直接给你的 web 做个反向代理,同转发完整的 HTTP 请求头。
    如果是 nginx 做反向代理只要在配置里面加上这面这几项
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header REMOTE-HOST $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    secsilm
        15
    secsilm  
    OP
       2019-03-26 19:31:21 +08:00
    @mayorbryant
    @wuyifar 一直都是 0.0.0.0 启动
    secsilm
        16
    secsilm  
    OP
       2019-03-26 19:40:09 +08:00
    @Abbeyok 对,都试了,都是那个内网 IP,而且我本身也没有用 nginx,我觉得可能还是公司网关服务器的问题


    @fucker
    @xpresslink 感谢回复,明天看看

    @fucker 正解😂
    westoy
        17
    westoy  
       2019-03-26 19:45:43 +08:00
    nginx 套一个 proxy.conf

    flask 套一个 werkzeug.contrib.fixers.ProxyFix 的 middleware
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5522 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 05:50 · PVG 13:50 · LAX 21:50 · JFK 00:50
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.