Ubuntu18.04にMosquittoMQTTメッセージングブローカーをインストールして保護する方法
序章
MQTT は、マシンツーマシンメッセージングプロトコルであり、「モノのインターネット」デバイスへの軽量のパブリッシュ/サブスクライブ通信を提供するように設計されています。 これは一般的に、車両の地理追跡、ホームオートメーション、環境センサーネットワーク、およびユーティリティ規模のデータ収集に使用されます。
Mosquitto は人気のあるMQTTサーバー(またはMQTT用語ではブローカー)であり、優れたコミュニティサポートを備えており、インストールと構成が簡単です。
このチュートリアルでは、Mosquittoをインストールし、SSLを使用してパスワードで保護されたMQTT通信を保護するようにブローカーを設定します。
前提条件
このチュートリアルを開始する前に、次のものが必要です。
- このUbuntu18.04サーバーセットアップチュートリアルで詳しく説明されているように、root以外のsudo対応ユーザーと基本的なファイアウォールがセットアップされたUbuntu18.04サーバー。
- DigitalOcean を使用してホスト名を設定する方法に従って、サーバーを指すドメイン名。 このチュートリアルでは、全体を通して
mqtt.example.com
を使用します。 - Certbotツールを使用して生成された、ドメインおよびMosquittoで使用するための自動更新可能なLet'sEncryptSSL証明書。 これを設定する方法については、 Certbotスタンドアロンモードを使用して、Ubuntu18.04でLet'sEncryptSSL証明書を取得する方法をご覧ください。 手順4で、
systemctl restart mosquitto
をrenew_hook
として追加できます。 前の前提条件の手順で構成したものと同じドメインを使用してください。
ステップ1—Mosquittoのインストール
Ubuntu 18.04のデフォルトのソフトウェアリポジトリにはかなり新しいバージョンのMosquittoがあるため、そこからインストールできます。
まず、root以外のユーザーを使用してログインし、apt update
を使用してパッケージリストを更新します。
sudo apt update
次に、apt install
を使用してMosquittoをインストールします。
sudo apt install mosquitto mosquitto-clients
デフォルトでは、Ubuntuはインストール後にMosquittoサービスを開始します。 デフォルト設定をテストしてみましょう。 インストールしたばかりのMosquittoクライアントの1つを使用して、ブローカーのトピックをサブスクライブします。
トピックは、メッセージを公開およびサブスクライブするラベルです。 これらは階層として配置されているため、たとえばsensors/outside/temp
とsensors/outside/humidity
を使用できます。 トピックをどのように配置するかは、あなたとあなたのニーズ次第です。 このチュートリアル全体を通して、簡単なテストトピックを使用して構成の変更をテストします。
サーバーにもう一度ログインすると、2つの端末が並んでいます。 新しいターミナルで、mosquitto_sub
を使用して、テストトピックをサブスクライブします。
mosquitto_sub -h localhost -t test
-h
はMQTTサーバーのホスト名を指定するために使用され、-t
はトピック名です。 mosquitto_sub
はメッセージの到着を待機しているため、ENTER
を押しても出力は表示されません。 他の端末に戻り、メッセージを公開します。
mosquitto_pub -h localhost -t test -m "hello world"
mosquitto_pub
のオプションは、mosquitto_sub
と同じですが、今回は追加の-m
オプションを使用してメッセージを指定します。 ENTER
を押すと、もう一方の端末に helloworldがポップアップ表示されます。 最初のMQTTメッセージを送信しました。
2番目の端末にCTRL+C
と入力して、mosquitto_sub
を終了しますが、サーバーへの接続は開いたままにします。 ステップ5の別のテストに再び使用します。
次に、パスワードベースの認証を使用してインストールを保護します。
ステップ2—MQTTパスワードの設定
パスワードを使用するようにMosquittoを構成しましょう。 Mosquittoには、mosquitto_passwd
という特別なパスワードファイルを生成するユーティリティが含まれています。 このコマンドは、指定されたユーザー名のパスワードを入力するように求め、結果を/etc/mosquitto/passwd
に配置します。
sudo mosquitto_passwd -c /etc/mosquitto/passwd sammy
次に、Mosquittoの新しい構成ファイルを開き、このパスワードファイルを使用してすべての接続にログインを要求するように指示します。
sudo nano /etc/mosquitto/conf.d/default.conf
これにより、空のファイルが開きます。 次のように貼り付けます。
/etc/mosquitto/conf.d/default.conf
allow_anonymous false password_file /etc/mosquitto/passwd
ファイルの最後に必ず末尾の改行を残してください。
allow_anonymous false
は、認証されていないすべての接続を無効にし、password_file
行は、ユーザーとパスワードの情報を探す場所をMosquittoに指示します。 ファイルを保存して終了します。
次に、Mosquittoを再起動して、変更をテストする必要があります。
sudo systemctl restart mosquitto
パスワードなしでメッセージを公開してみてください。
mosquitto_pub -h localhost -t "test" -m "hello world"
メッセージは拒否する必要があります:
OutputConnection Refused: not authorised. Error: The connection was refused.
パスワードで再試行する前に、2番目のターミナルウィンドウに再度切り替えて、今回はユーザー名とパスワードを使用して「テスト」トピックにサブスクライブします。
mosquitto_sub -h localhost -t test -u "sammy" -P "password"
接続して座って、メッセージを待つ必要があります。 テストメッセージを定期的に送信するため、チュートリアルの残りの部分では、この端末を開いたまま接続したままにしておくことができます。
次に、ユーザー名とパスワードを使用して、他の端末でメッセージを公開します。
mosquitto_pub -h localhost -t "test" -m "hello world" -u "sammy" -P "password"
メッセージはステップ1のように通過するはずです。 Mosquittoにパスワード保護を追加しました。 残念ながら、インターネットを介して暗号化されていないパスワードを送信しています。 次に、SSL暗号化をMosquittoに追加して修正します。
ステップ3—MQTTSSLの構成
SSL暗号化を有効にするには、Let'sEncrypt証明書が保存されている場所をMosquittoに通知する必要があります。 以前に開始した構成ファイルを開きます。
sudo nano /etc/mosquitto/conf.d/default.conf
ファイルの最後に次のように貼り付けて、すでに追加した2行を残します。
/etc/mosquitto/conf.d/default.conf
. . . listener 1883 localhost listener 8883 certfile /etc/letsencrypt/live/mqtt.example.com/cert.pem cafile /etc/letsencrypt/live/mqtt.example.com/chain.pem keyfile /etc/letsencrypt/live/mqtt.example.com/privkey.pem
繰り返しになりますが、ファイルの最後に必ず末尾の改行を残してください。
2つの別々のlistener
ブロックを構成に追加します。 最初のlistener 1883 localhost
は、ポート1883
のデフォルトのMQTTリスナーを更新します。これは、これまで接続してきたものです。 1883
は、暗号化されていない標準のMQTTポートです。 行のlocalhost
部分は、Mosquittoにこのポートをローカルホストインターフェイスにのみバインドするように指示しているため、外部からアクセスすることはできません。 とにかく外部リクエストはファイアウォールによってブロックされていたでしょうが、明示的にするのは良いことです。
listener 8883
は、ポート8883
に暗号化されたリスナーを設定します。 これはMQTT+SSLの標準ポートであり、MQTTSと呼ばれることもあります。 次の3行、certfile
、cafile
、およびkeyfile
はすべて、Mosquittoが適切なLet'sEncryptファイルをポイントして暗号化された接続を設定します。
ファイルを保存して終了し、Mosquittoを再起動して設定を更新します。
sudo systemctl restart mosquitto
ポート8883
への接続を許可するようにファイアウォールを更新します。
sudo ufw allow 8883
OutputRule added Rule added (v6)
次に、mosquitto_pub
を使用して、SSLのいくつかの異なるオプションを使用して再度テストします。
mosquitto_pub -h mqtt.example.com -t test -m "hello again" -p 8883 --capath /etc/ssl/certs/ -u "sammy" -P "password"
localhost
の代わりに完全なホスト名を使用していることに注意してください。 SSL証明書はmqtt.example.com
に対して発行されているため、localhost
に安全に接続しようとすると、ホスト名が証明書のホスト名と一致しないというエラーが表示されます(両方が同じMosquittoサーバー)。
--capath /etc/ssl/certs/
は、mosquitto_pub
のSSLを有効にし、ルート証明書を探す場所を指示します。 これらは通常、オペレーティングシステムによってインストールされるため、Mac OS、Windowsなどではパスが異なります。 mosquitto_pub
は、ルート証明書を使用して、Mosquittoサーバーの証明書がLet'sEncrypt認証局によって適切に署名されていることを確認します。 mosquitto_pub
およびmosquitto_sub
は、標準のセキュアに接続している場合でも、このオプション(または同様の--cafile
オプション)なしではSSL接続を試行しないことに注意してください。 8883
のポート。
テストがすべてうまくいくと、helloagainがもう一方のmosquitto_sub
ターミナルに表示されます。 これは、サーバーが完全にセットアップされていることを意味します。 MQTTプロトコルを拡張してWebSocketで動作するようにする場合は、最後の手順に従うことができます。
ステップ4— Websocketを介したMQTTの構成(オプション)
Webブラウザ内からJavaScriptを使用してMQTTを話すために、プロトコルは標準のWebSocketで機能するように調整されました。 この機能が必要ない場合は、この手順をスキップできます。
Mosquitto構成にlistener
ブロックをもう1つ追加する必要があります。
sudo nano /etc/mosquitto/conf.d/default.conf
ファイルの最後に、以下を追加します。
/etc/mosquitto/conf.d/default.conf
. . . listener 8083 protocol websockets certfile /etc/letsencrypt/live/mqtt.example.com/cert.pem cafile /etc/letsencrypt/live/mqtt.example.com/chain.pem keyfile /etc/letsencrypt/live/mqtt.example.com/privkey.pem
繰り返しになりますが、ファイルの最後に必ず末尾の改行を残してください。
これは、ポート番号とprotocol websockets
行を除いて、前のブロックとほとんど同じです。 WebSocketを介したMQTTの公式の標準化されたポートはありませんが、8083
が最も一般的です。
ファイルを保存して終了し、Mosquittoを再起動します。
sudo systemctl restart mosquitto
次に、ファイアウォールでポート8083
を開きます。
sudo ufw allow 8083
この機能をテストするために、パブリックなブラウザーベースのMQTTクライアントを使用します。 そこにはいくつかありますが、 EclipsePahoJavaScriptクライアントはシンプルで簡単に使用できます。 ブラウザでPahoクライアントを開きます。 次のように表示されます。
次のように接続情報を入力します。
- Host は、Mosquittoサーバーのドメイン
mqtt.example.com
である必要があります。 - ポートは
8083
である必要があります。 - ClientIdはデフォルト値のjs-utility-DI1m6のままにしておくことができます。
- Pathはデフォルト値の/wsのままにしておくことができます。
- ユーザー名はMosquittoのユーザー名である必要があります。 ここでは、sammyを使用しました。
- Password は、選択したパスワードである必要があります。
残りのフィールドはデフォルト値のままにしておくことができます。
接続を押すと、PahoブラウザベースのクライアントがMosquittoサーバーに接続します。
メッセージを公開するには、メッセージの公開ペインに移動し、トピックをテストとして入力し、メッセージセクションにメッセージを入力します。 次に、公開を押します。 メッセージはmosquitto_sub
端末に表示されます。
結論
これで、パスワードで保護され、SSLで保護された安全なMQTTサーバーがセットアップされました。 これは、あなたが夢見ているどんなプロジェクトに対しても、堅牢で安全なメッセージングプラットフォームとして機能します。 MQTTプロトコルでうまく機能する一般的なソフトウェアとハードウェアには次のものがあります。
- OwnTracks 、携帯電話にインストールできるオープンソースの地理追跡アプリ。 OwnTracksは定期的に位置情報をMQTTサーバーに報告します。これを保存して地図に表示したり、アラートを作成して場所に基づいてIoTハードウェアをアクティブ化したりできます。
- Node-RED は、モノのインターネットを「配線」するためのブラウザベースのグラフィカルインターフェイスです。 あるノードの出力を別のノードの入力にドラッグすると、フィルターを介して、さまざまなプロトコル間で、データベースなどに情報をルーティングできます。 MQTTはNode-REDによって非常によくサポートされています。
- ESP8266 は、MQTT機能を備えた安価なwifiマイクロコントローラーです。 温度データをトピックに公開するために1つを接続するか、気圧トピックをサブスクライブして、嵐が来たときにブザーを鳴らすことができます。
これらは、MQTTエコシステムからのいくつかの人気のある例です。 プロトコルを話すハードウェアとソフトウェアはもっとたくさんあります。 お気に入りのハードウェアプラットフォームまたはソフトウェア言語がすでにある場合は、おそらくMQTT機能があります。 あなたの「もの」がお互いに話し合うのを楽しんでください!