為分佈式系統設計安全的架構

分佈式系統的保安是一個複雜的挑戰,因為涉及的组件種類多樣且數量庞大。由於多個服務在 potentially unsecured networks 上互動,未授權存取和數據洩漏的風險大幅增加。本文探讨了一個實際的方法,使用一個開源項目來保安分佈式系統。該項目示範了如何將多個保安機制和技術集成,以解決常见的保安挑戰,如驗證、授權和安全的通信。

了解分佈式系統中的保安挑戰

分佈式系統涉及多個服務或微型服務,必须在網絡上安全地互通。這種架構中的关键是保安挑戰包括:

  1. 安全通信:確保服務之間的傳輸數據被加密,並免受窃聽或篡改
  2. 驗證:驗證用戶和服務的身份,防止未經授權的存取
  3. 授權:控制已驗證的用戶和服務被允許做什么,基于他们的角色和权限
  4. 策略執行:实施细粒度的存取控制和策略,规范服务之间的互动和用户行为。
  5. 憑證管理 服務之間建立信任及对学生数据进行加密的数字凭證管理

這個開源計劃 透過數個集成技術和解決方案來解決這些挑戰。

計劃設定與配置

計劃從設定一個安全的環境開始,該環境透過 shell 腳本和 Docker 來建立。設定過程包括提供数字凭證並開始必要服務,確保所有組件都已準備好進行安全的通信。

設定環境步驟

1. 提供憑證

計劃使用一個 shell 腳本 (provisioning.sh) 來模擬憑證 authorities (CA) 並生成服務所需的必要憑證。

   ./provisioning.sh

2. 啟動服務

使用 Docker Compose 啟動計劃中定義的所有服務,確保它們被正確配置以進行安全的操作。

   docker-compose up

3. 測試服務之間的通信

服務之間的通信驗證使用憑證和JWT令牌,提供test_services.sh腳本。此腳本展示了不同服務如何使用其所分配的憑證安全地互動。

分布式系統中的安全性挑戰

该项目整合了若干关键技术以解決早先提到的主要安全风险。以下是對應每個挑戰的解決方案:

1. 使用相互TLS (mTLS)的 securely communication

挑戰

在分布式系統中,服務必須以安全方式互動,以防止未授權的存取和數據洩漏。

解決方案

该项目使用相互TLS (mTLS)來保安服務之間的通信。mTLS確保双方使用各自的憑證互相驗證。這種相互驗證防止未授權服務與 legit services 溝通。

實施

Nginx 已被設定作為反向代理以處理 mTLS。它需要客戶端和服务器证书來建立安全的連接,確保服務之間傳輸的數據保持機密並防篡改。

2. 使用 Keycloak 進行認證

挑戰

正確認證用戶和服務對於防止未授權訪問至關重要。

解決方案

该项目利用 Keycloak,一个开源的身份和访问管理解决方案,来管理认证。Keycloak 支持多种认证方法,包括 OpenID Connect 和客户端凭证,使其适用于用户和服务认证。

  • 用戶認證:
    用户通过 OpenID Connect 进行认证。Keycloak 与客户端 (appTest-login-client) 配置,处理用户认证流程,包括登录、令牌发放和回调处理。
  • 服務認證:
    对于服务间的认证,该项目使用了一个配置为客户端凭证授权类型的 Keycloak 客户端 (client_credentials-test)。这种方法非常适合于无需用户干预即可认证服务。

認證流程示例

  1. 用户转向登录页面。
  2. 成功登錄後,Keycloak將使用者重定向至回呼頁面並傳送一個授權碼。
  3. 接著,我們用這個授權碼來交換JWT憑證,此憑證將用於後續的請求。在nginx/njs 目錄中的authn.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. 使用 Open Policy Agent (OPA) 和 JWT 的使用者授權

挑戰

確保已登錄的使用者和服务只能夠存取授權的資源

解決方案

该项目使用Open Policy Agent (OPA)JWT凭證的组合来实施授权策略。该项目展示了三种不同的JWT验证策略以确保健壮的安全性:

  1. 从Keycloak获取证书:动态地从Keycloak获取证书以验证令牌。
  2. 使用x5t(拇指印):使用令牌中嵌入的拇指印从本地信任存储中获取公钥。
  3. 嵌入式憑證驗證:使用嵌入式憑證來驗證 tokens,確保憑證被驗證於可信的憑證授權機構(CA)。

請參考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

結論

建立一個安全的分布式系統需要仔細考慮各種安全方面,包括安全通信、身份驗證、授權、策略執行和憑證管理。這個開源項目提供了一個綜合示例,展示了如何整合多個安全機制以有效解決這些挑戰。

通過跟從這個項目中的設定和配置示例,開發者可以 lever mutual TLS、Keycloak、Open Policy Agent 和 Nginx 來建立一個強健的安全架構。這些技術結合在一起,為保護分布式系統免受各種威脅提供了堅實的基礎,同時確保了數據保護和安全的訪問控制。

Source:
https://dzone.com/articles/designing-a-secure-architecture-for-distributed-systems