Share via


設定 Azure IoT MQ 預覽驗證

重要

Azure IoT Operations Preview – 由 Azure Arc 啟用目前處於預覽狀態。 您不應該在生產環境中使用此預覽軟體。

請參閱 Microsoft Azure 預覽版增補使用規定,以了解適用於 Azure 功能 (搶鮮版 (Beta)、預覽版,或尚未正式發行的版本) 的法律條款。

Azure IoT MQ Preview 支援用戶端的多個驗證方法,而且您可以將每個接聽程式設定為有自己的驗證系統與 BrokerAuthentication 資源。

默認 BrokerAuthentication 資源

Azure IoT Operations Preview 會部署名為 連結的預設 BrokerAuthentication 資源,並在命名空間中azure-iot-operations名為 authnlistener 的默認接聽程式。 其設定為只使用 Kubernetes 服務帳戶令牌進行驗證。 若要檢查它,請執行:

kubectl get brokerauthentication authn -n azure-iot-operations -o yaml

輸出會顯示預設 BrokerAuthentication 資源,並移除元數據以求簡潔:

apiVersion: mq.iotoperations.azure.com/v1beta1
kind: BrokerAuthentication
metadata:
  name: authn
  namespace: azure-iot-operations
spec:
  listenerRef:
    - listener
  authenticationMethods:
    - sat:
        audiences: ["aio-mq"]

若要變更組態,請修改 authenticationMethods 此 BrokerAuthentication 資源中的設定,或使用不同的名稱建立全新的 BrokerAuthentication 資源。 然後,使用 kubectl apply部署它。

BrokerListener 與 BrokerAuthentication 之間的關聯性

BrokerListener 和 BrokerAuthentication 是個別的資源,但會使用 listenerRef連結在一起。 適用的規則如下:

  • BrokerListener 只能連結至一個 BrokerAuthentication
  • BrokerAuthentication 可以連結至多個 BrokerListeners
  • 每個 BrokerAuthentication 都可以一次支援多個驗證方法

驗證流程

數位中的驗證方法順序會決定 Azure IoT MQ 如何驗證用戶端。 Azure IoT MQ 會嘗試使用第一個指定的方法驗證客戶端的認證,並逐一查看數位,直到找到相符專案或到達結尾為止。

針對每個方法,Azure IoT MQ 會先檢查客戶端的認證 是否與該方法相關 。 例如,SAT 驗證需要以 開頭 $sat的用戶名稱,而 X.509 驗證需要客戶端憑證。 如果客戶端的認證相關,Azure IoT MQ 會驗證其是否有效。 如需詳細資訊,請參閱 設定驗證方法 一節。

針對自定義驗證,Azure IoT MQ 會將與自定義驗證伺服器通訊失敗視為 與認證無關。 如果無法連線到自定義伺服器,此行為可讓 Azure IoT MQ 回復至其他方法。

驗證流程會在下列情況下結束:

  • 下列其中一個條件成立:
    • 客戶端的認證與其中一種方法相關且有效。
    • 用戶端的認證與任何方法無關。
    • 客戶端的認證是相關的,但對於任何方法都無效。
  • Azure IoT MQ 會根據驗證流程的結果,授與或拒絕對用戶端的存取權。

使用多個驗證方法,Azure IoT MQ 具有後援機制。 例如:

apiVersion: mq.iotoperations.azure.com/v1beta1
kind: BrokerAuthentication
metadata: 
  name: authn
  namespace: azure-iot-operations
spec:
  listenerRef:
    - listener
  authenticationMethods:
    - custom:
        # ...
    - sat:
        # ...
    - usernamePassword:
        # ...

先前的範例會指定自定義、SAT 和 使用者名稱密碼驗證。 當用戶端連線時,Azure IoT MQ 會嘗試使用指定順序 自定義 > SAT > 使用者名稱密碼中的指定方法驗證用戶端。

  1. Azure IoT MQ 會檢查客戶端的認證是否適用於自定義驗證。 由於自定義驗證依賴外部伺服器來判斷認證的有效性,因此訊息代理程式會考慮與自定義驗證相關的所有認證,並將其轉送至自定義驗證伺服器。

  2. 如果自定義驗證伺服器回應 PassFail 結果,驗證流程就會結束。 不過,如果自定義驗證伺服器無法使用,則 Azure IoT MQ 會回復為其餘指定的方法,而 SAT 則為下一個。

  3. Azure IoT MQ 會嘗試將認證驗證為 SAT 認證。 如果 MQTT 使用者名稱以 開頭 $sat,Azure IoT MQ 會將 MQTT 密碼評估為 SAT。 否則,訊息代理程式會回復為username-password,並檢查提供的 MQTT 使用者名稱和密碼是否有效。

如果自定義驗證伺服器無法使用,且所有後續方法都判斷所提供的認證不相關,則訊息代理程式會拒絕客戶端連線。

停用驗證

若要進行測試,請在 BrokerListener 資源變更驗證,以停用驗證。

spec:
  authenticationEnabled: false

設定驗證方法

若要深入瞭解每個驗證選項,請參閱下列各節:

使用者名稱與密碼

每個用戶端都有下列必要屬性:

例如,以 clients.toml 身分識別和 PBKDF2 編碼密碼開頭。

# Credential #1
# username: client1
# password: password
[client1]
password = "$pbkdf2-sha512$i=100000,l=64$HqJwOCHweNk1pLryiu3RsA$KVSvxKYcibIG5S5n55RvxKRTdAAfCUtBJoy5IuFzdSZyzkwvUcU+FPawEWFPn+06JyZsndfRTfpiEh+2eSJLkg"

[client1.attributes]
floor = "floor1"
site = "site1"

# Credential #2
# username: client2
# password: password2
[client2]
password = "$pbkdf2-sha512$i=100000,l=64$+H7jXzcEbq2kkyvpxtxePQ$jTzW6fSesiuNRLMIkDDAzBEILk7iyyDZ3rjlEwQap4UJP4TaCR+EXQXNukO7qNJWlPPP8leNnJDCBgX/255Ezw"

[client2.attributes]
floor = "floor2"
site = "site1"

若要使用 PBKDF2 來編碼密碼,請使用包含 命令的 az iot ops mq get-password-hash Azure IoT Operations CLI 擴充功能。 它會使用 SHA-512 演算法和 128 位隨機鹽,從密碼片語產生 PBKDF2 密碼哈希。

az iot ops mq get-password-hash --phrase TestPassword

輸出會顯示要複製的 PBKDF2 密碼哈希:

{
  "hash": "$pbkdf2-sha512$i=210000,l=64$4SnaHtmi7m++00fXNHMTOQ$rPT8BWv7IszPDtpj7gFC40RhhPuP66GJHIpL5G7SYvw+8rFrybyRGDy+PVBYClmdHQGEoy0dvV+ytFTKoYSS4A"
}

然後,將檔案儲存為 passwords.toml ,並將它匯入該金鑰下的 Kubernetes 秘密。

kubectl create secret generic passwords-db --from-file=passwords.toml -n azure-iot-operations

在 BrokerAuthentication 自定義資源中包含秘密的參考

spec:
  authenticationMethods:
    - usernamePassword:
        secretName: passwords-db

變更可能需要幾分鐘的時間才會生效。

您可以使用 Azure 金鑰保存庫 來管理 Azure IoT MQ 的秘密,而不是 Kubernetes 秘密。 若要深入瞭解,請參閱使用 Azure 金鑰保存庫 或 Kubernetes 秘密管理秘密

X.509 用戶端憑證

必要條件

  • 已啟用 TLS 的 Azure IoT MQ。
  • Step-CLI
  • PEM 檔案中的用戶端憑證和發行憑證鏈結。 如果您沒有任何專案,請使用步驟 CLI 來產生一些。
  • 熟悉公鑰密碼編譯,以及根 CA、私鑰和中繼憑證等詞彙。

支援 EC 和 RSA 金鑰,但鏈結中的所有憑證都必須使用相同的密鑰演演算法。 如果您要匯入自己的 CA 憑證,請確定客戶端憑證使用與 CA 相同的金鑰演演算法。

匯入受信任的用戶端根 CA 憑證

需要受信任的跟證書才能驗證客戶端憑證。 若要匯入可用來驗證客戶端憑證的跟證書,請先將憑證 PEM 匯入為金鑰 client_ca.pem下的 ConfigMap。 用戶端憑證必須在此 CA 中根目錄,Azure IoT MQ 才能進行驗證。

kubectl create configmap client-ca --from-file=client_ca.pem -n azure-iot-operations

若要檢查根 CA 憑證是否已正確匯入,請執行 kubectl describe configmap。 結果會顯示 PEM 憑證檔案的相同 base64 編碼方式。

$ kubectl describe configmap client-ca -n azure-iot-operations
Name:         client-ca
Namespace:    azure-iot-operations

Data
====
client_ca.pem:
----
-----BEGIN CERTIFICATE-----
MIIBmzCCAUGgAwIBAgIQVAZ2I0ydpCut1imrk+fM3DAKBggqhkjOPQQDAjAsMRAw
...
t2xMXcOTeYiv2wnTq0Op0ERKICHhko2PyCGGwnB2Gg==
-----END CERTIFICATE-----


BinaryData
====

匯入憑證對屬性對應

若要使用 X.509 憑證上屬性的用戶端使用授權原則,請建立憑證對屬性對應 TOML 檔案,並將其匯入為密鑰 x509Attributes.toml下的 Kubernetes 秘密。 此檔案會將客戶端憑證的主體名稱對應至可用於授權原則的屬性。 即使您未使用授權原則,也需要它。

kubectl create secret generic x509-attributes --from-file=x509Attributes.toml -n azure-iot-operations

若要瞭解屬性檔案語法,請參閱 授權使用 X.509 驗證的用戶端。

如同使用者名稱密碼驗證,您可以使用 Azure 金鑰保存庫 來管理此秘密,而不是 Kubernetes 秘密。 若要深入瞭解,請參閱使用 Azure 金鑰保存庫 或 Kubernetes 秘密管理秘密

啟用 X.509 客戶端驗證

最後,一旦匯入受信任的用戶端跟 CA 憑證和憑證對屬性對應,請新增 x509 為其中一個驗證方法,作為連結至已啟用 TLS 之接聽程式的 BrokerAuthentication 資源一部分來啟用 X.509 用戶端驗證。 例如:

spec:
  authenticationMethods:
    - x509:
        trustedClientCaCert: client-ca
        attributes:
          secretName: x509-attributes

使用 X.509 用戶端憑證將 mosquitto 用戶端 連線 至 Azure IoT MQ 預覽版

像 mosquitto 這樣的用戶端需要三個檔案,才能使用 TLS 和 X.509 用戶端驗證連線到 Azure IoT MQ。 例如:

mosquitto_pub -q 1 -t hello -d -V mqttv5 -m world -i thermostat \
-h "<IOT_MQ_EXTERNAL_IP>" \
--cert thermostat_cert.pem \
--key thermostat_key.pem \
--cafile chain.pem

在下列範例中:

  • 參數 --cert 會指定客戶端憑證 PEM 檔案。
  • 參數 --key 會指定客戶端私鑰 PEM 檔案。
  • 第三個參數 --cafile 最複雜:受信任的憑證資料庫,用於兩個用途:
    • 當 mosquitto 用戶端透過 TLS 連線到 Azure IoT MQ 時,它會驗證伺服器證書。 它會搜尋資料庫中的跟證書,以建立伺服器證書的受信任鏈結。 因此,伺服器跟證書必須複製到此檔案中。
    • 當 Azure IoT MQ 向 mosquitto 用戶端要求客戶端憑證時,也需要有效的憑證鏈結才能傳送至伺服器。 參數 --cert 會告訴 mosquitto 要傳送的憑證,但還不夠。 Azure IoT MQ 無法單獨驗證此憑證,因為它也需要中繼憑證。 Mosquitto 會使用資料庫檔案來建置必要的憑證鏈結。 若要支援此功能, cafile 必須同時包含中繼和跟證書。

瞭解 Azure IoT MQ 預覽 X.509 用戶端驗證流程

X.509 用戶端驗證流程的圖表。

以下是客戶端驗證流程的步驟:

  1. 當 X.509 用戶端驗證開啟時,連線客戶端必須呈現其用戶端憑證和任何中繼憑證,讓 Azure IoT MQ 建置跟在其其中一個設定的受信任憑證的憑證鏈結。
  2. 負載平衡器會將通訊導向至其中一個前端代理程式。
  3. 一旦前端代理程式收到客戶端憑證,它會嘗試建置跟在其中一個已設定憑證的憑證鏈結。 TLS 交握需要憑證。 如果前端代理程式已成功建置鏈結並驗證呈現的鏈結,則會完成 TLS 交握。 線上客戶端可以透過建置的 TLS 通道,將 MQTT 封包傳送至前端。
  4. TLS 通道已開啟,但客戶端驗證或授權尚未完成。
  5. 用戶端接著會將 CONNECT 封包傳送至 Azure IoT MQ。
  6. CONNECT 封包會再次路由傳送至前端。
  7. 前端會收集到目前為止呈現的所有客戶端認證,例如使用者名稱和密碼字段、CONNECT 封包中的驗證數據,以及 TLS 交握期間呈現的用戶端憑證鏈結。
  8. 前端會將這些認證傳送至驗證服務。 驗證服務會再次檢查憑證鏈結,並收集鏈結中所有憑證的主體名稱。
  9. 驗證服務會使用其 設定的授權規則 來判斷連線客戶端擁有的屬性。 這些屬性會決定客戶端可執行哪些作業,包括 CONNECT 封包本身。
  10. 驗證服務會將決策傳回給前端訊息代理程式。
  11. 前端代理程式知道客戶端屬性,以及它是否允許連線。 如果是,則 MQTT 連線已完成,而且用戶端可以繼續傳送和接收由其授權規則決定的 MQTT 封包。

Kubernetes Service 帳戶令牌

Kubernetes 服務帳戶令牌 (SAT) 是與 Kubernetes 服務帳戶相關聯的 JSON Web 令牌。 用戶端向 Azure IoT MQTT 訊息代理程式呈現 SAT,以自行驗證。

Azure IoT MQ 會使用 系結的服務帳戶令牌,這些令牌 詳述於 GKE 使用者需要知道 Kubernetes 的新服務帳戶令牌 文章。 以下是文章的突出功能:

在 Kubernetes 1.13 中啟動,並成為 1.21 的預設格式,系結令牌可解決舊版令牌的所有有限功能,以及更多功能:

  • 令牌本身更難竊取和濫用:它們是時間系結、對象系結和對象系結。
  • 它們採用標準化格式:OpenID 連線 (OIDC),具有完整的 OIDC 探索,讓服務提供者更容易接受它們。
  • 它們會使用新的 Kubelet 投影磁碟區類型,更安全地散發到 Pod。

訊息代理程式會使用 Kubernetes 令牌檢閱 API 來驗證令牌。 啟用 Kubernetes TokenRequestProjection 功能以指定 audiences (預設值自 1.21 起)。 如果未啟用此功能,就無法使用 SAT。

建立服務帳戶

若要建立 SAT,請先建立服務帳戶。 下列命令會建立名為 mqtt-client的服務帳戶。

kubectl create serviceaccount mqtt-client -n azure-iot-operations

新增授權的屬性

透過 SAT 的用戶端驗證可以選擇性地使用屬性標註其 SAT,以搭配自訂授權原則使用。 若要深入瞭解,請參閱 授權使用 Kubernetes Service 帳戶令牌的用戶端。

啟用服務帳戶令牌 (SAT) 驗證

authenticationMethods修改 BrokerAuthentication 資源中的設定,以指定sat為有效的驗證方法。 audiences指定令牌的有效物件清單。 選擇可識別 Azure IoT MQ 訊息代理程式服務的唯一值。 您必須指定至少一個物件,而且所有 SAT 都必須符合其中一個指定的物件。

spec:
  authenticationMethods:
    - sat:
        audiences: ["aio-mq", "my-audience"]

使用套用 kubectl apply您的變更。 變更可能需要幾分鐘的時間才會生效。

測試 SAT 驗證

SAT 驗證必須從與 Azure IoT MQ 位於相同叢集中的用戶端使用。 下列命令會指定具有 mosquitto 用戶端的 Pod,並將先前步驟中建立的 SAT 掛接至 Pod。

apiVersion: v1
kind: Pod
metadata:
  name: mqtt-client
  namespace: azure-iot-operations
spec:
  serviceAccountName: mqtt-client
  containers:
  - image: efrecon/mqtt-client
    name: mqtt-client
    command: ["sleep", "infinity"]
    volumeMounts:
    - name: mqtt-client-token
      mountPath: /var/run/secrets/tokens
  volumes:
  - name: mqtt-client-token
    projected:
      sources:
      - serviceAccountToken:
          path: mqtt-client-token
          audience: my-audience
          expirationSeconds: 86400

在這裡, serviceAccountName Pod 組態中的 字段必須符合與所使用令牌相關聯的服務帳戶。 此外, serviceAccountToken.audience Pod 組態中的字段必須是 BrokerAuthentication 資源中設定的 audiences 其中一個。

建立 Pod 之後,請在 Pod 中啟動殼層:

kubectl exec --stdin --tty mqtt-client -n azure-iot-operations -- sh

令牌會掛接在上一個範例中組態 /var/run/secrets/tokens 中指定的路徑。 擷取令牌,並使用它進行驗證。

token=$(cat /var/run/secrets/tokens/mqtt-client-token)

mosquitto_pub -h aio-mq-dmqtt-frontend -V mqttv5 -t hello -m world -u '$sat' -P "$token"

MQTT 使用者名稱必須設定為 $sat。 MQTT 密碼必須設定為 SAT 本身。

重新整理服務帳戶令牌

服務帳戶令牌在有限的時間內有效,並使用 進行 expirationSeconds設定。 不過,Kubernetes 會在令牌到期之前自動重新整理。 令牌會在背景重新整理,用戶端不需要執行任何其他動作,即可再次擷取令牌。

例如,如果用戶端是使用掛接為磁碟區的令牌的Pod,就像在測試SAT驗證範例中一樣,則會在同一個路徑/var/run/secrets/tokens/mqtt-client-token取得最新的令牌。 進行新的連線時,用戶端可以擷取最新的令牌,並使用它進行驗證。 用戶端也應該有一個機制,藉由擷取最新的令牌並重試連線,來處理 MQTT 未經授權的錯誤。

自訂驗證

使用自訂驗證,將客戶端驗證延伸至提供的驗證方法之外。 只要服務遵守 API,就可以插入

當用戶端連線到 Azure IoT MQ 並啟用自定義驗證時,Azure IoT MQ 會將客戶端認證驗證委派給具有 HTTP 要求的自訂驗證伺服器,以及用戶端呈現的所有認證。 自訂驗證伺服器會以客戶端 屬性進行授權的核准或拒絕回應。

建立自訂驗證服務

自訂驗證伺服器會與 Azure IoT MQ 分開實作和部署。

GitHub提供範例自定義驗證伺服器和指示。 使用此範例做為範本,以及實作您自己的自定義驗證邏輯的起點。

API

Azure IoT MQ 與自定義驗證伺服器之間的 API 遵循自定義驗證的 API 規格。 OpenAPI 規格可在 GitHub取得。

需要具有 TLS 加密的 HTTPS

Azure IoT MQ 會將包含敏感性客戶端認證的要求傳送至自定義驗證伺服器。 若要保護這些認證,Azure IoT MQ 與自定義驗證伺服器之間的通訊必須使用 TLS 加密。

自定義驗證伺服器必須出示伺服器證書,而 Azure IoT MQ 必須具有受信任的根 CA 憑證,才能驗證伺服器證書。 或者,自定義驗證伺服器可能需要 Azure IoT MQ 來呈現用戶端憑證以自行驗證。

啟用接聽程式的自定義驗證

authenticationMethods修改 BrokerAuthentication 資源中的設定,以指定custom為有效的驗證方法。 然後,指定與自定義驗證伺服器通訊所需的參數。

此範例顯示所有可能的參數。 所需的確切參數取決於每個自定義伺服器的需求。

spec:
  authenticationMethods:
    - custom:
        # Endpoint for custom authentication requests. Required.
        endpoint: https://auth-server-template
        # Trusted CA certificate for validating custom authentication server certificate.
        # Required unless the server certificate is publicly-rooted.
        caCert: custom-auth-ca
        # Authentication between Azure IoT MQ with the custom authentication server.
        # The broker may present X.509 credentials or no credentials to the server.
        auth:
          x509:
            secretName: custom-auth-client-cert
            namespace: azure-iot-operations
        # Optional additional HTTP headers that the broker will send to the
        # custom authentication server.
        headers:
          header_key: header_value