概要
MosquittoによるMQTTサーバに,TLSのクライアント証明書によってユーザ側の認証をするようにします.サーバの証明書ではなくクライアントの証明書です.
MQTTにおいてユーザ認証といえばユーザ名とパスワードですが,平文パスワードだけだとちょっと心配…という場合に導入してみるといいかもしれません.
MQTT自体の解説だったりサーバ構築の丁寧な解説は別の記事を参照してください.自分が構築した時に参照したサイトはいくつか参考文献に載っけておきます.
筆者はそこまで認証系に詳しいわけではないので間違いなどあれば指摘してくださると助かります.
動作確認環境
- Ubuntu Server 22.04 LTS (Broker, Client)
- mosquitto 2.0.11
- OpenSSL 3.0.2
- Mac OS Ventura 13.4.1
- mosquitto 2.0.18
準備
既にMosquittoのTLS対応をしたなどでCAができている場合は飛ばして大丈夫です.
- OpenSSLでオレオレ認証局を作ります.適当な作業ディレクトリを作って移動します.
mkdir cert cd cert
- CAの秘密鍵を作ります.パスフレーズが求められるので適当に決めます.
openssl genrsa -des3 out ca.key 2048
- CSRファイルを作成します.この時もいろいろ聞かれますが適当に答えます.
openssl req -new -key ca.key -out ca.csr -sha256
ここまででいったん準備完了.理論上これで一応動きますが,他記事をみてサーバの方の証明書も作っておくことを推奨します(サーバ証明書なしでクライアント証明書のみの場合の動作検証はしてません).
クライアント証明書を作る.
- Q. そもそもクライアント証明書ってなんすか?
- A. サーバ側から見て,特定のクライアントのみ通信を許可したいときに,クライアントの身許をはっきりさせるために配る証明書.SSHの設定とかしてるなら公開鍵を配る感じに近い(というか実際は中身公開鍵認証だからほぼまんま公開鍵)
というわけで作っていきます.
- クライアント用の秘密鍵を作る.デバイス名は適当に決めてください.
openssl genrsa -out {デバイス名}.key 2048
- CSRファイルを作る.
openssl -req -new -key {デバイス名}.key -out {デバイス名}.csr
- クライアント証明書を作る.
コマンドのほとんどはサーバ証明書作るのと同じですが,後ろにadd-trust clientAuth
をつけるのを忘れずに!
openssl x509 -req -in {デバイス名}.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out {デバイス名}.crt -days 3650 -sha256 -addtrust clientAuth
これで,{デバイス名}.crt
, {デバイス名}.key
, {デバイス名}.csr
のみっつができました.
最後に,mosquitto.conf
ファイルの末尾に,
require_certificate true
を追加してサーバを再起動しましょう.
これで,MQTT Brokerに入るには,{デバイス名}.crt
, {デバイス名}.key
,それとca.crt
が必要になります.もしローカルではなくリモートで接続したければそちらのデバイスにこれらを渡しておきましょう.
接続してみる
一応,サーバ側の証明書もca.crtで作り,ポートを8883にしている想定です.また,カレントディレクトリに認証系のファイルを置いている想定です.条件に該当しない場合は適当に読み替えてください.
Subscribe
- ローカル実行
mosquitto_sub -p 8883 --cafile ca.crt --cert {デバイス名}.crt --key {デバイス名}.key -t {トピック} --insecure
--insecure
をつけるとCommon Nameとホスト名が違っていても無視してくれます.ローカル実行時はつけないとTLS Errorを吐くことが多いです.
- リモート実行
mosquitto_sub -h {ホスト名} -p 8883 --cafile ca.crt --cert {デバイス名}.crt --key {デバイス名}.key -t {トピック}
Publish
- ローカル実行
mosquitto_pub -p 8883 --cafile ca.crt --cert {デバイス名}.crt --key {デバイス名}.key -t {トピック} --insecure -m "{メッセージ}"
- リモート実行
mosquitto_pub -h {ホスト名} -p 8883 --cafile ca.crt --cert {デバイス名}.crt --key {デバイス名}.key -t {トピック} -m "{メッセージ}"
気が向いたらPythonなどから接続する方法を追記するかもしれないです.
参考文献
MQTT Essentials (Amazonページ)
Hillar, Gastón C. MQTT essentials - a lightweight IoT protocol : the preferred IoT publish-subscribe lightweight messaging protocol. 1st edition, Birmingham, England ;, Packt Publishing, 2017, ISBN1-78728-514-6.
サーバ構築に関して:
【Mosquitto】MQTTブローカの構築・動作確認 (ユーザ認証・TLS暗号化まで)
MQTTの概説・mosquittoの導入に関して:
【MQTT】MQTTの導入 mosquittoのインストール/動作確認まで