SSD Nodes Learn Hosting plans →
指南 Matt Connor作者: Matt Connor · 已更新 2026-08-30

Ollama API 沒有密碼,如何安全防護?

Ollama 預設沒有驗證機制,任何能連到 11434 埠的來源都能執行模型、下載 2 到 40 GB 模型,本文依序說明 3 種修正方法。

Ollama API 沒有密碼

Ollama API 沒有驗證機制。您執行的伺服器中沒有使用者、密碼、金鑰檢查或任何允許清單。任何能建立 TCP 連線至 11434 埠的來源,都能列出您的模型、執行模型、下載新模型,以及刪除現有模型。

官方文件明確說明:「透過 http://localhost:11434 從本機存取 Ollama API 時,不需要驗證。」其中的「本機」一詞涵蓋了完整的安全模型。Ollama 預設繫結至 127.0.0.1,因此在筆記型電腦上,loopback 介面就是存取控制。若將監聽位址改為公開位址,存取控制就會消失,因為沒有其他機制取代它。

這就是 VPS(virtual private server)環境中必須注意此問題的原因。預設設定是安全的。多數人進行的第一項變更,是開放監聽器,讓第二台機器使用模型;但這項變更會一次移除所有防護。

開放連接埠 11434 會暴露哪些資訊

所有端點都可存取。沒有唯讀模式,也沒有獨立的管理連接埠。以下是真實的請求,目標是伺服器位址,而不是 localhost:

# List every model on the box
curl http://SERVER_IP:11434/api/tags

# See what is loaded into memory right now
curl http://SERVER_IP:11434/api/ps

# Run a prompt on your hardware
curl http://SERVER_IP:11434/api/generate -d '{"model":"llama3.2","prompt":"Why is the sky blue?"}'

# Write several gigabytes to your disk
curl http://SERVER_IP:11434/api/pull -d '{"model":"llama3.2"}'

# Remove a model
curl -X DELETE http://SERVER_IP:11434/api/delete -d '{"model":"llama3.2"}'

以管理者的角度來看,會發生 4 個問題:

  • 您的 CPU 或 GPU 會替他人執行推論。若方案提供有限度使用的 CPU 額度,持續負載就代表陌生人正在消耗您的額度;當您不再是唯一的呼叫端時,控制 VPS 上的 AI 工作負載成本會更加困難。
  • /api/pull 會將模型寫入您的磁碟。每個模型大小介於 2 到 40 gigabytes。反覆執行 pull 會填滿磁碟區;磁碟滿了之後,伺服器上的其他服務也會故障,不只 Ollama 受影響。
  • 請求會進入您的程序並寫入日誌。在預設日誌層級下,Ollama 只會記錄中繼資料,因此您會取得端點、狀態、延遲時間與用戶端位址,而不會取得提示文字。但這仍會在您的 journal 中留下誰使用伺服器及其用途的紀錄,而您並未選擇收集這些資料。
  • /api/delete 會移除模型。要恢復模型,必須再次使用您自己的頻寬下載。

這些行為都不需要利用漏洞。這只是文件所述的 API 按照設計正常運作。

Ed25519 金鑰不是存取控制

搜尋「Ollama API key」時,會看到兩種不同的項目。兩者都不是伺服器的密碼。釐清兩者的差異,就能排除大部分混淆。

第一種是身分金鑰組。 Ollama 第一次執行時會產生 Ed25519 金鑰組。在 Linux 上,安裝指令碼會建立名為 ollama 的系統使用者,並將其家目錄設為 /usr/share/ollama,因此金鑰組會儲存在:

/usr/share/ollama/.ollama/id_ed25519
/usr/share/ollama/.ollama/id_ed25519.pub

這組金鑰用於對外驗證。ollama signin 會將公開金鑰註冊到您的 ollama.com 帳戶,並用它授權您將模型推送至 registry,或拉取私有模型。它會向 ollama.com 證明您的機器身分,但不會要求連線到您機器的用戶端提供任何資訊。刪除、輪替或完全不建立這組金鑰,都不會改變哪些用戶端可以呼叫您的 API。

第二種是 OLLAMA_API_KEY 該變數會儲存您在 https://ollama.com/settings/keys 建立的金鑰。用戶端呼叫位於 https://ollama.com/api 的代管 API 時,會將它作為 Authorization: Bearer $OLLAMA_API_KEY 傳送。這是對方服務使用的認證資訊,您是以用戶端身分使用它。您自己的 ollama serve 不會讀取它。在 VPS 上設定 OLLAMA_API_KEY,不會為 VPS 設定密碼。

因此,沒有需要啟用的設定。以下 3 種防護方式的原則都相同:讓連接埠無法連線,並在前方放置確實執行驗證的元件。

確認伺服器目前正在監聽的項目

sudo ss -tlnp | grep 11434

安全的結果會列出迴路位址:

LISTEN 0  4096  127.0.0.1:11434  0.0.0.0:*  users:(("ollama",pid=812,fd=3))

暴露的結果會列出每個網路介面:

LISTEN 0  4096  0.0.0.0:11434  0.0.0.0:*  users:(("ollama",pid=812,fd=3))

0.0.0.0 表示主機上的所有 IPv4 位址,包括公開位址。*:11434[::]:11434 則表示包含 IPv6 的相同範圍。

現在從外部確認。請在筆記型電腦上執行,而不是在伺服器上執行:

curl -m 5 http://YOUR_SERVER_IP:11434/api/version

curl: (28) Connection timed out after 5001 milliseconds 是你要的結果,curl: (7) Failed to connect ... Connection refused 也是。包含 version 欄位的 JSON 物件表示任何提出請求的人都能存取完整 API。在伺服器本身使用 curl 測試無法證明任何事,因為迴路介面一定會回應。

服務通常會透過兩種方式暴露。第一種是刻意修改設定,因為有人需要讓另一台機器存取模型:

sudo systemctl edit ollama.service
[Service]
Environment="OLLAMA_HOST=0.0.0.0:11434"

這一行就是造成暴露的全部設定。第二種方式是 Docker,完全不需要你編輯任何內容。這部分會在下方的專節說明。

防禦 1:維持 localhost 綁定,透過 tunnel 連入

先採用這個方法。它不需要安裝新軟體,也不會建立可能外洩的憑證。連接埠從未存在於公開介面上,因此掃描無法找到它。

明確設定 bind address,不要依賴預設值:

sudo systemctl edit ollama.service
[Service]
Environment="OLLAMA_HOST=127.0.0.1:11434"

這會寫入 /etc/systemd/system/ollama.service.d/override.conf。套用設定並檢查:

sudo systemctl daemon-reload
sudo systemctl restart ollama
sudo ss -tlnp | grep 11434

ss 現在應顯示 127.0.0.1:11434。如果仍顯示 0.0.0.0,表示另一個 drop-in 檔案優先套用。執行 systemctl cat ollama.service,列出該 unit 及所有 drop-in 檔案與其路徑,然後刪除過時的檔案。

若要從筆記型電腦使用該模型,請透過 SSH 轉送連接埠:

ssh -N -L 11434:127.0.0.1:11434 you@your-server

-L 11434:127.0.0.1:11434 會在筆記型電腦上開啟連接埠 11434,並將送達該連接埠的所有內容轉送至伺服器上看到的 127.0.0.1:11434-N 會告訴 SSH 不要執行遠端命令,因此該程序只會維持 tunnel 開啟。tunnel 執行期間,您可以在筆記型電腦上使用:

curl -s http://localhost:11434/api/tags

您會遇到兩種失敗情況。bind [127.0.0.1]:11434: Address already in use 表示筆記型電腦上的 Ollama 已使用該連接埠,因此請使用 -L 11500:127.0.0.1:11434 選擇其他本機連接埠,並將用戶端指向 11500。若 tunnel 已成功建立,但收到空回應,表示 SSH 正常運作,而 Ollama 未在伺服器端監聽;請先在伺服器上檢查 ss,再修改 SSH 命令。

若有多台用戶端機器,使用私有網路比為每個人建立一條 tunnel 更合適。讓這些機器加入 WireGuard 或 Tailscale,然後將 Ollama 綁定至該網路上的位址,而不是 0.0.0.0

[Service]
Environment="OLLAMA_HOST=10.8.0.1:11434"

如此一來,連接埠只會存在於必須使用憑證才能加入的介面上。即使防火牆設定錯誤,這種方式仍能避免暴露,因為公開介面沒有該監聽服務,允許所有來源的規則也無法公開它。

防禦 2:檢查 bearer token 的反向代理

當公開網際網路上的服務必須呼叫模型時,請讓 Ollama 保持監聽 loopback,並在前方配置代理。代理負責終止 TLS(transport layer security),並拒絕缺少正確標頭的請求。Ollama 仍只接受來自 127.0.0.1 的連線,因此代理是唯一的進入路徑。

先產生真正的 token。不要手動虛構:

openssl rand -base64 36

以下是會檢查該 token 的 nginx site:

map $http_authorization $ollama_ok {
    default                                   0;
    "Bearer PASTE_YOUR_GENERATED_TOKEN_HERE"  1;
}

server {
    listen 443 ssl;
    server_name llm.example.com;

    ssl_certificate     /etc/letsencrypt/live/llm.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/llm.example.com/privkey.pem;

    location = /api/pull   { return 403; }
    location = /api/delete { return 403; }
    location = /api/push   { return 403; }

    location / {
        if ($ollama_ok = 0) { return 401; }

        proxy_pass http://127.0.0.1:11434;
        proxy_set_header Host 127.0.0.1:11434;
        proxy_buffering off;
        proxy_read_timeout 600s;
    }
}

這裡有 5 行真正發揮作用的設定,每一行都能避免一個否則會遇到的故障。

在 nginx 中,if 放在 location 區塊內通常不是好做法。不過,內容恰好為 return 是兩種行為可預期的形式之一,因此這種用法是安全的。

location = /api/pull 是精確比對。nginx 對精確比對的優先級高於 location / 前綴,因此這 3 個端點會在檢查 token 前先遭到拒絕。有效 token 只能取得推論權限,不能讓人填滿你的磁碟。

proxy_set_header Host 127.0.0.1:11434; 很重要,因為 Ollama 會檢查傳入的 HostOrigin 標頭。直接轉送代理的公開主機名稱,可能產生由 Ollama 而非 nginx 提供的 403 Forbidden,會增加除錯困難。OLLAMA_ORIGINS 是另一個控制項,適用於需要允許特定來源的瀏覽器用戶端。

proxy_buffering off; 很重要,因為 Ollama 會逐一串流回應 token。啟用緩衝時,nginx 會保留整個串流,直到生成結束才一次送出,因此用戶端在整個生成期間看起來都像是沒有回應。

proxy_read_timeout 600s; 很重要,因為 nginx 的預設值是 60 秒。CPU 上的長時間生成很容易超過這個時間,用戶端會收到 504 Gateway Time-out,而 /var/log/nginx/error.log 會記錄 upstream timed out (110: Connection timed out) while reading response header from upstream。請求其實仍在處理中,只是 nginx 放棄等待。

重新載入並測試兩條路徑:

sudo nginx -t && sudo systemctl reload nginx
curl -s -o /dev/null -w '%{http_code}\n' https://llm.example.com/api/tags
curl -s -H "Authorization: Bearer YOUR_TOKEN" https://llm.example.com/api/tags

第一個命令應輸出 401。第二個命令應輸出你的模型清單。如果第一個命令也回傳模型清單,表示 map 區塊位於錯誤的範圍。它應位於 http 層級,因此請將它放在 /etc/nginx/conf.d/ 下的檔案中,或放在 server 區塊上方,絕對不要放在 server 內。

Caddy 只需 4 行即可透過基本驗證完成相同工作,對瀏覽器用戶端而言通常比 bearer token 更合適:

llm.example.com {
	basic_auth {
		apiuser PASTE_BCRYPT_HASH_HERE
	}
	reverse_proxy 127.0.0.1:11434
}

執行 caddy hash-password 以產生它所需的 bcrypt 雜湊值。有一個命名陷阱:在 Caddy v2.8 之前,該指示詞是 basicauth;現在則是 basic_auth。因此,從舊版指南複製的設定會無法載入,且 Caddy 會指出它無法辨識的指示詞。

無論選擇哪個代理,這都是所有人共用的一組 secret。持有它的每個用戶端都擁有完全相同的存取權。撤銷它代表必須修改設定,並同時更新所有呼叫端。

防禦 3:依用戶端簽發金鑰的閘道

當不只一個人員或應用程式呼叫模型時,共用 token 很快就不敷使用。你無法判斷是哪個用戶端造成負載,也無法在不影響其他用戶端的情況下停用其中一個。閘道位於原本代理的位置,使用相同的 OpenAI 相容 API,為每個用戶端簽發個別金鑰,並記錄各金鑰的使用情況。自行託管的 LiteLLM 閘道 是通常的做法,除了存取控制之外,還能提供每個金鑰的預算與請求日誌。

防禦 1 的規則不變。Ollama 綁定至 127.0.0.1,只有閘道程序會與它通訊,且只有閘道服務對外監聽。如果某台主機的 11434 埠仍對全世界開放,閘道就只是裝飾,因為呼叫端可以直接繞過它。

防火牆陷阱:發布的容器連接埠會繞過 UFW

這就是為什麼伺服器擁有者明明正確設定防火牆,伺服器上仍會出現暴露的服務。

UFW(uncomplicated firewall)會將規則寫入核心的 filter 表格中的 INPUT 鏈,而 INPUT 會處理目的地是主機本身的封包。Docker 的 -p 旗標會將目的地 NAT(network address translation)規則寫入 nat 表格中的 PREROUTING 鏈。核心會在決定封包傳送位置前先評估這項規則。路由決策發生時,目的地已經改寫為容器的位址,因此封包會被轉送,而不是在本機交付;它會通過 FORWARD,而不是 INPUT。UFW 的 INPUT 規則完全不會被查詢,因此封包會繞過防火牆,而不是通過防火牆。

因此,以下指令序列會讓連接埠 11434 對網際網路開放:

sudo ufw default deny incoming
sudo ufw enable
docker run -d -v ollama:/root/.ollama -p 11434:11434 --name ollama ollama/ollama

sudo ufw status 仍會顯示防火牆已啟用,且預設政策為拒絕。這兩個結果可以同時正確,正是人們誤信其中一個結果的原因。你可以查看造成這項結果的規則:

sudo iptables -t nat -L DOCKER -n

修正方式是在發布旗標中指定一個位址:

docker rm -f ollama
docker run -d -v ollama:/root/.ollama -p 127.0.0.1:11434:11434 --name ollama ollama/ollama

-p 11434:11434-p 0.0.0.0:11434:11434 的簡寫。指定 127.0.0.1 會將對應的主機端綁定至 loopback,因此 SSH tunnel 和反向代理仍可連線,而網際網路無法連線。重新建立容器在這裡是安全的,因為模型儲存在具名的 ollama volume 中,而不是容器內。

確認兩種檢視結果一致:

docker port ollama
sudo ss -tlnp | grep 11434

docker port ollama 應輸出 11434/tcp -> 127.0.0.1:11434。如果輸出 0.0.0.0:11434,表示服務仍然暴露在外。了解一次這個機制後,所有發布的容器都適用:Docker 發布的連接埠為何會繞過 UFW 說明 DOCKER-USER 鏈,以及 Docker 重新啟動後仍會保留的規則。如果你仍在建立主機本身的政策,新 VPS 需要的 UFW 規則 說明這項設定所依據的基礎政策。在 Rocky 或 AlmaLinux 上沒有可設定的 UFW,因此應從以 firewalld 撰寫的相同基礎政策開始。

程序以哪個帳號執行

Linux 安裝指令碼會建立專用帳號,並以該帳號執行服務:

useradd -r -s /bin/false -U -m -d /usr/share/ollama ollama

/etc/systemd/system/ollama.service 中的 unit 會設定 User=ollamaGroup=ollama。請不要修改這些設定。在終端機中手動執行的簡單 ollama serve,會以目前登入帳號的身分執行。如果該帳號是 root,未經驗證的 API 就會以 root 身分寫入檔案。請確認目前的執行身分:

ps -o user= -C ollama

結果應為 ollama。其他結果都表示有手動啟動的程序與該 unit 並行執行,或取代了該 unit。之後新增任何 daemon 時,也應採用相同的檢查方式;以最小權限使用者執行服務 可正確落實這項原則。

如何檢查 Ollama API endpoint 是否安全

無論您採用哪種方式,都必須從另一台機器執行以下測試,才能確認結果:

curl -m 5 http://YOUR_SERVER_IP:11434/api/version
curl -m 5 http://YOUR_SERVER_IP:11434/api/tags

這兩個請求都應逾時或遭拒絕。如果您建立了 proxy,則對 proxy 主機名稱上的相同兩個路徑發出請求時,未提供認證應回傳 401,提供認證後則應回傳有效的 JSON。

接著讀取一次 access log,因為其中會顯示在埠開放期間是否有人發現該埠:

journalctl -u ollama --since "-30 days" | grep GIN | grep -v 127.0.0.1

Ollama 會為每個請求寫入一行,並包含用戶端位址:

[GIN] 2026/08/12 - 14:01:10 | 200 | 103.965898ms | 127.0.0.1 | POST "/api/generate"

Ollama 綁定至 loopback 後,每一行都應顯示一次 127.0.0.1,因為連線只能從這個位址進入。該欄位若出現公開位址,表示請求來自外部;時間戳記則會顯示請求發生的時間。這個命令完全沒有輸出,才是您要的結果。如果您不熟悉這部分的模型設定,請參閱在 VPS 上執行 Ollama,其中涵蓋安裝、模型大小,以及決定實際可載入內容的記憶體限制。

FAQ

Ollama 是否有 API key 或密碼?

沒有。您執行的伺服器完全沒有任何驗證機制,官方文件也說明,存取 API 不需要驗證。被稱為「Ollama API key」的兩種項目,其用途都不是驗證您自行執行的伺服器。/usr/share/ollama/.ollama/ 中的 Ed25519 金鑰組可向 ollama.com 證明您的機器身分,讓您推送模型及拉取私有模型。OLLAMA_API_KEY 是用戶端傳送至 https://ollama.com/api 託管 API 的憑證。您自己的 ollama serve 不會讀取這兩者,因此存取控制必須由網路或前端的代理伺服器提供。

如果我有防火牆,OLLAMA_HOST=0.0.0.0 是否安全?

只有在該主機上沒有其他程式寫入防火牆規則時才安全。0.0.0.0 表示監聽程式確實存在於公開介面上,而您只依賴防火牆阻止外部存取。Docker 發布連接埠後,這項信任就會失效,因為 Docker 加入 nat 表的 DNAT 規則,會在封包抵達 UFW 所使用的 INPUT 鏈之前先行套用。因此封包會被轉送,UFW 根本看不到它。繫結至 127.0.0.1 或私有通道位址,會將監聽程式從公開介面移除。如此一來,即使防火牆設定錯誤,也沒有可被暴露的監聽程式。

如何確認 Ollama 連接埠是否對網際網路開放?

在伺服器上執行 sudo ss -tlnp | grep 11434,再從另一台機器執行 curl -m 5 http://YOUR_SERVER_IP:11434/api/versionss 顯示 127.0.0.1:11434,且遠端 curl 逾時,就是您想看到的結果。若 ss 顯示 0.0.0.0:11434*:11434,而遠端 curl 回傳 JSON,表示完整 API 可被存取。不要在伺服器本身使用 curl 測試,因為迴路位址會回應實際繫結位址所提供的內容。

我可以直接將連接埠從 11434 改成隨機連接埠嗎?

不行,原因值得說明。改用其他連接埠,只能讓針對單一連接埠的掃描變慢。掃描器會掃描整個連接埠範圍,而對 /api/tags 發出的單一請求,就能辨識服務實際使用的連接埠。變更連接埠也會使所有用戶端的預設值失效,日後更難理解自己的設定。請改為繫結至迴路位址,這會移除監聽程式,而不是將它搬到其他位置。

有人連入我開放的 Ollama。我該檢查什麼?

先將它繫結至 127.0.0.1 並重新啟動服務,讓暴露狀態先停止,再開始調查。接著執行 journalctl -u ollama --since "-30 days" | grep GIN | grep -v 127.0.0.1,查看哪些外部位址在何時呼叫了哪些端點。將 ollama list 與您原本預期擁有的模型進行比對,因為 /api/pull 沒有驗證機制,而您未拉取的模型同時代表磁碟使用量與事件證據。使用 df -h 檢查可用空間。Ollama 在預設日誌層級不會記錄提示文字,因此您能掌握的是誰針對哪個模型提出要求,而不是系統產生了什麼內容。