简体   繁体   English

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

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

I'm developing a website using the Python Flask framework and I now do some devving, pushing my changes to a remote dev server.我正在使用 Python Flask 框架开发一个网站,现在我做了一些开发,将我的更改推送到远程开发服务器。 I set this remote dev server up to serve the website publically using app.run(host='0.0.0.0') .我将此远程开发服务器设置为使用app.run(host='0.0.0.0')公开为网站提供服务。

This works fine, but I just don't want other people to view my website yet.这工作正常,但我只是不希望其他人查看我的网站。 For this reason I somehow want to whitelist my ip so that the dev server only serves the website to my own ip address, giving no response, 404's or some other non-useful response to other ip addresses.出于这个原因,我想以某种方式将我的 ip 列入白名单,以便开发服务器只为我自己的 ip 地址提供网站服务,而对其他 ip 地址不提供响应、404 或其他一些无用的响应。 I can of course set up the server to use apache or nginx to actually serve the website, but I like the automatic reloading of the website on code changes for devving my website我当然可以将服务器设置为使用 apache 或 nginx 来实际为网站提供服务,但我喜欢在代码更改时自动重新加载网站以开发我的网站

So does anybody know of a way to do this using the built in Flask dev server?那么有人知道使用内置的 Flask 开发服务器来做到这一点的方法吗? All tips are welcome!欢迎所有提示!

Using just the features of Flask, you could use a before_request() hook testing the request.remote_addr attribute :使用 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

but using a firewall rule on the server is probably the safer and more robust option.但在服务器上使用防火墙规则可能是更安全、更可靠的选择。

Note that the Remote_Addr can be masked if there is a reverse proxy in between the browser and your server;请注意,如果浏览器和服务器之间存在反向代理,则可以屏蔽 Remote_Addr; be careful how you limit this and don't lock yourself out.小心你如何限制这一点,不要把自己锁在外面。 If the proxy lives close to the server itself (like a load balancer or front-end cache), you can inspect the request.access_route list to access the actual IP address.如果代理靠近服务器本身(如负载平衡器或前端缓存),您可以检查request.access_route列表以访问实际 IP 地址。 Do this only if remote_addr itself is a trusted IP address too :仅当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

This IPTABLES/Netfilter rule will attend your need, dropping all incoming traffic, EXCEPT the traffic originated from your_ip_address to port 80:这个 IPTABLES/Netfilter 规则将满足您的需要,丢弃所有传入流量,除了来自your_ip_address到端口 80 的流量:

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

Here's something presented on many forums, which allows localhost traffic + external access to your Flask app from your_ip_address , but reject all traffic from other IP address:这是许多论坛上介绍的内容,它允许本地流量+从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

Although you can easily achieve the expected result via Flask (as pointed out on the elected answer), this kind of issue should be treated at the Network Layer of the Operating System.尽管您可以通过 Flask 轻松实现预期结果(如所选答案所指出的那样),但应在操作系统的网络层处理此类问题。 Considering that you're using a Nix-like OS, you can deny/allow incoming connections using Netfilter via IPTABLES , with rules like these.考虑到您使用的是类似 Nix 的操作系统,您可以通过IPTABLES使用Netfilter拒绝/允许传入连接,规则如下。

Incoming traffic/packets, firstly, they pass through the analysis of the Kernel of your Operating System.传入的流量/数据包首先通过对操作系统内核的分析。 To deny/allow traffic, from any source to specific ports, it's a job for the Firewall of the Operating System, on the Network Layer of its Kernel.要拒绝/允许从任何来源到特定端口的流量,这是操作系统防火墙在其内核的网络层上的一项工作。 If you don't have a Firewall running on your server, you should configure it.如果您的服务器上没有运行防火墙,则应该对其进行配置。

Here's a takeaway:这是一个要点:

  • Traffic must be treated at the Network Layer of your Operating System.必须在操​​作系统的网络层处理流量。 Do not let application handle this task, at least on a Production environment.不要让应用程序处理这个任务,至少在生产环境中是这样。 No one will do a best job regarding this task, than the Kernel of you Operating System (hoping that you're using a Nix-like OS).没有人会在此任务上做得最好,而不是您操作系统的内核(希望您使用的是类似 Nix 的操作系统)。 The Linux Kernel and its modules (Netfilter) are much more reliable, competent and effective to treat these kind of tasks. Linux 内核及其模块 (Netfilter) 在处理此类任务时更加可靠、称职和有效。

I found this very helpful, but there is an easier way to do this if you have multiple ip address.我发现这非常有帮助,但如果您有多个 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

This will check your trusted ip list and return "404 - Not Found" if the remote ip is not in the list.如果远程 ip 不在列表中,这将检查您的可信 ip 列表并返回“404 - 未找到”。

You can also block specific ip by changing a few things您还可以通过更改一些内容来阻止特定的 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

Same thing but blocks the ips in your bad_ips list同样的事情,但阻止了 bad_ips 列表中的 ip

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

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