Azure IoT EdgeでX.509証明書のデバイス認証 - OpenSSL編

![Untitled (1056 x 700 px).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287622/d8d463f1-9e7e-eecb-be3c-ca8455001d96.png)

# 背景

IoTデバイスまたはIoT Edgeデバイスを検証する際は、扱いやすい対称キー認証(SAS)でデバイスを登録して使うと思います。検証後の本番運用ではX.509証明書の認証に切り替える必要があることとお客様に説明資料として関連業界の方々に情報共有のため、整理します。

# [参考] certGen.shを使ってX.509証明書作成

certGen.shを使ってX.509証明書を作成する場合は以下の手順をご参照ください。

https://qiita.com/motoJinC25/items/8049972a6e6080da7ac1

# Azure IoT Hubのデバイス認証

IoTデバイスとIoT Edgeデバイスによってデバイス認証方式が異なります。
こちらの記事では、OpenSSLを使って「X.509 自己署名認証」でIoT Edgeデバイスを登録する内容をまとめます。

## IoTデバイス

- 対称キー認証(SAS)
- X.509 CA署名認証(X.509 CA-signed authentication)
- X.509 自己署名認証(X.509 Self-signed authentication)

## IoT Edgeデバイス

- 対称キー認証(SAS)
- X.509 自己署名認証(X.509 Self-signed authentication)

# OpenSSLで自己署名によるデバイス認証

## 確認と設定

`openssl`コマンドが必要なのでLinux基盤OSが必要となります。
こちらはRaspberry Pi OSで実行した内容をお見せします。

```bash
$ openssl version  # OpenSSLインストール状態確認
OpenSSL 1.1.1n  15 Mar 2022
$ export DEVICE_NAME="edge_device_001"  # デバイス名定義
$ export DAYS=7300  # 証明書有効期間定義(20年)
```

## 証明書作成

三つの証明書関連ファイルを作成します。

- KEYファイル : シークレットな鍵（秘密鍵）と呼ばれるファイル。この鍵はとても大事で、他の人に知られてはいけません。
- CSRファイル : 公開鍵という特別な鍵と、デバイス名などの情報を合わせたファイル。この鍵は、他に共有するためのものです。秘密鍵から作られますが、秘密鍵自体はこのファイルには含まれません。
- CRTファイル : 信頼された人（認証機関）が、CSRファイルをチェックしてOKだと判断したら（自己署名）、このCRTファイルが作られます。このファイルは、デバイスの公開鍵に信頼の証となる印をつけたもので、他に知らせるための証明書となります。

```bash
$ sudo openssl genpkey -out /var/secrets/${DEVICE_NAME}.key.pem -algorithm RSA -pkeyopt rsa_keygen_bits:2048  # OpenSSL3.0ベースで証明書の2048ビットRSA秘密キーファイル(PKCS#8のPEM形式)を作成
............+++++
........................+++++
$ sudo openssl req -new -key /var/secrets/${DEVICE_NAME}.key.pem -out /var/secrets/${DEVICE_NAME}.csr.pem  # 秘密キーを使用してCSRの証明書署名要求ファイル(PEM形式)を生成 - Common Nameの設定値はデバイス名
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:edge_device_001   <-- デバイス名入力
Email Address []:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
$ sudo openssl x509 -req -days ${DAYS} -in /var/secrets/${DEVICE_NAME}.csr.pem -signkey ${DEVICE_NAME}.key.pem -out /var/secrets/${DEVICE_NAME}.crt.pem  # X.509自己署名証明書(PEM形式)の作成
Signature ok
subject=C = AU, ST = Some-State, O = Internet Widgits Pty Ltd, CN = edge_device_001
Getting Private key
$ sudo chmod 444 /var/secrets/${DEVICE_NAME}.*  # 権限設定
```

## 証明書の拇印確認

Azure IoT Hubで証明書認証のエッジデバイスを登録する際に拇印入力で必要な値です。

```bash
$ openssl x509 -in ${DEVICE_NAME}.crt -noout -fingerprint | sed 's/[:]//g'  # X.509自己署名証明書の拇印確認
SHA1 Fingerprint=EA9D8C43D48293436A74A60A3A81D66D73A8D1F1
```

## Azure IoT EdgeでIoT Edgeデバイス登録

### Azure CLI

Azure CLIを使って証明書認証のエッジデバイスを登録します。
プライマリとセカンダリの両方の拇印に同じ証明書の拇印の値を設定します。

```bash
$ az iot hub device-identity create --device-id ${DEVICE_NAME} --hub-name <IoT Hubリソース名> --edge-enabled --auth-method x509_thumbprint --primary-thumbprint <拇印の値> --secondary-thumbprint <拇印の値>
```

### Azure Portal

Azureポータルでエッジデバイスを登録します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287622/8922e684-4019-366c-37d2-eeac7af79a6a.png)

## IoT Edgeデバイスの構成ファイル反映

```bash
$ sudo vi /etc/aziot/config.toml
...
[provisioning]
source = "manual"
iothub_hostname = "<IoT Hubリソース名>.azure-devices.net"
device_id = "<DEVICE_NAME>"

[provisioning.authentication]
method = "x509"
identity_pk = "file:///var/secrets/<DEVICE_NAME>.key.pem"
identity_cert = "file:///var/secrets/<DEVICE_NAME>.crt.pem"
...
$ sudo iotedge config apply  # 構成ファイルの変更を適用
Azure IoT Edge has been configured successfully!

Restarting service for configuration to take effect...
Stopping aziot-edged.service...Stopped!
Stopping aziot-identityd.service...Stopped!
Stopping aziot-keyd.service...Stopped!
Stopping aziot-certd.service...Stopped!
Stopping aziot-tpmd.service...Stopped!
Starting aziot-edged.mgmt.socket...Started!
Starting aziot-edged.workload.socket...Started!
Starting aziot-identityd.socket...Started!
Starting aziot-keyd.socket...Started!
Starting aziot-certd.socket...Started!
Starting aziot-tpmd.socket...Started!
Starting aziot-edged.service...Started!
Done.
```