繁体   English   中英

如何限制单个 IP 地址对 Flask 的访问?

[英]How to limit access to Flask for a single IP address?

我正在使用 Python Flask 框架开发一个网站,现在我做了一些开发,将我的更改推送到远程开发服务器。 我将此远程开发服务器设置为使用app.run(host='0.0.0.0')公开为网站提供服务。

这工作正常,但我只是不希望其他人查看我的网站。 出于这个原因,我想以某种方式将我的 ip 列入白名单,以便开发服务器只为我自己的 ip 地址提供网站服务,而对其他 ip 地址不提供响应、404 或其他一些无用的响应。 我当然可以将服务器设置为使用 apache 或 nginx 来实际为网站提供服务,但我喜欢在代码更改时自动重新加载网站以开发我的网站

那么有人知道使用内置的 Flask 开发服务器来做到这一点的方法吗? 欢迎所有提示!

使用 Flask 的功能,您可以使用before_request()钩子测试request.remote_addr属性

from flask import abort, request

@app.before_request
def limit_remote_addr():
    if request.remote_addr != '10.20.30.40':
        abort(403)  # Forbidden

但在服务器上使用防火墙规则可能是更安全、更可靠的选择。

请注意,如果浏览器和服务器之间存在反向代理,则可以屏蔽 Remote_Addr; 小心你如何限制这一点,不要把自己锁在外面。 如果代理靠近服务器本身(如负载平衡器或前端缓存),您可以检查request.access_route列表以访问实际 IP 地址。 仅当remote_addr本身也是受信任的 IP 地址时才这样做

trusted_proxies = ('42.42.42.42', '82.42.82.42', '127.0.0.1')

def limit_remote_addr():
    remote = request.remote_addr
    route = list(request.access_route)
    while remote in trusted_proxies:
        remote = route.pop()

    if remote != '10.20.30.40':
        abort(403)  # Forbidden

这个 IPTABLES/Netfilter 规则将满足您的需要,丢弃所有传入流量,除了来自your_ip_address到端口 80 的流量:

$ /sbin/iptables -A INPUT -s ! your_ip_address --dport 80 -j DROP

这是许多论坛上介绍的内容,它允许本地流量+从your_ip_address外部访问您的 Flask 应用程序,但拒绝来自其他 IP 地址的所有流量:

$ /sbin/iptables -A INPUT -i lo -j ACCEPT
$ /sbin/iptables -A INPUT -s your_ip_address --dport 80 -j DROP
$ /sbin/iptables -A INPUT --dport 80 -j REJECT

尽管您可以通过 Flask 轻松实现预期结果(如所选答案所指出的那样),但应在操作系统的网络层处理此类问题。 考虑到您使用的是类似 Nix 的操作系统,您可以通过IPTABLES使用Netfilter拒绝/允许传入连接,规则如下。

传入的流量/数据包首先通过对操作系统内核的分析。 要拒绝/允许从任何来源到特定端口的流量,这是操作系统防火墙在其内核的网络层上的一项工作。 如果您的服务器上没有运行防火墙,则应该对其进行配置。

这是一个要点:

  • 必须在操​​作系统的网络层处理流量。 不要让应用程序处理这个任务,至少在生产环境中是这样。 没有人会在此任务上做得最好,而不是您操作系统的内核(希望您使用的是类似 Nix 的操作系统)。 Linux 内核及其模块 (Netfilter) 在处理此类任务时更加可靠、称职和有效。

我发现这非常有帮助,但如果您有多个 IP 地址,则有一种更简单的方法可以做到这一点。

trusted_ips = ['42.42.42.42', '82.42.82.42', '127.0.0.1']

@app.before_request
def limit_remote_addr():
if request.remote_addr not in trusted_ips:
    abort(404)  # Not Found

如果远程 ip 不在列表中,这将检查您的可信 ip 列表并返回“404 - 未找到”。

您还可以通过更改一些内容来阻止特定的 ip

bad_ips = ['42.42.42.42', '82.42.82.42', '127.0.0.1']

@app.before_request
def limit_remote_addr():
if request.remote_addr in bad_ips:
    abort(404)  # Not Found

同样的事情,但阻止了 bad_ips 列表中的 ip

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM