如何為分散式系統設計一種安全架構

2024.09.30

由於涉及多種多樣的大規模組件,保護分散式系統是一項複雜的挑戰。鑑於多個服務在可能不安全的網路上交互,未經授權的存取和資料外洩的風險顯著增加。本文探討了一種使用開源專案來保護分散式系統的實用方法,該專案示範如何整合幾種安全機制和技術來應對常見的安全挑戰,例如身分驗證、授權和安全通訊。

理解分散式系統中的安全挑戰

分散式系統涉及多個服務或微服務,這些服務或微服務必須透過網路安全地通訊。這類架構中的主要安全挑戰包括:

1.安全通訊:確保服務之間傳輸的資料經過加密、安全可靠,以免被竊聽或竄改。

2. 身份驗證:驗證使用者和服務的身份,防止未授權存取。

3.授權:根據身份已驗證的使用者和服務的角色和權限,控制允許使用者和服務執行的操作。

4.策略執行:實施管理服務到服務和使用者互動的細粒度存取控制和策略。

5.憑證管理:管理用於加密資料、建立服務之間信任的數位憑證。

這個開源專案使用幾種整合的技術和解決方案來克服這些挑戰。

項目設定和配置

這個專案先使用shell腳本和Docker建立一個安全的環境。設定需要提供數位證書和啟動必要的服務,以確保所有組件都準備好進行安全通訊。

設定環境的步驟

1.提供證書

本專案使用shell腳本(provisioning.sh )以模擬憑證授權單位(CA ),並為服務產生必要的憑證。


./provisioning.sh

2.啟動服務

Docker Compose用於啟動專案中定義的所有服務,確保它們被正確配置以實現安全運行。


docker-compose up

3.測試服務到服務通信

為了使用憑證和JWT令牌驗證服務到服務通信,提供test_services.sh腳本。該腳本演示了不同的服務如何使用分配給它們的憑證安全地互動。

解決分散式系統中的安全挑戰

該專案整合了幾項關鍵技術來解決前面提到的主要安全挑戰。以下是應對每個挑戰的方法:

1.使用相互TLS (mTLS )的安全通信

挑戰

在分散式系統中,服務必須安全地通信,以防止未經授權的存取和資料外洩。

解決方案

此專案使用相互TLS (mTLS )來保護服務之間的通訊。mTLS確保客戶端和伺服器都使用各自的憑證對彼此進行身份驗證。這種相互驗證可以防止未經授權的服務與合法服務進行通訊。

實施

Nginx被設定為反向代理來處理mTLS。它需要客戶端憑證和伺服器憑證來建立安全連接,確保服務之間傳輸的資料保持機密和防篡改。

2. 使用Keycloak的身份驗證

挑戰

正確地驗證使用者和服務的身份對於防止未經授權的存取至關重要。

解決方案

此專案利用開源身分和存取管理解決方案Keycloak來管理身分驗證。 Keycloak支援多種身份驗證方法,包括OpenID Connect和用戶端憑證,既適合使用者身份驗證,也適合服務身份驗證。

  • 使用者身份驗證:

使用OpenID Connect對使用者進行身份驗證。 Keycloak配置了用戶端(appTest-login-client ),該用戶端處理使用者驗證流,包括登入、令牌頒發和回調處理。

  • 服務身份驗證:

針對服務到服務的驗證,專案使用為客戶端憑證授予類型配置的Keycloak客戶端(client_credentials-test )。這種方法非常適合在沒有使用者乾預的情況下對服務進行身份驗證。

身份驗證流程範例

  • 使用者導航到登入頁面。
  • 成功登入後,Keycloak將使用者重新導向到具有授權碼的回呼頁面。
  • 然後將授權碼交換為JWT令牌,用於後續請求。 nginx/njs目錄中的auth n .js檔案提供了該流程的詳細實作。

使用用戶端憑證的服務驗證範例

curl -X POST "http://localhost:9000/realms/tenantA/protocol/openid-connect/token" \
 -H "Content-Type: application/x-www-form-urlencoded" \
 -d "grant_type=client_credentials" \
 -d "client_id=client_credentials-test" \
 -d "client_secret=your-client-secret-here"

3. 使用開放策略代理程式(OPA )和JWT的使用者授權

挑戰

實施細粒度的存取控制,以確保已驗證的使用者和服務只能存取授權的資源。

解決方案

此專案結合使用開放策略代理(OPA )和JWT令牌來執行授權策略。本專案示範了三種不同的JWT驗證策略,以確保可靠的安全性:

  • 從Keycloak取得憑證:從Keycloak動態取得憑證以驗證代幣。
  • 使用x5t (拇指紋):使用令牌中嵌入的拇指紋,從本機信任儲存中檢索公鑰。
  • 嵌入式憑證驗證:使用嵌入式憑證驗證令牌,確保對照受信任的憑證授權單位(CA )驗證憑證。

有關這些策略的詳細實施,請參閱nginx/njs/token.js檔案:https://github.com/apssouza22/security-architecture/blob/main/nginx/njs/token.js。

4. 使用開放策略代理程式(OPA )的策略執行

挑戰

為服務和使用者實施動態且靈活的存取控制策略。

解決方案

OPA用於實施細粒度的存取控制策略。策略以聲明性語言(Rego )加以編寫,儲存在opa/目錄中。這些策略規定了服務可以通訊、使用者可以存取資源的條件,確保在整個系統中一致地運用存取控制。

5. 證書管理

挑戰

管理服務的數位證書,以建立信任和安全通訊。

解決方案:

該項目包括一個強大的證書管理系統。 shell腳本(provisioning.sh )用於模擬憑證授權單位(CA ),並為每個服務產生憑證。這種方法簡化了憑證管理,並確保所有服務都擁有安全通訊所需的憑證。

我們也新增了一個端點來更新服務證書,不需要重新啟動nginx。

curl --insecure https://localhost/certs --cert certificates/gen/serviceA/client.crt --key certificates/gen/serviceA/client.key -F cert=@certificates/gen/serviceA/client.crt -F key=@certificates/gen/serviceA/client.key

結論

建置安全的分散式系統需要仔細考慮各個安全性方面,包括安全通訊、身分驗證、授權、策略執行和憑證管理。這個開源專案提供了一個全面的範例,顯示如何整合多種安全機制來有效地應對這些挑戰。

如果遵循本專案中示範的設定和配置,開發人員就可以利用相互TLS、Keycloak、Open Policy Agent和Nginx來建立一套穩健的安全架構。這些技術結合在一起,就可以為保護分散式系統免受各種威脅提供堅實的基礎,確保資料保護和安全存取控制。

原文標題:Designing a Secure Architecture for Distributed Systems,作者:Alexsandro Souza