bin/kc.[sh|bat] start --proxy-headers forwarded
分散式環境經常需要使用反向代理。Keycloak 提供多種選項來與此類環境安全整合。
Keycloak 將根據 proxy-headers
選項解析反向代理標頭,該選項接受多個值
預設情況下,如果未指定此選項,則不會解析任何反向代理標頭。
forwarded
啟用根據 RFC7239 解析 Forwarded
標頭。
xforwarded
啟用解析非標準的 X-Forwarded-*
標頭,例如 X-Forwarded-For
、X-Forwarded-Proto
、X-Forwarded-Host
和 X-Forwarded-Port
。
如果您使用反向代理進行除 https 直通之外的任何操作,並且未設定 proxy-headers 選項,則預設情況下,您會看到透過代理執行來源檢查的請求返回 403 Forbidden 回應。 |
例如
bin/kc.[sh|bat] start --proxy-headers forwarded
如果選擇 forwarded 或 xforwarded ,請確保您的反向代理正確設定並覆寫 Forwarded 或 X-Forwarded-* 標頭。若要設定這些標頭,請查閱您的反向代理的文件。錯誤的配置會讓 Keycloak 面臨安全漏洞。 |
請採取額外預防措施,確保用戶端位址透過 Forwarded
或 X-Forwarded-For
標頭由您的反向代理正確設定。如果此標頭配置不正確,惡意用戶端可以設定此標頭,並欺騙 Keycloak 認為用戶端是從與實際位址不同的 IP 位址連線的。如果您對 IP 位址進行任何拒絕或允許列表,此預防措施可能更為重要。
當使用 xforwarded 設定時,X-Forwarded-Port 的優先順序高於 X-Forwarded-Host 中包含的任何連接埠。 |
如果 TLS 連線在反向代理 (邊緣終止) 處終止,則需要透過「http-enabled」設定啟用 HTTP。 |
Keycloak 假設它是透過與 Keycloak 配置相同的上下文路徑透過反向代理公開的。預設情況下,Keycloak 是透過根目錄 (/
) 公開的,這表示它也希望透過反向代理在 /
上公開。您可以在這些情況下使用完整 URL 作為 hostname
選項,例如,如果 Keycloak 是透過反向代理在 /auth
上公開,則使用 --hostname=https://my.keycloak.org/auth
。
如需在不同的主機名稱或上下文路徑上公開 Keycloak (包括管理 REST API 和主控台) 的更多詳細資訊,請參閱 配置主機名稱 (v2)。
或者,您也可以使用 http-relative-path
選項來變更 Keycloak 本身的上下文路徑,以符合反向代理的上下文路徑,這會變更 Keycloak 本身的上下文路徑,以符合反向代理使用的上下文路徑。
典型的叢集部署包含負載平衡器 (反向代理) 和私有網路上的 2 個或多個 Keycloak 伺服器。為了效能,如果負載平衡器將與特定瀏覽器連線相關的所有請求轉送至相同的 Keycloak 後端節點,可能會很有用。
原因是,Keycloak 使用 Infinispan 分散式快取在底層儲存與目前驗證連線和使用者連線相關的資料。Infinispan 分散式快取的配置限制了擁有者的數量。這表示連線相關資料僅儲存在某些叢集節點中,如果其他節點想要存取這些資料,則需要遠端查找這些資料。
例如,如果 ID 為 123 的驗證連線儲存在 node1 上的 Infinispan 快取中,然後 node2 需要查找此連線,則需要透過網路將請求傳送至 node1,以傳回特定的連線實體。
如果特定的連線實體始終在本機可用會很有利,這可以藉由黏性連線來完成。在具有公用前端負載平衡器和兩個後端 Keycloak 節點的叢集環境中的工作流程可以是這樣
使用者傳送初始請求以查看 Keycloak 登入畫面
此請求由前端負載平衡器處理,該負載平衡器將其轉送至某些隨機節點 (例如,node1)。嚴格來說,該節點不必是隨機的,但可以根據其他一些條件 (用戶端 IP 位址等) 選擇。這一切都取決於基礎負載平衡器 (反向代理) 的實作和配置。
Keycloak 建立具有隨機 ID (例如,123) 的驗證連線,並將其儲存至 Infinispan 快取。
Infinispan 分散式快取根據連線 ID 的雜湊值指派連線的主要擁有者。如需更多相關詳細資訊,請參閱 Infinispan 文件。我們假設 Infinispan 指派 node2 為此連線的擁有者。
Keycloak 建立格式為 <連線 ID>.<擁有者節點 ID> 的 Cookie AUTH_SESSION_ID。在我們的範例中,它將是 123.node2 。
回應會與 Keycloak 登入畫面和瀏覽器中的 AUTH_SESSION_ID Cookie 一起傳回給使用者
從這一點開始,如果負載平衡器將所有後續請求轉送至 node2 會很有利,因為此節點是 ID 為 123 的驗證連線的擁有者,因此 Infinispan 可以在本機查找此連線。驗證完成後,驗證連線會轉換為使用者連線,使用者連線也會儲存在 node2 上,因為它具有相同的 ID 123。
黏性連線對於叢集設定不是強制性的,但是由於上述原因,它對於效能有益。您需要將負載平衡器配置為透過 AUTH_SESSION_ID Cookie 進行黏性連線。具體如何執行此操作取決於您的負載平衡器。
如果您的代理支援連線親和性而不處理來自後端節點的 Cookie,則應將 spi-sticky-session-encoder-infinispan-should-attach-route
選項設定為 false
,以避免將節點附加至 Cookie,而僅依賴反向代理的功能。
bin/kc.[sh|bat] start --spi-sticky-session-encoder-infinispan-should-attach-route=false
預設情況下,spi-sticky-session-encoder-infinispan-should-attach-route
選項值為 true
,以便將節點名稱附加至 Cookie,以向反向代理指示應將後續請求傳送至的節點。
使用反向代理時,Keycloak 只需要公開某些路徑。下表顯示了建議公開的路徑。
Keycloak 路徑 | 反向代理路徑 | 已公開 | 原因 |
---|---|---|---|
/ |
- |
否 |
公開所有路徑時,會不必要地公開管理路徑。 |
/admin/ |
- |
否 |
公開的管理路徑會導致不必要的攻擊向量。 |
/realms/ |
/realms/ |
是 |
此路徑是正確運作所必需的,例如,對於 OIDC 端點。 |
/resources/ |
/resources/ |
是 |
此路徑是正確提供資產所必需的。它可以從 CDN (而不是 Keycloak 路徑) 提供。 |
/robots.txt |
/robots.txt |
是 |
搜尋引擎規則 |
/metrics |
- |
否 |
公開的指標會導致不必要的攻擊向量。 |
/health |
- |
否 |
公開的健康檢查會導致不必要的攻擊向量。 |
我們假設您在反向代理/閘道的公用 API 上的根路徑 /
上執行 Keycloak。如果不是,請使用您想要的路徑作為前綴。
為了確保僅從您信任的代理使用代理標頭,請將 proxy-trusted-addresses
選項設定為以逗號分隔的 IP 位址 (IPv4 或 IPv6) 或無類別網域間路由 (CIDR) 表示法清單。
例如
bin/kc.[sh|bat] start --proxy-headers forwarded --proxy-trusted-addresses=192.168.0.32,127.0.0.0/8
proxy-protocol-enabled
選項控制伺服器是否應在為來自代理後方的請求提供服務時使用 HA PROXY 通訊協定。當設定為 true 時,返回的遠端位址將是來自實際連線用戶端的位址。
當在相容的 https 直通代理後方執行時,這非常有用,因為無法操作請求標頭。
例如
bin/kc.[sh|bat] start --proxy-protocol-enabled true
當代理配置為 TLS 終止代理時,用戶端憑證資訊可以透過特定的 HTTP 請求標頭轉送至伺服器,然後用於驗證用戶端。您可以根據您使用的代理配置伺服器如何擷取用戶端憑證資訊。
伺服器支援一些最常見的 TLS 終止代理,例如
代理 | 提供者 |
---|---|
Apache HTTP 伺服器 |
apache |
HAProxy |
haproxy |
NGINX |
nginx |
若要設定如何從請求擷取用戶端憑證,您需要
bin/kc.[sh|bat] build --spi-x509cert-lookup-provider=<provider>
bin/kc.[sh|bat] start --spi-x509cert-lookup-<provider>-ssl-client-cert=SSL_CLIENT_CERT --spi-x509cert-lookup-<provider>-ssl-cert-chain-prefix=CERT_CHAIN --spi-x509cert-lookup-<provider>-certificate-chain-length=10
設定 HTTP 標頭時,您需要確保您使用的值與代理使用用戶端憑證資訊轉送的標頭名稱相對應。
用於設定提供者的可用選項包括
選項 | 描述 |
---|---|
ssl-client-cert |
包含用戶端憑證的標頭名稱 |
ssl-cert-chain-prefix |
包含鏈中其他憑證的標頭前綴,並根據鏈的長度用於擷取個別憑證。例如,值 |
certificate-chain-length |
憑證鏈的最大長度。 |
trust-proxy-verification |
啟用信任 NGINX 代理憑證驗證,而不是將憑證轉送至 Keycloak 並在 Keycloak 中驗證。 |
NGINX SSL/TLS 模組不會公開用戶端憑證鏈。Keycloak 的 NGINX 憑證查找提供者會使用 Keycloak 信任儲存庫重建憑證鏈。
如果您使用此提供者,請參閱 配置信任的憑證,了解如何配置 Keycloak 信任儲存庫。
值 | |
---|---|
僅當啟用 hostname:v2 功能時可用 |
|
僅當啟用 hostname:v2 功能時可用 |
|
|
(預設) |
|
|
|
|
|