MQTT用に個別に証明書を用意する

WebArenaでMQTTサーバを立てたときに、電子証明書はWebサーバのものを使うように設定しましたが、これだとLet’s Encryptでサーバ証明書やフィンガープリントが更新されたときに困ってしまいます。

ですので、mosquitto用に専用の証明書を用意します。Webブラウザは関係ないので、今回はオレオレ証明書で行くことにします。といっても、ほぼこちらの記事のままです。ですので、参考にされる方はこちらの記事を見てください。あと、公式ドキュメントも参考になります。以下は自分の作業記録として必要な部分だけです。

証明書の生成

まず、CA証明書に必要な秘密鍵を生成します。-des3を付けるとパスフレーズ必須なので、なにか考えておきます。

ubuntu@i-xxxxxxxxxxxxxx:~$ sudo su -
root@i-xxxxxxxxxxxxxx:~# cd /etc/mosquitto/certs/
root@i-xxxxxxxxxxxxxx:/etc/mosquitto# ls -la certs
total 12
drwxr-xr-x 2 root root 4096 Oct  2 13:47 .
drwxr-xr-x 5 root root 4096 Oct  2 13:47 ..
-rw-r--r-- 1 root root  130 Jun 18  2019 README
root@i-xxxxxxxxxxxxxx:/etc/mosquitto# chown mosquitto.mosquitto certs
root@i-xxxxxxxxxxxxxx:/etc/mosquitto# chmod 700 certs
root@i-xxxxxxxxxxxxxx:/etc/mosquitto# ls -la certs
total 12
drwx------ 2 mosquitto mosquitto 4096 Oct  2 13:47 .
drwxr-xr-x 5 root      root      4096 Oct  2 13:47 ..
-rw-r--r-- 1 root      root       130 Jun 18  2019 README
root@i-xxxxxxxxxxxxxx:/etc/mosquitto/certs# sudo -u mosquitto openssl genrsa -des3 -out ca.key 2048
Generating RSA private key, 2048 bit long modulus (2 primes)
...........................................+++++
....................................+++++
e is 65537 (0x010001)
Enter pass phrase for ca.key:
Verifying - Enter pass phrase for ca.key:
root@i-xxxxxxxxxxxxxx:/etc/mosquitto/certs# ls -la
total 16
drwx------ 2 mosquitto mosquitto 4096 Nov  8 05:50 .
drwxr-xr-x 5 root      root      4096 Oct  2 13:47 ..
-rw-r--r-- 1 root      root       130 Jun 18  2019 README
-rw------- 1 mosquitto mosquitto 1743 Nov  8 05:50 ca.key
root@i-xxxxxxxxxxxxxx:/etc/mosquitto/certs# 

※安全に鍵を保管できるなら、

root@i-xxxxxxxxxxxxxx:/etc/mosquitto/certs# openssl rsa -in ca.key -out ca_nopass.key
Enter pass phrase for ca.key:
writing RSA key
root@i-xxxxxxxxxxxxxx:/etc/mosquitto/certs# 

などとして秘密鍵からパスフレーズを削除することもできます。(-out の代わりに -text とすると、秘密鍵の内容をテキスト表示できます)

次に、秘密鍵を使って、CA証明書を生成します。設定は適当にしました。有効期間は7305日(20年)にしました。暗号強度的には20年も持つものではないと思いますが、しょせん趣味ですので、実質永遠とします。

root@i-xxxxxxxxxxxxxx:/etc/mosquitto/certs# sudo -u mosquitto openssl req -new -x509 -days 7305 -key ca.key -out ca.crt
Enter pass phrase for ca.key:
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]:JP
State or Province Name (full name) [Some-State]:Tokyo
Locality Name (eg, city) []:Tokyo  
Organization Name (eg, company) [Internet Widgits Pty Ltd]:example.com
Organizational Unit Name (eg, section) []: 
Common Name (e.g. server FQDN or YOUR name) []:example.com
Email Address []:
root@i-xxxxxxxxxxxxxx:/etc/mosquitto/certs# ls -la
total 20
drwx------ 2 mosquitto mosquitto 4096 Nov  8 06:08 .
drwxr-xr-x 5 root      root      4096 Oct  2 13:47 ..
-rw-r--r-- 1 root      root       130 Jun 18  2019 README
-rw-rw-r-- 1 mosquitto mosquitto 1257 Nov  8 06:08 ca.crt
-rw------- 1 mosquitto mosquitto 1751 Nov  8 06:07 ca.key
root@i-xxxxxxxxxxxxxx:/etc/mosquitto/certs# 

サーバ証明書を生成します。

root@i-xxxxxxxxxxxxxx:/etc/mosquitto/certs# sudo -u mosquitto openssl genrsa -out server.key 2048
Generating RSA private key, 2048 bit long modulus (2 primes)
.................................................+++++
..........................................................................+++++
e is 65537 (0x010001)
root@i-xxxxxxxxxxxxxx:/etc/mosquitto/certs# ls -la
total 24
drwx------ 2 mosquitto mosquitto 4096 Nov  8 06:09 .
drwxr-xr-x 5 root      root      4096 Oct  2 13:47 ..
-rw-r--r-- 1 root      root       130 Jun 18  2019 README
-rw-rw-r-- 1 mosquitto mosquitto 1257 Nov  8 06:08 ca.crt
-rw------- 1 mosquitto mosquitto 1751 Nov  8 06:07 ca.key
-rw------- 1 mosquitto mosquitto 1679 Nov  8 06:09 server.key
root@i-xxxxxxxxxxxxxx:/etc/mosquitto/certs# 

サーバ証明書を生成したCA証明書で認証してもらうのに必要なCSRファイルを作成します。

root@i-xxxxxxxxxxxxxx:/etc/mosquitto/certs# sudo -u mosquitto openssl req -new -out server.csr -key server.key
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]:JP
State or Province Name (full name) [Some-State]:Tokyo
Locality Name (eg, city) []:Tokyo
Organization Name (eg, company) [Internet Widgits Pty Ltd]:example.com
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:example.com
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
root@i-xxxxxxxxxxxxxx:/etc/mosquitto/certs# ls -la
total 28
drwx------ 2 mosquitto mosquitto 4096 Nov  8 06:11 .
drwxr-xr-x 5 root      root      4096 Oct  2 13:47 ..
-rw-r--r-- 1 root      root       130 Jun 18  2019 README
-rw-rw-r-- 1 mosquitto mosquitto 1257 Nov  8 06:08 ca.crt
-rw------- 1 mosquitto mosquitto 1751 Nov  8 06:07 ca.key
-rw-rw-r-- 1 mosquitto mosquitto  964 Nov  8 06:11 server.csr
-rw------- 1 mosquitto mosquitto 1679 Nov  8 06:09 server.key
root@i-xxxxxxxxxxxxxx:/etc/mosquitto/certs# 

サーバ証明書をCAに認証してもらいます。

root@i-xxxxxxxxxxxxxx:/etc/mosquitto/certs# sudo -u mosquitto openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 3605
Signature ok
subject=C = JP, ST = Tokyo, L = Tokyo, O = example.com, CN = example.com
Getting CA Private Key
Enter pass phrase for ca.key:
root@i-xxxxxxxxxxxxxx:/etc/mosquitto/certs# ls -la
total 36
drwx------ 2 mosquitto mosquitto 4096 Nov  8 06:11 .
drwxr-xr-x 5 root      root      4096 Oct  2 13:47 ..
-rw-r--r-- 1 root      root       130 Jun 18  2019 README
-rw-rw-r-- 1 mosquitto mosquitto 1257 Nov  8 06:08 ca.crt
-rw------- 1 mosquitto mosquitto 1751 Nov  8 06:07 ca.key
-rw-rw-r-- 1 mosquitto mosquitto   41 Nov  8 06:11 ca.srl
-rw-rw-r-- 1 mosquitto mosquitto 1135 Nov  8 06:11 server.crt
-rw-rw-r-- 1 mosquitto mosquitto  964 Nov  8 06:11 server.csr
-rw------- 1 mosquitto mosquitto 1679 Nov  8 06:09 server.key
root@i-xxxxxxxxxxxxxx:/etc/mosquitto/certs# 

ついでに、フィンガープリントも確認しておきます。

root@i-xxxxxxxxxxxxxx:/etc/mosquitto/certs# openssl x509 -sha1 -fingerprint -noout -in server.crt
SHA1 Fingerprint=xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx
root@i-xxxxxxxxxxxxxx:/etc/mosquitto/certs# 

mosquittoの設定変更

上記で生成した各ファイルを /etc/mosquitto/certs に配置します。(実際には /etc/mosquitto/certs で作業しました)

設定ファイルである、/etc/mosquitto/conf.d/default.conf を以下のように修正します。

allow_anonymous false
password_file /etc/mosquitto/passwd

listener 1883 localhost

listener 8883
certfile /etc/mosquitto/certs/server.crt
cafile /etc/mosquitto/certs/ca.crt
keyfile /etc/mosquitto/certs/server.key

listener 8083
protocol websockets
certfile /etc/mosquitto/certs/server.crt
cafile /etc/mosquitto/certs/ca.crt
keyfile /etc/mosquitto/certs/server.key

mosquittoを再起動します。

root@i-xxxxxxxxxxxxxx:/etc/mosquitto/conf.d# service mosquitto restart
root@i-xxxxxxxxxxxxxx:/etc/mosquitto/conf.d# service mosquitto status
● mosquitto.service - Mosquitto MQTT v3.1/v3.1.1 Broker
     Loaded: loaded (/lib/systemd/system/mosquitto.service; enabled; vendor preset: enabled)
     Active: active (running) since Sun 2020-11-08 06:32:06 JST; 4s ago
       Docs: man:mosquitto.conf(5)
             man:mosquitto(8)
   Main PID: 155046 (mosquitto)
      Tasks: 3 (limit: 1075)
     Memory: 1.4M
     CGroup: /system.slice/mosquitto.service
             └─155046 /usr/sbin/mosquitto -c /etc/mosquitto/mosquitto.conf

Nov 08 06:32:06 i-xxxxxxxxxxxxxx systemd[1]: Starting Mosquitto MQTT v3.1/v3.1.1 Broker...
Nov 08 06:32:06 i-xxxxxxxxxxxxxx mosquitto[155046]: 1604784726: Loading config file /etc/mosquitto/conf.>
Nov 08 06:32:06 i-xxxxxxxxxxxxxx mosquitto[155046]: [3169503.676688]~DLT~155046~INFO     ~FIFO /tmp/dlt >
Nov 08 06:32:06 i-xxxxxxxxxxxxxx systemd[1]: Started Mosquitto MQTT v3.1/v3.1.1 Broker.

Arduino側の証明書の更新

Arduino(esp32)側のWiFiClientSecure側に /etc/mosquitto/certs/ca.crt の内容を証明書として取り込んでファームウェアを更新します。

Arduino(esp8266)の場合には、証明書の検証ではなく、フィンガープリントの検証でサーバを確認しているので、

root@i-xxxxxxxxxxxxxx:/etc/mosquitto/certs# openssl x509 -sha1 -fingerprint -noout -in server.crt
SHA1 Fingerprint=xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx

として取得したフィンガープリントをファームウェアのソースコードに取り込んでファームウェアを更新します。

Linux上でのクライアント接続

以下のように、オプションに –cafile server.crt を追加してサーバ証明書を指定して接続します。

$ mosquitto_sub -t '/#' -h example.com -p 8883 -u ユーザ名 -P パスワード --cafile server.crt

–cafile オプションは ~/.config/mosquitto_sub にする際は以下のようにフルパスが必要(~は使えない)なようです。(考えてみれば、~はシェルの機能なのであたり前ですね・・)

-h example.com
-p 8883
-u MQTTユーザ名
-P MQTTパスワード
--cafile /home/ユーザー名/.config/mosquitto/server.crt

これで、コマンドラインから、

$ mosquitto_sub -t '/#'

といった感じでsubscribeできます。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)