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できます。