iT邦幫忙

2025 iThome 鐵人賽

DAY 25
1
Cloud Native

從 Docker 到 K8s:我的 30 天雲原生筆記系列 第 25

Day 25: 服務間的雙向認證:啟用 mTLS

  • 分享至 

  • xImage
  •  

哈囉大家好,歡迎來到 Istio 的第三天!

在昨天的 Day 24,我們學會了如何使用 GatewayVirtualService管理從外部進入我們服務網格的流量。

在我們的 K8s 叢集內部,服務與服務之間的通訊,是安全的嗎?

預設情況下,Pod 之間的網路流量是明文傳輸的。如果叢集內部有任何節點被入侵,攻擊者就能輕易地竊聽或竄改服務之間的通訊內容。今天我們要為微服務通訊建立一道加密屏障 — mTLS (Mutual TLS)

Part 1:什麼是 mTLS?從「單向」到「雙向」的信任

我們都熟悉 TLS (或稱 SSL),也就是在瀏覽器中看到的「HTTPS」連線。這是一種單向認證

  • 你 (Client) 會驗證網站 (Server) 的憑證,確保你正在訪問的是真正的銀行網站,而不是一個釣魚網站。
  • 但網站不會反過來驗證你的身份(它只知道你的 IP 位址)。

mTLS 中的 m 代表 Mutual (雙向的)。在 mTLS 連線中:

  1. Client 必須驗證 Server 的身份。
  2. Server必須反過來驗證 Client 的身份。

這就像兩位特務接頭,不僅你要確認對方的暗號,對方也要確認你的暗號,雙方都驗證通過後,才能開始交換情報。這在零信任網路 (Zero Trust Network) 的安全模型中至關重要:我們不信任網路上的任何人,每一次通訊都必須經過嚴格的雙向身份驗證。

Sidecar 的魔法

最棒的是,這整個複雜的 TLS 憑證交換、加密、解密的過程,都由 Istio 自動地Sidecar Proxy 之間完成。我們的應用程式本身完全不需要修改任何程式碼,它依然是發送普通的 HTTP 請求,對 mTLS 的存在毫無感知。

Part 2:伺服器端的規則:PeerAuthentication

Istio 讓我們可以透過 PeerAuthentication 這個物件,來定義一個 Namespace 或特定服務,應該如何接收流量

官方文件定義:

PeerAuthentication defines how traffic will be tunneled (or not) to the sidecar.
(PeerAuthentication 定義了流量將如何(或是否)被通道化到 sidecar。)

PeerAuthentication 主要有兩種模式:

  • STRICT (嚴格模式)
    • 我的大門是上鎖的。只接受使用 mTLS 加密的、且身份驗證通過的連線。所有發往此服務的明文流量,都將被拒絕
  • PERMISSIVE (寬鬆模式)
    • 我的大門是開著的。如果對方使用 mTLS,我很樂意進行加密通訊;如果對方發送的是明文流量,我也會接受。

實戰範例:為 project-space 啟用嚴格模式

# peer-authentication.yaml
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: default
  namespace: project-space # 此規則作用於整個 project-space
spec:
  mtls:
    mode: STRICT

Part 3:客戶端的規則:DestinationRule

如果說 PeerAuthentication 是伺服器端的「接收規則」,那麼 DestinationRule 就是客戶端的「發送規則」。

DestinationRule 的功能非常多,但其中與 mTLS 相關的部分,是用來告訴發起呼叫的 Sidecar:「當你要連線到某個特定目的地 (Destination) 時,你應該採取什麼樣的流量策略?」

官方文件解釋:

DestinationRule defines policies that apply to traffic intended for a service after routing has occurred.
(DestinationRule 定義了在路由發生後,應用於發往某個服務的流量的策略。)

客戶端主要有兩種模式可選:

  • ISTIO_MUTUAL
    • Sidecar 在發起連線時,會主動進行 mTLS 握手。這是啟用 mTLS 的標準設定。
  • DISABLE
    • Sidecar 會發起一個普通的、未加密的明文連線。這在與網格外部、不支持 mTLS 的老舊服務通訊時會用到。

實戰範例:設定客戶端使用 mTLS

# destination-rule.yaml
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: default
  namespace: project-space
spec:
  host: "*.project-space.svc.cluster.local" # 此規則適用於所有發往 project-space 的流量
  trafficPolicy:
    tls:
      mode: ISTIO_MUTUAL # 告訴客戶端 Sidecar:請務必使用 Istio 的 mTLS 模式來發起連線

Part 4:mTLS 握手流程

https://ithelp.ithome.com.tw/upload/images/20251002/201786561YPUJvfKf1.png

圖片中有提到 Sidecar ASidecar B 用來互相驗證的憑證 (Certificate) 和金鑰並不是我們手動設定,而是由 Istio 的控制平面 (istiod) 自動發行與管理的。可以把 istiod 想像成服務網格的「身份證發行中心」,類似憑證中心 (Certificate Authority, CA) 的角色。完整的流程如下:

  1. Sidecar 啟動:當一個新的 Pod 和它的 Sidecar 被建立時,Sidecar 會自動向 istiod 發起一個證書簽署請求 (CSR)。
  2. 身份驗證istiod 會根據 Pod 的 Kubernetes Service Account 來驗證這個 Sidecar 的身份。
  3. 簽發證書:驗證通過後,istiod 就會簽發一張代表其工作負載身份(以 SPIFFE ID 格式)的 x.509 證書,連同金鑰一起,安全地發送給 Sidecar。

這個過程是完全自動化的。而且 istiod 發行的證書都是短期有效的,並且會自動輪換

簡化理解會是這樣:

https://ithelp.ithome.com.tw/upload/images/20251002/20178656QUUKCpGBDR.png

我們現在已經能確認通訊雙方的身份了(因為 mTLS 驗證了憑證)。但下一個問題是:即使身份合法,Service A 是否有權限去呼叫 Service BDELETE /users 這個 API 呢?

在明天的文章中,我們就要來探討 Istio 的授權 (Authorization) 機制 — AuthorizationPolicy!明天見!


上一篇
Day 24: Istio 核心路由:Gateway & VirtualService
下一篇
Day 26: 誰能存取我的服務?用 AuthorizationPolicy 實現存取控制
系列文
從 Docker 到 K8s:我的 30 天雲原生筆記26
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言