概要
MQTTブローカーは、IoTデバイスやアプリケーション間のメッセージ通信を仲介する重要なコンポーネントである。
出版社と購読者の関係に似たPublish / Subscribeモデルを採用しており、各デバイスやアプリケーションはブローカーを介してメッセージをやり取りする。
ブローカーの主な役割は、発行されたメッセージを適切な購読者に配信することである。
例えば、温度センサがデータを発行すると、そのトピックを購読している全てのクライアントにブローカーが自動的にメッセージを転送する。
セキュリティ面では、ユーザ認証や暗号化通信をサポートしており、機密性の高い情報でも安全に扱うことができる。
また、QoS (Quality of Service) レベルを設定することにより、メッセージの配信保証レベルを制御できる。
人気のあるMQTTブローカーとしては、Mosquitto、HiveMQ、EMQX等がある。
これらはオープンソースで提供されており、小規模なプロジェクトから大規模な商用システムまで幅広く利用されている。
ブローカーの特徴的な機能として、トピックベースのフィルタリングがある。
トピックは階層構造を持ち、ワイルドカードを使用することで柔軟なメッセージのルーティングが可能である。
例えば、"sensors / temperature/+"というトピックを購読することで、全ての温度センサからのデータを受信できる。
また、多くのブローカーは永続化機能を備えており、クライアントが一時的にオフラインになった場合でも、メッセージを保持して、再接続時に配信することができる。
これにより、不安定なネットワーク環境でも確実なメッセージングが実現できる。
スケーラビリティの面では、クラスタリングやロードバランシングをサポートしているブローカーも多く、大規模なIoTシステムの構築も可能である。
MQTTブローカーは、IoTシステムにおける中心的な役割を果たしており、効率的で信頼性の高いメッセージング基盤を提供する。
メッセージングの基本的なフロー
下図では、MQTTの非同期メッセージング方式、および、1対多の通信パターンを表現している。
また下図において、以下に示す要素を表現している。
- Publisher (発行者) として温度センサと湿度センサを配置する。
- MQTTブローカーを配置する。
- Subscriber (購読者) として、データロガー、モニタリングアプリ、アラートシステムを配置する。
- また、トピックベースの通信 (sensors/tempやsensors/humidity)、ワイルドカードの使用 (sensors/+およびsensors/#) を示している。
パブリックMQTTブローカーサービス (無料 / 有料)
- HiveMQ Cloud (無料枠あり)
- 100台までのデバイス接続可能。
- TLS暗号化対応。
- 10[KB]/秒までのデータ転送可能。
- CloudMQTT (現在はUpstashの一部)
- スモールスケール向けの無料プラン有り。
- 管理画面が理解しやすい。
- セキュリティ設定が充実している。
- AWS IoT Core
- AWSの完全マネージドサービス
- 高度なセキュリティ機能
- 他のAWSサービスと連携可能
- 従量課金制
- test.mosquitto.org (テスト向けは無料)
- テストや学習用
- セキュリティの保証が無いため、本番環境での使用は非推奨である。
パブリックMQTTブローカーサービスとオンプレミスの比較
パブリックMQTTブローカーサービス
メリット
- すぐに利用開始可能
- 運用管理不要
- 高可用性
- 自動スケーリング
- セキュリティ対策済み
デメリット
- コストが発生 (規模による)
- カスタマイズの制限
- ベンダーロックイン
- データの管理場所に制約
オンプレミス
メリット
- コスト削減可能
- 完全なカスタマイズ制御
- データの完全な管理
- ネットワーク遅延の最適化
デメリット
- 保守運用の負担
- セキュリティ対策が必要となる。
- スケーリングの手間
- 可用性の確保が必要となる。
推奨される環境
開発を始める場合は、まず、パブリックサービスの無料枠を使用して、システムの動作確認や要件の明確化を行う。
その後、本番環境に適したソリューションを選択することを推奨する。
開発 / テスト段階
最初は、test.mosquitto.org や HiveMQ Cloudの無料枠を使用することを推奨する。
これは、素早く開発を始められ、かつ、コストがかからないからである。
小規模な本番環境の場合
HiveMQ Cloud や CloudMQTT の小規模プランを使用することを推奨する。
これは、運用の手間を省けることができ、コストが安いからである。
大規模な本番環境
AWS IoT Core 等のエンタープライズサービスを使用することを推奨する。
または、十分な運用体制がある場合は自身で構築する。
これは、スケーラビリティとセキュリティを重視する必要がある。
MQTTブローカーの構築 : オンプレミス
※運用時の注意
- 必ず匿名接続を無効にして、ユーザ認証を設定すること。
- 可能な限り、SSL/TLS通信を使用することを推奨する。
- 定期的にログを確認して、不正なアクセスがないか監視すること。
MQTTブローカーのインストール
# RHEL sudo dnf install mosquitto mosquitto-clients # SUSE sudo zypper install mosquitto mosquitto-clients # Raspberry Pi / PinePhone sudo apt install mosquitto mosquitto-clients
MQTTブローカーサービスを起動する。
sudo systemctl start mosquitto
必要であれば、MQTTブローカーサービスを自動起動に設定する。
sudo systemctl enable mosquitto
ファイアウォールの設定
MQTTブローカーの動作に必要なポートを開放する。
- 標準のMQTT通信用ポート
- TCP : 1883
- SSL/TLS暗号化通信用ポート
- TCP : 8883
sudo firewall-cmd --permanent --add-port=1883/tcp sudo firewall-cmd --permanent --add-port=8883/tcp sudo firewall-cmd --reload
ユーザとパスワードの設定
まず、MQTTユーザを追加する。
次に、パスワード (プロンプトが表示される) を入力する。
sudo mosquitto_passwd -c /etc/mosquitto/passwd <初めて登録するユーザ名>
※注意
追加のユーザを作成する場合は、-cオプションは付加しないこと。
-cオプションは、既存ファイルを上書きするためである。
sudo mosquitto_passwd /etc/mosquitto/passwd <追加するユーザ名>
Mosquittoの設定
まず、Mosquittoの設定ファイルを作成する。
sudo vi /etc/mosquitto/conf.d/default.conf
次に、Mosquittoの設定を記述する。
# ポート設定 listener 1883 # 匿名接続の許可 / 不許可 allow_anonymous false # パスワードファイルの指定 password_file /etc/mosquitto/passwd
セキュリティ設定 (推奨)
TLS/SSL通信を有効にする。
# SSL/TLS証明書の作成
sudo mkdir /etc/mosquitto/certs
cd /etc/mosquitto/certs
# 証明書ファイルを作成する
# 出力する秘密鍵ファイルは、絶対に外部に漏れないよう、適切なパーミッションで保護する必要がある
# 実行時において、以下の情報の入力を求められる
## Country Name (2文字の国コード)
## State or Province Name (都道府県名)
## Locality Name (市区町村名)
## Organization Name (組織名)
## Organizational Unit Name (部門名)
## Common Name (サーバのFQDNやドメイン名)
## Email Address (メールアドレス)
sudo openssl req -new -x509 \
-days <証明書の有効期限日数 例: 365> \
-extensions v3_ca \ # X.509 v3 CA拡張を使用(CAとしての役割を示す)
-keyout <出力する秘密鍵ファイル 例: ca.key> \
-out <出力する証明書ファイル 例: ca.crt>
# サーバ向けRSA秘密鍵を生成する
# 鍵の長さ (ビット数) を指定
# 2048ビットは現在の標準的なセキュリティレベル
# 4096ビットはより強力なセキュリティが必要な場合に使用
sudo openssl genrsa -out <生成した鍵の保存先 例: server.key> 2048
# 証明書署名要求 (CSR) を作成する
sudo openssl req -new -out <CSRの出力先 例: server.csr> -key <使用する秘密鍵の指定 例: server.key>
# CSRに対してCA証明書で署名して、サーバ証明書を作成する
sudo openssl x509 -req \
-in <署名対象のCSRファイル 例: server.csr> \
-CA <署名に使用するCA証明書 例: ca.crt> \
-CAkey <CA証明書の秘密鍵ファイル 例: ca.key> \
-CAcreateserial \ # シリアル番号ファイルの作成
-out <生成される証明書の出力先 例: server.crt> \
-days <証明書の有効期限日数 例: 365>
上記のコマンドを実行することにより、以下に示すファイル群が生成される。
- ca.key
- CA (証明局) の秘密鍵
- ca.crt
- CA (証明局) の証明書
- server.key
- サーバの秘密鍵
- server.csr
- 証明書署名要求
- server.crt
- サーバの証明書
※注意
秘密鍵 (.keyファイル) は、絶対に外部に漏れないように、適切なパーミッションで保護する必要がある。
本番環境では、これらのファイルは安全な場所に保管して、定期的な更新を行うことを推奨する。
SSL/TLS証明書ファイルをMQTTの設定ファイルに記述する。
# SSL/TLS証明書の設定 listener 8883 cafile /etc/mosquitto/certs/ca.crt certfile /etc/mosquitto/certs/server.crt keyfile /etc/mosquitto/certs/server.key tls_version tlsv1.2
動作確認
サブスクライバー (購読者) の起動
mosquitto_sub -h <IPアドレスまたはホスト名 例: localhost> -t <購読するトピック 例: "test/topic"> -u <MQTTユーザ名> -P <MQTTユーザ名のパスワード>
# または
mosquitto_sub -h <IPアドレスまたはホスト名 例: localhost> -t <購読するトピック 例: "sensors/#"> -v
# QoSを指定する場合
# QoS 1を使用
mosquitto_sub -h <IPアドレスまたはホスト名 例: localhost> -t <購読するトピック 例: "important/data"> -q 1
# SSL/TLS証明書を使用してサブスクライブ
mosquitto_sub -h <IPアドレスまたはホスト名 例: localhost> \
-t <購読するトピック 例: "secure/topic"> \
-p 8883 \
--cafile /etc/mosquitto/certs/ca.crt \
--tls-version tlsv1.2
- mosquitto_subコマンド
- MQTTメッセージを購読 (受信) するためのコマンドラインツールである。
- -hオプション
- 接続先のMQTTブローカーのIPアドレスまたはホスト名を指定する。
- localhostを指定する場合は、同じPC上のブローカーに接続される。
- 別のサーバを指定する場合は、IPアドレスやドメイン名を指定する。
- -tオプション
- 購読するトピックを指定する。
- トピックは階層構造を持つことができる。
- トピックの例 : home/livingroom/temperature
- -uオプション
- 認証用のユーザ名を指定する。
- -Pオプション
- 認証用のパスワードを指定する。
その他のオプションを以下に示す。
- -vオプション
- 受信メッセージと共にトピック名も表示する。
- -qオプション
- QoSレベルを指定する。
- 指定できる値は、0、1、2のいずれかである。
- --tls-versionオプション
- TLSバージョンを指定する。
- --cafile
- CA証明書ファイルを指定する。
パブリッシャー (発行者) の実行
mosquitto_pub -h <IPアドレスまたはホスト名> -t test/topic -m "<メッセージ内容 例: Hello MQTT>" -u <MQTTユーザ名> -P <MQTTユーザ名のパスワード>