[IoT Core] プライベートCAで署名されたサーバ証明書を使用してカスタムドメインを設定してみました

2022.10.01

1 はじめに

IoT Coreでは、カスタムドメイン設定で、エンドポイントに独自のドメインを使用することができます。そして、この時、使用されるサーバ証明書についても、独自のものを設定することが可能です。

IoT Coreの証明書に関しては、ブログなどで、たくさん紹介されているのですが、殆どがクライアント証明書の話で、サーバ証明書について書かれているものが、殆どないように感じましたでので、今回試した内容を、覚書としてここに置かせて頂きました。

作業としては、下記のような内容になります。

  • プライベートCA作成
  • サーバ証明書に署名してACM登録
  • ドメインの検証証明書作成
  • ドメインの名前解決
  • IoT Coreでのカスタムドメイン設定

なお、設定したドメイン名は、example.alexa-dev.tokyoです。

2 証明書作成

テストのために、プライベートなCA及び、サーバ証明書を作成します。

(1) CA証明書

% openssl genrsa 2048 > ca.key
% SUBJ="/C=JP/ST=Tokyo/L=Chiyoda-ku/O=Classmethod.Inc/OU=IoT/CN=CA"
% openssl req -new -x509 -days 365 -key ca.key -subj "$SUBJ" > ca.crt

(2) サーバ証明書

% openssl genrsa 2048 > server.key
% SUBJ="/C=JP/ST=Tokyo/L=Chiyoda-ku/O=Classmethod.Inc/OU=IoT/CN=example.alexa-dev.tokyo"
% openssl req -new -key server.key -subj "$SUBJ" > server.csr
% cat > server.ext <<EOF
[ v3_server ]
extendedKeyUsage = serverAuth
EOF
% openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial \
-extfile server.ext -extensions "v3_server" -days 365 > server.crt

サーバ証明書のCNは、ドメイン名と一致している必要があります。また、拡張属性のserverAuthは、必須です。この指定がないと、IoT Coreのカスタムドメイン設定で、サーバ証明書として使用できません。

3 ACM

カスタムドメインで設定する証明書は、AMCに登録されている必要があります。

(1) サーバ証明書のインポート

作成したサーバ証明書を、ACMにインポートします。

(2) 検証証明書のリクエスト

ドメインの所有者であることを証明するための、パブリック証明書です。

DNS検証に必要なCNAMEの追加は、ACMと同一アカウントのRoute53で、当該ドメインのゾーンを管理している場合は、「Route 53でレコードを作成」 から自動で行えます。

検証が完了して、証明書が利用可能になるまで、少し、時間がかかる場合があります。

Route 53では、のCNAMEレコードが追加されていることが確認できますが、Route53以外で管理されている場合は、このCNAMEの追加は、手作業になります。

4 カスタムドメイン設定

ACMにサーバ証明書及び、検証証明書が置かれた時点で、IoT Coreでのカスタムドメインの設定が可能になります。

ACMに追加した2つの証明書をセットします。

ドメイン設定に追加されると、一覧に表示されます。

5 名前解決

設定するドメイン名と、Iot Coreのデフォルトのエンドポイントとの紐付けは、CNAMEで行います。

% dig example.alexa-dev.tokyo
・・・略・・・
;; ANSWER SECTION:
example.alexa-dev.tokyo. 59 IN  CNAME   xxxxxxxxxxxx-ats.iot.ap-northeast-1.amazonaws.com.
・・・略・・・

6 動作確認

動作確認のために、IoT Coreで証明書を発行し、手元に準備します。(テストに必要なポリシーもセットしています)

  • AmazonRootCA1.pem ルート証明書
  • client.crt クライアント証明書
  • client.key クライアント秘密鍵

(1) デフォルトのエンドポイント + Root証明書

最初に、デフォルトのエンドポイントに対し、AWSからダウンロードしたルート証明書(AmazonRootCA1.pem)で接続してみました、当然ですが、こちらは、問題なく送信できています。

% mosquitto_pub --cafile AmazonRootCA1.pem --cert client.crt --key client.key -h xxxxxxxxxxxx-ats.iot.ap-northeast-1.amazonaws.com -t topic/test -i clientid -d -m "TEST1"

Client clientid sending CONNECT
Client clientid received CONNACK (0)
Client clientid sending PUBLISH (d0, q0, r0, m1, 'topic/test', ... (5 bytes))
Client clientid sending DISCONNECT

(2) カスタムドメイン + Root証明書

接続先を、設定したカスタムドメインに変更すると、こちらは、verify failedとなっていることが確認できます。使用されているサーバ証明書は、パブリック署名が無いことが、原因です。

% mosquitto_pub --cafile AmazonRootCA1.pem --cert client.crt --key client.key -h example.alexa-dev.tokyo -t topic/test -i clientid -d -m "TEST2"

Client clientid sending CONNECT
OpenSSL Error[0]: error:1416F086:SSL routines:tls_process_server_certificate:certificate verify failed
Error: A TLS error occurred.

(3) カスタムドメイン + プライベートCA証明書

今回設定したカスタムドメインに対しては、プライベートCA証明書を使用すると、問題なく接続できることが確認できます。

% mosquitto_pub --cafile ca.crt --cert client.crt --key client.key -h example.alexa-dev.tokyo -t topic/test -i clientid -d -m "TEST3"

Client clientid sending CONNECT
Client clientid received CONNACK (0)
Client clientid sending PUBLISH (d0, q0, r0, m1, 'topic/test', ... (5 bytes))
Client clientid sending DISCONNECT

7 カスタムドメインの再作成

今回の記事とは、直接関係ないですが・・・一度、有効なカスタムドメインを作成すると、その作り直しには、1週間の期間が必要になるので注意が必要です。 これは、例えば、既にパブリックな署名をされたサーバ証明書でカスタムドメインを作成してある場合、これを、プライベートな署名のものに差し替える作業が、これに該当します。

まず最初に、カスタムドメインは、同じ名前のものが登録できません。そこで、一旦削除する必要があるのですが、カスタムドメインの削除は、「無効化」してから7日間が必要です。

また、カスタムドメインに使用中の「サーバ証明書」は、ACM上から削除できません。

このことから、作り直しは、以下の手順になると思います。

削除
1. カスタムドメインの無効化
2. 1週間の待機
3. カスタムドメインの削除
4. カスタムドメインで使用した証明書の削除
登録
1. サーバ証明書をACMへ登録
2. カスタムドメインの作成

8 最後に

今回は、IoT Coreでは、プライベートなCAで署名したサーバ証明書を使用して、カスタムドメイン設定を行い、独自のCA証明書を使用してサーバを信用する通信を確認してみました。

クライアント証明書の方は、「CA登録無しの証明書登録(マルチアカウント登録)」が利用可能になってから、かなり自由に設定が可能になったと感じておりましたが、サーバ証明書の方も、自由度は高いようです。

一点注意が必要だなと感じたのは、サーバ証明書を作成する時に、拡張属性のserverAuthを追加しておくことを忘れないようにすることです。これが無いと、IoT Coreへの登録時にエラーとなってしまうようです。

9 参考リンク


プライベート CA によって署名された外部証明書
AWS Certificate Manager に証明書をインポートする