簡體   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