Python Flask实现公网ip查询

前言

为了将内部的应用暴露到外部,选择了CloudFlare的DDNS方式。

ddns脚本会执行curl -s ipv4.icanhazip.com 获取公网IP地址,并将其发送到cf,用以动态更新dns解析,大致是这么个原理。

ipv4.icanhazip.com 这个站点用的是cf的cdn,而cf的cdn节点,偶尔会出现不可访问的情况。

cdn不可访问+公网IP周期性变换,这两种情况同时发生,就导致无法从外部访问内部的应用。

故,为尽量避免此类结果的事件发生,决定自己实现一个类似的站点(折腾一下)。

过程

icanhazip对应的github资源,https://github.com/major/icanhaz

使用Nginx做了一层代理,一开始获取到的“remote_addr”始终是127.0.0.1

中间尝试换成取请求头部的字段来获取IP,发现这种方式不是合理的,而且在Flask官网上找到了更好的方法。

https://flask.palletsprojects.com/en/1.1.x/deploying/wsgi-standalone/ ,官方给出的修补方法。

Nginx配置

server{
    listen 80;
    server_name ;
    location /.well-known {
        root ;
    }
    location / {
        rewrite ^(.*)$ https://$1 permanent;
    }
}

server {
    listen 443;
    autoindex off;
    server_name ;
    access_log ;
    ssl_certificate ;
    ssl_certificate_key ;
    location / {
        proxy_pass http://127.0.0.1:5000;
        proxy_redirect     off;
        proxy_set_header   Host                 $host;
        proxy_set_header   X-Real-IP            $remote_addr;
        proxy_set_header   X-Forwarded-For      $proxy_add_x_forwarded_for;
        proxy_set_header   X-Forwarded-Proto    $scheme;
    }
}

Python代码

#!/usr/bin/env python
from flask import Flask, Response, request
from werkzeug.middleware.proxy_fix import ProxyFix

app = Flask(__name__)
app.wsgi_app = ProxyFix(app.wsgi_app, x_proto=1, x_host=1)


@app.route("/", methods=['GET'])
def pubip():
    ip = request.remote_addr
    return Response("%s\n" % ip, mimetype="text/plain")


if __name__ == "__main__":
    app.run()

启动方式

用supervisor来启动Python程序并守护,对应的配置如下

[program:pubip]
command=python pubip.py
stdout_logfile=pubip.log
stderr_logfile=pubip.log
user=
group=
autostart=true
autorestart=true
posted @ 2022-10-26 17:13  ヾ(o◕∀◕)ノヾ  阅读(376)  评论(0)    收藏  举报