Django 初學者指南:ALLOWED_HOSTS 設定與安全性考量

更新日期: 2025 年 3 月 13 日

Django 是一個強大的 Web 框架,但在部署時,安全性設定至關重要。

其中,ALLOWED_HOSTS 是 Django 預設的安全機制之一,它能有效防止 HTTP Host Header 攻擊。

然而,許多初學者在部署 Django 至 GCP 或其他雲端平台時,對於如何正確設定 ALLOWED_HOSTS 感到困惑。

本篇文章將詳細介紹 ALLOWED_HOSTS 的概念、風險、防範措施,以及如何在 GCP 環境中透過 Docker Compose 和環境變數來管理這個設定。


什麼是 ALLOWED_HOSTS?

ALLOWED_HOSTS 是 Django 設定檔 settings.py 中的一項安全機制,主要用來防範 HTTP Host Header 攻擊

它的作用是檢查 來自用戶端的請求中 Host 標頭 (Host Header) 是否在允許的清單內,從而確保只有經過授權的網域或 IP 地址才能存取 Django 應用。

當 Django 伺服器收到 HTTP 請求時,它會解析請求標頭中的 Host 欄位,並與 ALLOWED_HOSTS 內的清單進行比對:

  • HostALLOWED_HOSTS 清單內,請求將被接受並繼續處理。
  • Host 不在清單內,Django 會立即返回 400 Bad Request,防止進一步處理請求。

基本範例

settings.py 中,我們可以這樣設定 ALLOWED_HOSTS

ALLOWED_HOSTS = ['example.com', 'www.example.com', '34.123.45.67', 'localhost']

這表示:

  • Django 允許 來自 example.comwww.example.com 的請求。
  • 允許使用指定的 IP 地址 34.123.45.67 直接存取。
  • 允許在 本機環境 (localhost) 中存取,例如開發環境的測試請求。
  • 任何 不在 ALLOWED_HOSTS 清單中的請求都會被拒絕,並回應 400 Bad Request

為什麼需要 ALLOWED_HOSTS?

ALLOWED_HOSTS 主要用來防止 HTTP Host Header 攻擊,這是一種針對 Web 伺服器的攻擊手法,攻擊者可以透過 偽造 Host 標頭 來達成不同的攻擊目的。例如:

不安全的重定向 (Open Redirect) 攻擊

情境說明

假設你的 Django 網站有一個 登入成功後的重定向功能,它會把使用者導向首頁 (/home/)。程式碼可能如下:

from django.http import HttpResponseRedirect

def redirect_to_home(request):
    return HttpResponseRedirect(f"https://{request.get_host()}/home/")

在這段程式碼中,request.get_host() 會取得 HTTP 請求中的 Host 標頭 (Host Header),然後組合成重定向的 URL。

攻擊方式

攻擊者可以發送一個 偽造的 Host 標頭,例如:

GET / HTTP/1.1
Host: attacker.com

Django 在沒有嚴格檢查 Host 的情況下,會根據這個偽造的 Host 產生以下重定向網址:

https://attacker.com/home/

然後,當 Django 把這個網址發送回用戶時:

  1. 用戶的瀏覽器會 自動導向 attacker.com/home/
  2. attacker.com 可能是一個 釣魚網站,它的畫面看起來跟你的網站很像,讓用戶以為自己仍然在官方網站上。
  3. 用戶可能會在攻擊者網站輸入帳號密碼,從而洩露個人資料。

如何防範?

settings.py 中設定 ALLOWED_HOSTS,讓 Django 只接受指定的 Host

ALLOWED_HOSTS = ['example.com', 'www.example.com']

這樣,當攻擊者偽造 attacker.com 時,Django 會直接返回 400 Bad Request,阻止攻擊發生。

生成錯誤的絕對 URL

情境說明

假設你的 Django 應用程式有 密碼重設功能,會在寄送郵件時提供一個網址讓用戶點擊來重設密碼:

def get_password_reset_url(request):
    absolute_url = f"https://{request.get_host()}/reset-password/"
    return absolute_url

在這段程式碼中:

  • request.get_host() 取得 Host 標頭 (例如 example.com)。
  • 然後組合出 https://example.com/reset-password/,讓用戶點擊重設密碼。

攻擊方式

攻擊者發送一個帶有偽造 Host 的 HTTP 請求:

GET / HTTP/1.1
Host: fakebank.com

Django 沒有檢查 Host,所以會錯誤地產生:

https://fakebank.com/reset-password/

這個錯誤的 URL 可能會出現在:

  • Django 自動發送的 密碼重設郵件
  • 應用程式內部的 UI 按鈕,例如「重設密碼」。

當用戶收到這封郵件,點擊 https://fakebank.com/reset-password/

  1. 他會進入攻擊者控制的網站 (fakebank.com)。
  2. 這個網站可能會顯示一個 與原站相似的登入頁面,誘導用戶輸入密碼。
  3. 用戶輸入的密碼就會直接傳送給攻擊者,造成帳號洩露。

如何防範?

settings.py 中設定 ALLOWED_HOSTS,讓 Django 只允許合法的 Host

ALLOWED_HOSTS = ['example.com', 'www.example.com']

此外,在產生網址時,避免使用 request.get_host(),而是硬編碼官方網站的網域

def get_password_reset_url():
    return "https://example.com/reset-password/"

這樣,不管攻擊者如何偽造 Host,Django 產生的密碼重設連結都會是 正確的官方網址

綜合比較

攻擊類型攻擊手法風險防範方式
不安全的重定向 (Open Redirect)偽造 Host,讓 Django 產生錯誤的跳轉網址用戶被導向釣魚網站,可能洩露帳號密碼設定 ALLOWED_HOSTS 限制合法的 Host
生成錯誤的絕對 URL偽造 Host,讓 Django 產生錯誤的網站連結釣魚攻擊,誘導用戶點擊錯誤的密碼重設連結設定 ALLOWED_HOSTS,避免使用 request.get_host() 生成 URL

Django 如何判斷請求是否合法?

當使用者在瀏覽器中輸入 http://example.com 時,請求的處理流程如下:

瀏覽器發送 HTTP 請求

瀏覽器向伺服器發送請求時,會在 HTTP 標頭中包含 Host 欄位,例如:

GET / HTTP/1.1
Host: example.com

Django 伺服器檢查 ALLOWED_HOSTS

Django 伺服器收到請求後,會執行以下檢查:

  • 如果 example.comALLOWED_HOSTS,請求被接受並繼續處理。
  • 如果 Host 不在 ALLOWED_HOSTS 清單內,Django 直接回應 400 Bad Request,請求終止。

ALLOWED_HOSTS 只影響 HTTP 層,不影響網路層

在 Django 的安全機制中,ALLOWED_HOSTS 僅適用於 HTTP 層,它的作用是檢查請求的 Host 標頭 (Host Header) 是否在允許的清單中。

然而,它不會影響伺服器的網路層存取權限,這一點非常重要。

什麼是網路層與 HTTP 層?

在網路架構中,我們可以將 Django 伺服器的存取控制分為 網路層 (Network Layer)HTTP 層 (Application Layer) 來理解:

  1. 網路層 (Network Layer)
    • 控制誰可以連接到伺服器的 IP 地址Port (端口)
    • 例如,防火牆規則 (iptables、GCP 防火牆) 可用來限制哪些 IP 可以連線到伺服器的 80 (HTTP) 或 443 (HTTPS) 端口。
  2. HTTP 層 (Application Layer)
    • 這一層發生在 TCP 連線已經建立之後,處理 HTTP 請求的內容。
    • ALLOWED_HOSTS 屬於 HTTP 層,它不會阻擋連線,而是檢查請求中的 Host 標頭,確保 Django 只回應來自合法網域的請求。

ALLOWED_HOSTS 不影響 TCP 連線

由於 ALLOWED_HOSTS 只檢查 HTTP Host 標頭,而不會影響網路層的存取,這意味著:

  • 任何知道伺服器 IP 地址 的人都可以嘗試向 Django 伺服器發送 HTTP 請求。
  • 但 Django 不一定會回應這些請求,因為它會先檢查 ALLOWED_HOSTS

舉例說明

假設你的 Django 伺服器運行在 GCP VM 上,並且你的 ALLOWED_HOSTS 只允許你的官方域名:

ALLOWED_HOSTS = ['example.com']

這代表 Django 只會回應來自 example.com 的請求。

情境 1:正常請求

使用者在瀏覽器輸入:

http://example.com

瀏覽器會發送請求:

GET / HTTP/1.1
Host: example.com

Django 會檢查 Host,發現 example.comALLOWED_HOSTS 清單內,因此接受請求並回應正常的 HTTP 內容

情境 2:攻擊者直接用 IP 存取

假設攻擊者知道了你的 GCP 伺服器的 IP,例如 34.123.45.67,並嘗試直接使用 IP 進行請求:

http://34.123.45.67

攻擊者的請求如下:

GET / HTTP/1.1
Host: 34.123.45.67

Django 會進行 ALLOWED_HOSTS 檢查:

  • 34.123.45.67 不在 ALLOWED_HOSTS 清單內。
  • Django 直接回應 400 Bad Request,拒絕處理該請求。

但需要注意的是:

  • 攻擊者的請求仍然會到達你的伺服器,只是 Django 不會回應內容。
  • 如果伺服器上運行的不是 Django,而是其他應用程式 (如 Nginx),該應用程式仍可能處理請求。

如何加強安全性?

雖然 ALLOWED_HOSTS 能防止 Django 回應未授權的 Host,但它無法阻止攻擊者與伺服器建立 TCP 連線。因此,建議額外採取以下措施來提升安全性:

1. 設定防火牆,限制 IP 存取

在 GCP 或其他雲端平台上,可以設定防火牆 只允許特定 IP 或 Cloudflare Proxy 來存取 Django 伺服器

  • GCP 防火牆規則 中,設定 只允許 80 (HTTP) 和 443 (HTTPS) 來自 Cloudflare IP 的存取,其他 IP 則封鎖。
  • Linux 伺服器上使用 iptables,只允許來自特定 IP 的連線:
sudo iptables -A INPUT -p tcp --dport 80 -s 203.0.113.0/24 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 443 -s 203.0.113.0/24 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 80 -j DROP
sudo iptables -A INPUT -p tcp --dport 443 -j DROP
  • 這樣,只有來自 203.0.113.0/24 (例如 Cloudflare) 的請求能夠進入伺服器。

2. 使用反向代理 (Nginx) 來過濾 Host

你可以使用 Nginx 作為反向代理,並在 Nginx 設定檔 (nginx.conf) 中 只允許特定 Host,將不符合條件的請求直接拒絕:

server {
    listen 80;
    server_name example.com www.example.com;
    
    if ($host !~* ^(example\.com|www\.example\.com)$ ) {
        return 444;
    }

    location / {
        proxy_pass http://127.0.0.1:8000;
    }
}

這樣,來自 example.com 的請求會直接被 Nginx 丟棄 (返回 HTTP 444),根本不會傳到 Django。

總結

安全機制作用範圍限制效果
GCP 防火牆 (firewall rules)網路層 (TCP/IP)控制哪些 IP 可以連接到伺服器
Nginx 反向代理HTTP 層只允許特定 Host 進入 Django
Django ALLOWED_HOSTSHTTP 層只允許 Django 回應合法 Host 的請求
  • ALLOWED_HOSTS 只影響 HTTP 應用層,它無法阻擋來自任何來源的 TCP 連線,但能確保 Django 只回應合法的 Host
  • 如果要完全避免攻擊者直接存取伺服器 IP,應該搭配 GCP 防火牆Linux iptables 限制 IP 存取。
  • 若使用 Nginx,還可以額外設定 server_name 來過濾 Host,進一步增強安全性。

這樣,你的 Django 伺服器才能真正安全地運行在雲端環境中! 🚀


常見錯誤與最佳實踐

在設定 ALLOWED_HOSTS 時,許多初學者會犯一些常見錯誤,例如 錯誤的格式暴露伺服器 IP,或是 硬編碼設定,這些都可能影響 Django 應用的正常運行與安全性。

以下是常見錯誤與正確的最佳做法,幫助你確保 Django 部署時的安全性與靈活性。

錯誤:包含 http://https://

許多初學者誤以為 ALLOWED_HOSTS 需要包含完整的 URL,例如:

# ❌ 錯誤的設定:
ALLOWED_HOSTS = ['https://example.com', 'http://www.example.com']

這樣的設定會導致 Django 直接回應 400 Bad Request,因為 ALLOWED_HOSTS 只比對 Host 標頭,而 HTTP Host 標頭不包含 http://https://

🔎 為什麼會錯?

在 HTTP 通訊協議中,請求的 Host 標頭只包含主機名稱 (域名或 IP),不包含協議 (protocol)。舉例來說,當用戶請求 https://example.com 時,實際的 HTTP 請求是:

GET / HTTP/1.1
Host: example.com

如果 ALLOWED_HOSTS 設定為 ['https://example.com'],Django 會比對 Host"https://example.com",但請求的 Host 只有 "example.com",因此匹配失敗,導致 400 錯誤。

為什麼 HTTP Host 標頭不包含 http://

當客戶端發送 HTTP 或 HTTPS 請求時,請求的 第一行 (請求行, Request Line) 會包含:

GET /index.html HTTP/1.1

Host 標頭則只會包含主機名稱,例如:

Host: example.com

不會是:

Host: https://example.com  ❌(錯誤)

為什麼 Host 不包含 http://https://

  1. 因為 HTTP 層不負責協議 (Protocol) 的選擇
    • 協議 (http://https://) 早在 TCP 建立連線時就已經確定了
    • 如果是 HTTPS,瀏覽器會先建立 TLS 安全通道,之後的 HTTP 請求會直接在加密通道內傳輸,因此 Host 無需再指定 https://
  2. HTTP Host 只用來識別伺服器的名稱
    • 伺服器可能會託管多個網站,例如: server { listen 80; server_name example.com; } 在這種情況下,Host: example.com 讓伺服器知道該回應 example.com 這個站點,而不是其他網站 (如 another-site.com)。

哪個協議負責處理 http://https://

HTTP 本身不處理 http://https://,而是由 瀏覽器或客戶端應用程式 根據使用者輸入的網址來決定:

  • 如果輸入 http://example.com,則 使用 HTTP,連接到 80 端口
  • 如果輸入 https://example.com,則 使用 HTTPS,連接到 443 端口,並觸發 TLS 加密協議 來確保安全性。

這裡有三個主要負責的協議層:

  1. TCP/IP (網路層):建立與伺服器的連線。
  2. TLS (安全層, 只有 HTTPS 會用到):提供加密與身份驗證。
  3. HTTP (應用層):傳輸網頁內容,處理請求與回應。

因此,當 Django 在 ALLOWED_HOSTS 中檢查 Host 時,它處理的是 HTTP 層,而 http://https:// 的部分已經在較低層的協議中處理完畢了。

Host 在 HTTPS 連線中的特殊情況

當 Django 檢查 ALLOWED_HOSTS 時,它不會知道請求來自 httphttps,因為:

  • 如果是 HTTP,請求直接傳遞給 Django,Host 只會是 example.com
  • 如果是 HTTPS,請求已經先通過 TLS 加密通道,Django 依然只會收到 example.com,不會看到 https://

但有一個例外: 如果你的 Django 伺服器運行在 反向代理 (如 Nginx) 之後,而 Nginx 處理 HTTPS,則 Django 只會收到來自 Nginx 的 HTTP 請求

這時,你可以在 Django 設定 SECURE_PROXY_SSL_HEADER 來確保 Django 知道請求原本是 HTTPS:

SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')

這樣,即使 Django 只看到 HTTP,它仍然能知道最初的請求是否來自 HTTPS。

綜合比較

層級作用負責處理 http:// / https:// 嗎?
應用層 (HTTP)負責處理請求 (如 GET /index.html),檢查 Host。❌ 否,Host 只會包含域名 (如 example.com)
安全層 (TLS/SSL, 只有 HTTPS 會用到)確保加密傳輸,提供身份驗證。✅ 是,負責 HTTPS 的加密與驗證
傳輸層 (TCP)建立 TCP 連線 (80 = HTTP,443 = HTTPS)。✅ 是,透過端口決定使用 HTTP 或 HTTPS
網路層 (IP)負責資料封包的傳輸。❌ 否,IP 只知道要發送資料到哪台機器

正確做法:只填入域名或 IP

設定時應該只填入主機名稱 (域名或 IP),而不是完整的 URL:

# ✅ 正確的設定:
ALLOWED_HOSTS = ['example.com', 'www.example.com', '34.123.45.67']

這樣 Django 就能正確比對 Host,避免錯誤。

使用環境變數管理 ALLOWED_HOSTS

Docker 環境雲端部署 (如 GCP、AWS) 時,最佳做法是使用環境變數來管理 ALLOWED_HOSTS,避免將設定硬編碼在 settings.py,提高靈活性。

步驟 1:在 settings.py 讀取環境變數

import os
ALLOWED_HOSTS = os.getenv('DJANGO_ALLOWED_HOSTS', '').split(',')

這樣,Django 會從系統環境變數 DJANGO_ALLOWED_HOSTS 讀取設定,並解析為一個列表。

步驟 2:在 .env 檔案中設定 ALLOWED_HOSTS

.env 檔案 (用於 Docker 或 docker-compose) 中定義:

DJANGO_ALLOWED_HOSTS=example.com,www.example.com

步驟 3:在 docker-compose.yml 中載入環境變數

如果你的 Django 應用運行在 Docker Compose,可以在 docker-compose.yml 內這樣載入 .env

version: '3'
services:
  web:
    image: my-django-app
    env_file:
      - .env

這樣,你可以輕鬆修改 .env 來更改 ALLOWED_HOSTS,而不必手動編輯 settings.py,避免硬編碼帶來的維護困難與安全風險。


如何避免暴露伺服器的 IP?

當你將 Django 應用程式部署到雲端 (如 GCP、AWS、Azure),你可能會遇到這樣的問題:

該如何設定 ALLOWED_HOSTS,才能允許正常使用者存取,但同時避免攻擊者直接使用伺服器的 IP 來攻擊你的網站

許多初學者可能會直接將伺服器的 公網 IP 加入 ALLOWED_HOSTS,例如:

# ❌ 直接暴露伺服器的 IP
ALLOWED_HOSTS = ['34.123.45.67']

這樣的設定存在安全風險,讓我們來看看為什麼這麼做不好,以及如何更安全地管理 ALLOWED_HOSTS

為什麼直接暴露伺服器 IP 會有風險?

1️⃣ 攻擊者可以直接使用 IP 存取伺服器

當你將 Django 應用程式的 公網 IP 設為 ALLOWED_HOSTS,表示只要攻擊者知道你的 IP,他就可以直接透過 IP 存取你的網站,例如:

http://34.123.45.67/

這可能會導致以下問題:

  • 繞過你的域名安全性措施
    如果你的網站透過 Cloudflare 或 Nginx 作為防護層,但允許直接用 IP 存取,那麼攻擊者可以繞過這些保護機制,直接攻擊你的 Django 伺服器。
  • 容易成為掃描攻擊目標
    許多駭客會使用工具 (如 ShodannmapZmap) 掃描公網上的伺服器 IP,尋找開放的端口 (如 80、443) 來進行攻擊。如果你的 IP 被掃描到,攻擊者可能會:
    • 暴力破解管理後台
    • 發動 DDoS 攻擊
    • 利用已知的 Django 漏洞進行入侵
  • 可能洩露內部開發環境
    如果你的開發環境或測試環境也使用這個 IP,攻擊者可能會存取尚未正式公開的功能,甚至找到未經保護的 API 端點。

2️⃣ 如果你的伺服器 IP 變更了,Django 設定就會失效

當你將 固定的 IP 設為 ALLOWED_HOSTS,你的 Django 伺服器只能接受來自該 IP 的請求。然而,在雲端環境 (如 GCP、AWS) 中:

  • 你的 公網 IP 可能會變動 (如果沒有設定靜態 IP)。
  • 如果你使用 自動擴展 (Auto Scaling) 或負載平衡 (Load Balancer),你的 IP 可能會隨機變動。

這時候,你的 ALLOWED_HOSTS 可能會失效,導致網站無法正常運行,因為 Django 會拒絕來自新 IP 的請求。

如何避免暴露伺服器的 IP?

1️⃣ 使用網域名稱,而非直接使用 IP

最佳做法是 使用網域名稱 來設定 ALLOWED_HOSTS,而不是直接填入 IP。例如:

# ✅ 只允許透過域名存取
ALLOWED_HOSTS = ['mywebsite.com', 'www.mywebsite.com']

這樣即使你的伺服器 IP 變更了,只要你的 網域 DNS 指向最新的 IP,Django 就可以繼續運行,而不需要手動修改 settings.py

如何設定?

  1. 購買網域 (例如 mywebsite.com)。
  2. 設定 DNS 解析,將 mywebsite.com 指向你的 GCP VM 公網 IP。
  3. 確認 ALLOWED_HOSTS 只包含你的域名,避免直接使用 IP。

2️⃣ 透過反向代理 (Nginx) 隱藏後端 IP

如果你希望避免伺服器 IP 直接暴露在網路上,你可以使用 Nginx 作為反向代理,讓 Django 只能接受來自 Nginx 的請求,而不是來自外部的 IP 直接存取。

步驟

  1. 在 Nginx 設定 server_name,只允許特定網域存取
server {
    listen 80;
    server_name mywebsite.com www.mywebsite.com;

    location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_set_header Host $host;
    }
}
  1. 在 Django 設定 ALLOWED_HOSTS,確保只接受來自正確的網域
ALLOWED_HOSTS = ['mywebsite.com', 'www.mywebsite.com']
  1. 封鎖對 Django 內部服務 (Gunicorn) 的直接存取
    • 透過 防火牆 (iptables/GCP Firewall Rules) 限制 Django 只接受來自 Nginx (127.0.0.1) 的請求。

這樣,所有外部請求都必須透過 Nginx 來存取 Django,攻擊者無法直接用 IP 存取 Django 伺服器。

3️⃣ 使用環境變數來管理 ALLOWED_HOSTS

如果你的 Django 應用部署在 多個環境 (如開發環境、測試環境、正式環境),而且你不想手動修改 settings.py,你可以使用 環境變數 來動態設定 ALLOWED_HOSTS

這樣即使你的伺服器 IP 或域名變更了,你只需要修改環境變數即可。

步驟

  1. settings.py 讀取環境變數
import os 
ALLOWED_HOSTS = os.getenv('DJANGO_ALLOWED_HOSTS', '').split(',')
  1. .envdocker-compose.yml 設定環境變數
DJANGO_ALLOWED_HOSTS=mywebsite.com,www.mywebsite.com
  1. 在 Docker 或雲端環境載入環境變數
version: '3'
services:
  web:
    image: my-django-app
    env_file:
      - .env

這樣,你的 ALLOWED_HOSTS 會根據 .env 設定動態變更,而不需要修改程式碼。


總結

錯誤做法風險正確做法
ALLOWED_HOSTS = ['https://example.com']Django 無法匹配 Host,導致 400 錯誤ALLOWED_HOSTS = ['example.com']
ALLOWED_HOSTS = ['34.123.45.67']伺服器 IP 直接暴露,易受攻擊ALLOWED_HOSTS = ['mywebsite.com']
在 settings.py 硬編碼 ALLOWED_HOSTS變更時需要修改程式碼,難以維護使用環境變數 (os.getenv())
  • ✅ 不要在 ALLOWED_HOSTS 中包含 http://https://,只填入主機名稱 (域名或 IP)。
  • ✅ 使用 DNS 解析,避免直接暴露伺服器 IP。
  • ✅ 搭配 Nginx 作為反向代理,隱藏後端伺服器 IP,提升安全性。
  • ✅ 透過環境變數設定 ALLOWED_HOSTS,提升靈活性,避免硬編碼帶來的問題。

透過這些最佳實踐,你可以讓 Django 應用更安全、更靈活,避免潛在的攻擊與運維風險!🚀

在 GCP 搭配 Docker Compose 執行 Django

如果你使用 Google Cloud Platform (GCP) 部署 Django,且透過 Docker Compose 運行,建議透過 環境變數 設定 ALLOWED_HOSTS,確保靈活性與安全性。

設定方式

  1. 建立 .env 檔案 DJANGO_ALLOWED_HOSTS=mywebsite.com,www.mywebsite.com
  2. docker-compose.yml 中載入環境變數 version: '3' services: web: image: my-django-app env_file: - .env
  3. settings.py 中讀取環境變數 import os ALLOWED_HOSTS = os.getenv('DJANGO_ALLOWED_HOSTS', '').split(',')

這樣,你可以透過 .env 來動態調整 ALLOWED_HOSTS,而不需要修改 settings.py 內的程式碼。


GCP VM 上如何正確設定 ALLOWED_HOSTS?

如果你的 Django 應用是直接部署在 GCP VM 上,而非透過 Docker,可以透過 域名 來管理 ALLOWED_HOSTS

步驟

  1. 在 GCP 設定靜態 IP
    • 確保 GCP VM 有一個固定的外部 IP,然後將該 IP 綁定至網域。
  2. 設定 DNS 解析
    • Cloud DNS 或第三方 DNS 供應商(如 Cloudflare)中,將 mywebsite.com 指向 GCP VM 的靜態 IP。
  3. settings.py 中使用域名 ALLOWED_HOSTS = ['mywebsite.com', 'www.mywebsite.com']

避免常見錯誤

  • 不要在 ALLOWED_HOSTS 中包含 http://https:// # ❌ 錯誤 ALLOWED_HOSTS = ['https://mywebsite.com'] # ✅ 正確 ALLOWED_HOSTS = ['mywebsite.com']
  • 若使用反向代理 (如 Nginx),確保轉發的 Host 不變
    • 在 Nginx 配置 proxy_set_header Host $host; 以確保 Django 能正確檢查 Host。

總結

  • ALLOWED_HOSTS 用來限制哪些 Host 可以存取 Django 應用,防止 HTTP Host Header 攻擊。
  • 盡量使用 網域名稱,而非直接使用 IP 地址,來降低風險。
  • 在 GCP 或 Docker 環境中,可以透過 環境變數 設定 ALLOWED_HOSTS,提高彈性與安全性。
  • 在 GCP VM 部署時,應設定 靜態 IP,並搭配 DNS 解析,確保域名解析正常運作。

希望這篇文章能幫助你更好地理解 ALLOWED_HOSTS 的作用與最佳設定方式,讓你的 Django 應用更安全!🚀

Similar Posts