MQTT ブローカーで MQTT 通信をセキュリティで保護するために、自動の証明書管理で TLS を構成する
重要
Azure Arc によって有効にされる Azure IoT Operations Preview は、 現在プレビュー段階です。 運用環境ではこのプレビュー ソフトウェアを使わないでください。
一般公開されたリリースが利用可能になったときに、新しい Azure IoT Operations のインストールをデプロイする必要があります。プレビュー段階のインストールをアップグレードすることはできません。
ベータ版、プレビュー版、または一般提供としてまだリリースされていない Azure の機能に適用される法律条項については、「Microsoft Azure プレビューの追加使用条件」を参照してください。
BrokerListener リソースを使用して、MQTT ブローカーとクライアントの間の MQTT 通信をセキュリティで保護するように TLS を構成できます。 手動または自動の証明書管理で TLS を構成できます。
cert-manager のインストールを確認する
証明書の自動管理では、cert-manager を使用して TLS サーバー証明書を管理します。 既定では、cert-manager は Azure IoT Operations Preview と共に azure-iot-operations
名前空間に既にインストールされています。 続行する前に、インストールを確認します。
kubectl
を使用して、cert-manager のアプリ ラベルに一致するポッドを確認します。kubectl get pods --namespace azure-iot-operations -l 'app in (cert-manager,cainjector,webhook)'
NAME READY STATUS RESTARTS AGE aio-cert-manager-64f9548744-5fwdd 1/1 Running 4 (145m ago) 4d20h aio-cert-manager-cainjector-6c7c546578-p6vgv 1/1 Running 4 (145m ago) 4d20h aio-cert-manager-webhook-7f676965dd-8xs28 1/1 Running 4 (145m ago) 4d20h
ポッドが準備完了で実行中と表示されている場合、cert-manager はインストールされており、使用できる状態になっています。
ヒント
インストール状況をさらに確認するには、cert-manager のドキュメント、「インストールの確認」を確認します。 azure-iot-operations
名前空間を必ず使用してください。
TLS サーバー証明書の発行者を作成する
cert-manager の発行者リソースでは、証明書を自動的に発行する方法が定義されます。 cert-manager では、いくつかの発行者の種類がネイティブでサポートされています。 また、ネイティブでサポートされている発行者以外にも機能を拡張するために、外部発行者の種類もサポートされています。 MQTT ブローカーは、あらゆる種類の cert-manager 発行者で使用できます。
重要
初期デプロイ時に、Azure IoT Operations は TLS サーバー証明書の既定の発行者を使用してインストールされます。 この発行者を開発とテストに使うことができます。 詳細については、「Azure IoT Operations での既定のルート CA と発行者」を参照してください。 以下の手順は、別の発行者を使用する場合にのみ必要です。
発行者を作成する方法は、シナリオによって異なります。 次のセクションでは、作業の開始に役立つ例を示します。
CA 発行者は、開発とテストに役立ちます。 これは、Kubernetes シークレットに格納されている証明書と秘密キーを使用して構成する必要があります。
ルート証明書を Kubernetes シークレットとして設定する
既存の CA 証明書がある場合は、CA 証明書と秘密キーの PEM ファイルを使用して Kubernetes シークレットを作成します。 次のコマンドを実行すると、ルート証明書が Kubernetes シークレットとして設定され、次のセクションをスキップできます。
kubectl create secret tls test-ca --cert tls.crt --key tls.key -n azure-iot-operations
CA 証明書がない場合、cert-manager でルート CA 証明書を生成できます。 cert-manager を使用してルート CA 証明書を生成することは、自己署名証明書による CA 発行者のブートストラップ と呼ばれます。
まず、
ca.yaml
を作成します。apiVersion: cert-manager.io/v1 kind: Issuer metadata: name: selfsigned-ca-issuer namespace: azure-iot-operations spec: selfSigned: {} --- apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: selfsigned-ca-cert namespace: azure-iot-operations spec: isCA: true commonName: test-ca secretName: test-ca issuerRef: # Must match Issuer name above name: selfsigned-ca-issuer # Must match Issuer kind above kind: Issuer group: cert-manager.io # Override default private key config to use an EC key privateKey: rotationPolicy: Always algorithm: ECDSA size: 256
次のコマンドを使用して、自己署名 CA 証明書を作成します。
kubectl apply -f ca.yaml
cert-manager では、既定値を使用して CA 証明書を作成します。 この証明書のプロパティは、証明書の仕様を変更することで変更できます。 有効なオプションの一覧については、cert-manager のドキュメントを参照してください。
ルート証明書を配布する
前の例では、CA 証明書が test-ca
という Kubernetes シークレットに格納されます。 PEM 形式の証明書は、シークレットから取得し、次のコマンドを使用してファイル ca.crt
に格納できます。
kubectl get secret test-ca -n azure-iot-operations -o json | jq -r '.data["tls.crt"]' | base64 -d > ca.crt
この証明書は、すべてのクライアントに配布および信頼されている必要があります。 たとえば、mosquitto クライアントの場合は --cafile
フラグを使用します。
CA 証明書に基づいて発行者を作成する
cert-manager には、前の手順で生成またはインポートされた CA 証明書に基づく発行者が必要です。 次のファイルを issuer-ca.yaml
として作成します。
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: my-issuer
namespace: azure-iot-operations
spec:
ca:
# Must match secretName of generated or imported CA cert
secretName: test-ca
次のコマンドで発行者を作成します。
kubectl apply -f issuer-ca.yaml
前のコマンドでは、TLS サーバー証明書を発行するための発行者を作成します。 発行者の名前と種類をメモします。 この例では、名前が my-issuer
、種類が Issuer
です。 これらの値は、後で BrokerListener リソースで設定されます。
ポートの TLS を有効にする
BrokerListener リソースの tls
設定を変更して、フロントエンドの TLS ポートと発行者を指定します。 自動証明書管理を使用してポート 8884 で TLS を有効にする BrokerListener リソースの例を次に示します。
apiVersion: mqttbroker.iotoperations.azure.com/v1beta1
kind: BrokerListener
metadata:
name: my-new-tls-listener
namespace: azure-iot-operations
spec:
brokerRef: broker
serviceType: loadBalancer
serviceName: my-new-tls-listener # Avoid conflicts with default service name 'aio-mq-dmqtt-frontend'
port: 8884 # Avoid conflicts with default port 8883
tls:
automatic:
issuerRef:
name: my-issuer
kind: Issuer
BrokerListener リソースが構成されると、MQTT ブローカーでは、指定されたポートと TLS が有効になっている新しいサービスが自動的に作成されます。
省略可能: サーバー証明書のパラメーターを構成する
必須のパラメーターは、issuerRef.name
と issuerRef.kind
だけです。 生成された TLS サーバー証明書のすべてのプロパティは自動的に選択されます。 ただし、MQTT ブローカーでは特定のプロパティを BrokerListener リソースの tls.automatic.issuerRef
で指定することでカスタマイズできます。 サポートされているすべてのプロパティの例を次に示します。
# cert-manager issuer for TLS server certificate. Required.
issuerRef:
# Name of issuer. Required.
name: my-issuer
# 'Issuer' or 'ClusterIssuer'. Required.
kind: Issuer
# Issuer group. Optional; defaults to 'cert-manager.io'.
# External issuers may use other groups.
group: cert-manager.io
# Namespace of certificate. Optional; omit to use default namespace.
namespace: az
# Where to store the generated TLS server certificate. Any existing
# data at the provided secret will be overwritten.
# Optional; defaults to 'my-issuer-{port}'.
secret: my-issuer-8884
# Parameters for the server certificate's private key.
# Optional; defaults to rotationPolicy: Always, algorithm: ECDSA, size: 256.
privateKey:
rotationPolicy: Always
algorithm: ECDSA
size: 256
# Total lifetime of the TLS server certificate. Optional; defaults to '720h' (30 days).
duration: 720h
# When to begin renewing the certificate. Optional; defaults to '240h' (10 days).
renewBefore: 240h
# Any additional SANs to add to the server certificate. Omit if not required.
san:
dns:
- iotmq.example.com
# To connect to the broker from a different namespace, add the following DNS name:
- aio-mq-dmqtt-frontend.azure-iot-operations.svc.cluster.local
ip:
- 192.168.1.1
デプロイの検証
kubectl を使用して、BrokerListener リソースに関連付けられているサービスが実行されていることを確認します。 上記の例では、サービス名が my-new-tls-listener
、名前空間が azure-iot-operations
です。 次のコマンドで、サービスの状態を確認します。
$ kubectl get service my-new-tls-listener -n azure-iot-operations
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-new-tls-listener LoadBalancer 10.43.241.171 XXX.XX.X.X 8884:32457/TCP 33s
TLS を使用してブローカーに接続する
サーバー証明書が構成されると、TLS が有効になります。 mosquitto を使用してテストするには:
mosquitto_pub -h $HOST -p 8884 -V mqttv5 -i "test" -t "test" -m "test" --cafile ca.crt
--cafile
引数によって、mosquitto クライアント上で TLS が有効になり、クライアントは指定されたファイルによって発行されたすべてのサーバー証明書を信頼する必要があることが指定されます。 構成された TLS サーバー証明書の発行者を格納するファイルを指定する必要があります。
$HOST
を適切なホストに置き換えます。
- 同じクラスター内から接続する場合は、指定されたサービス名 (例では
my-new-tls-listener
) またはサービスCLUSTER-IP
に置き換えます。 - クラスターの外部から接続する場合、サービス
EXTERNAL-IP
を指定します。
必要に応じて、必ず認証方法を指定してください。
Azure IoT Operations Preview での既定のルート CA と発行者
作業の開始に役立つように、Azure IoT Operations は TLS サーバー証明書のための既定の "quickstart" というルート CA と発行者を使用してデプロイされます。 この発行者を開発とテストに使うことができます。
CA 証明書は自己署名証明書であるため、Azure IoT Operations の外部のどのクライアントからも信頼されていません。 CA 証明書のサブジェクトは
CN = Azure IoT Operations Quickstart Root CA - Not for Production
で、インストールから 30 日以内に期限切れになります。ルート CA 証明書は、
aio-ca-key-pair-test-only
と呼ばれる Kubernetes シークレットに格納されます。ルート CA 証明書のパブリック部分は、
aio-ca-trust-bundle-test-only
と呼ばれる ConfigMap に格納されます。 ConfigMap から CA 証明書を取得し、kubectl と openssl を使用して調べることができます。kubectl get configmap aio-ca-trust-bundle-test-only -n azure-iot-operations -o json | jq -r '.data["ca.crt"]' | openssl x509 -text -noout
Certificate: Data: Version: 3 (0x2) Serial Number: <SERIAL-NUMBER> Signature Algorithm: ecdsa-with-SHA256 Issuer: CN = Azure IoT Operations Quickstart Root CA - Not for Production Validity Not Before: Nov 2 00:34:31 2023 GMT Not After : Dec 2 00:34:31 2023 GMT Subject: CN = Azure IoT Operations Quickstart Root CA - Not for Production Subject Public Key Info: Public Key Algorithm: id-ecPublicKey Public-Key: (256 bit) pub: <PUBLIC-KEY> ASN1 OID: prime256v1 NIST CURVE: P-256 X509v3 extensions: X509v3 Basic Constraints: critical CA:TRUE X509v3 Key Usage: Certificate Sign X509v3 Subject Key Identifier: <SUBJECT-KEY-IDENTIFIER> Signature Algorithm: ecdsa-with-SHA256 [SIGNATURE]
既定では、
azure-iot-operations
名前空間に CA 発行者が既に構成されており、aio-ca-issuer
と呼ばれています。 これは IoT Operations のすべての TLS サーバー証明書のための共通の CA 発行者として使用されます。 MQTT ブローカーでは、同じ CA 証明書から作成された発行者を使用して、ポート 8883 の既定の TLS リスナーに対して TLS サーバー証明書を発行します。 次のコマンドを使用して、発行者を検査できます。kubectl get issuer aio-ca-issuer -n azure-iot-operations -o yaml
apiVersion: cert-manager.io/v1 kind: Issuer metadata: annotations: meta.helm.sh/release-name: azure-iot-operations meta.helm.sh/release-namespace: azure-iot-operations creationTimestamp: "2023-11-01T23:10:24Z" generation: 1 labels: app.kubernetes.io/managed-by: Helm name: aio-ca-issuer namespace: azure-iot-operations resourceVersion: "2036" uid: <UID> spec: ca: secretName: aio-ca-key-pair-test-only status: conditions: - lastTransitionTime: "2023-11-01T23:10:59Z" message: Signing CA verified observedGeneration: 1 reason: KeyPairVerified status: "True" type: Ready
運用環境では、前のセクションで説明したように、信頼された CA の証明書を使用して CA 発行者を構成する必要があります。