Ubuntu 16.04にMosquitto MQTTメッセージングブローカーをインストールして保護する方法
Ubuntu 16.04を使用していませんか?別のバージョンまたはディストリビューションを選択してください。
紹介
MQTTは、機械間通信プロトコルであり、"モノのインターネット"デバイスへの軽量な発行/購読通信を提供するように設計されています。これは、車両のフリートを地理的に追跡したり、ホームオートメーション、環境センサーネットワーク、ユーティリティ規模のデータ収集に一般的に使用されます。
Mosquittoは人気のあるMQTTサーバー(MQTT用語ではブローカー)で、素晴らしいコミュニティサポートがあり、インストールと設定が簡単です。
このチュートリアルでは、Mosquittoをインストールし、Let's EncryptからSSL証明書を取得し、パスワード保護されたMQTT通信を安全にするためにSSLを使用するようにブローカーを設定します。
前提条件
このチュートリアルを始める前に、次のものが必要です:
- 非ルートのsudo権限を持つユーザーと基本的なファイアウォールが設定されたUbuntu 16.04サーバー、これはこのUbuntu 16.04サーバーセットアップチュートリアルで詳述されています。
- あなたのサーバーにポイントされたドメイン名は、DigitalOceanでホスト名を設定する方法に従います。このチュートリアルでは、すべての場面で
mqtt.example.comを使用します。
ステップ1 — Mosquittoのインストール
Ubuntu 16.04 は、デフォルトのソフトウェアリポジトリにかなり最近のバージョンの Mosquitto を持っています。非ルートユーザーでログインし、apt-getを使用して Mosquitto をインストールしてください。
- sudo apt-get 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 はトピック名です。ENTERを押した後は何も出力されないでしょう。なぜなら、mosquitto_sub はメッセージの到着を待っているからです。別のターミナルに切り替えてメッセージを公開してください:
- mosquitto_pub -h localhost -t test -m "hello world"
mosquitto_pubのオプションは、mosquitto_subと同じですが、今回は追加の-mオプションを使用してメッセージを指定します。ENTERを押すと、別のターミナルにhello worldが表示されるはずです。これで初めてのMQTTメッセージを送信しました!
mosquitto_subから抜け出すには、2番目のターミナルでCTRL+Cを入力しますが、サーバーへの接続は維持します。ステップ5の別のテストで再度使用します。
次に、Certbotを使用してSSLでインストールを保護します。これは新しいLet’s Encryptクライアントです。
ステップ2 — Let’s Encrypt証明書のためのCertbotのインストール
Let’s Encryptは、自動化APIを通じて無料のSSL証明書を提供する新しいサービスです。APIと対話できるクライアントが多くありますが、Ubuntuは公式クライアントをデフォルトリポジトリに含めていますが、少し古く、私たちが必要とする重要な機能が欠けています。
代わりに、UbuntuのPPA(Personal Package Archive)から公式クライアントをインストールします。これらは、より最近のものやあまり知られていないソフトウェアをパッケージ化した代替リポジトリです。まず、リポジトリを追加します。
- sudo add-apt-repository ppa:certbot/certbot
受け入れるにはENTERを押す必要があります。その後、新しいリポジトリのパッケージ情報を取得するために、パッケージリストを更新してください。
- sudo apt-get update
最後に、公式のLet's Encryptクライアントであるcertbotをインストールします。
- sudo apt-get install certbot
私たちは今、certbotをインストールしたので、それを実行して証明書を取得しましょう。
ステップ3 — Certbotの実行
certbotは、当社がドメインを制御していることを証明するために、Let’s Encrypt APIによって発行された暗号学的チャレンジに応答する必要があります。これを達成するために、80(HTTP)および/または443(HTTPS)のポートを使用します。私たちはポート80のみを使用するので、まずはそのポートへの受信トラフィックを許可しましょう:
- sudo ufw allow http
Rule added
これでCertbotを実行して証明書を取得できるようになりました。--standaloneオプションを使用して、CertbotにHTTPチャレンジリクエストを自分で処理するよう指示し、--standalone-supported-challenges http-01は通信をポート80に制限します。-dは証明書を取得したいドメインを指定するために使用され、certonlyは他の設定手順を行うことなく証明書を取得するようにCertbotに指示します。
- sudo certbot certonly --standalone --standalone-supported-challenges http-01 -d mqtt.example.com
コマンドを実行すると、メールアドレスを入力し、サービス利用規約に同意するように求められます。その後、プロセスが成功したことと証明書の保存場所についてのメッセージが表示されるはずです。
私たちは証明書を取得しました。今、証明書が期限切れになりそうなときにCertbotが自動的に更新することを確認する必要があります。
ステップ4 — Certbotの自動更新の設定
Let’s Encryptの証明書は90日間のみ有効です。これは、ユーザーが証明書の更新プロセスを自動化することを促すためです。期限切れの証明書をチェックし、自動的に更新するために定期的に実行されるコマンドを設定する必要があります。
毎日リニューアルチェックを実行するために、標準のシステムサービスであるcronを使用します。cronに何をするか指示するために、crontabと呼ばれるファイルを開いて編集します。
- sudo crontab -e
テキストエディタを選択するように促されます。お気に入りを選択すると、いくつかのヘルプテキストが含まれているデフォルトのcrontabが表示されます。次の行をファイルの最後に貼り付けて、保存して閉じてください。
. . .
15 3 * * * certbot renew --noninteractive --post-hook "systemctl restart mosquitto"
15 3 * * * の部分は「毎日午前3時15分に次のコマンドを実行する」という意味です。renew コマンドは、システムにインストールされているすべての証明書をチェックし、30日以内に期限切れになるものを更新します。--noninteractive は Certbot にユーザーの入力を待たないよう指示します。
--post-hook "systemctl restart mosquitto" は、新しい証明書を取得するためにMosquittoを再起動しますが、証明書が更新された場合のみです。このpost-hook機能は、古いバージョンのLet's Encryptクライアントが欠けていたものであり、なぜ我々がデフォルトのUbuntuリポジトリではなくPPAからインストールしたのかの理由です。これがなければ、実際に証明書が更新されていなくても、毎日Mosquittoを再起動しなければなりません。あなたのMQTTクライアントは自動で再接続するように設定されているべきですが、特に理由もなく毎日それらを中断するのは避けるべきです。
自動証明書更新がすべて整ったので、これからMosquittoの設定をより安全にすることに戻ります。
ステップ5 — 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
これで空のファイルが開くはずです。以下を貼り付けてください:
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"
そのメッセージは拒否されるべきです。
Connection Refused: not authorised.
Error: The connection was refused.
パスワードで再試行する前に、再び2番目のターミナルウィンドウに切り替え、今回はユーザー名とパスワードを使用して「test」トピックにサブスクライブしてください。
- 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にパスワード保護を正常に追加しました。しかし、残念ながら、私たちはインターネット上でパスワードを暗号化せずに送信しています。次に、MosquittoにSSL暗号化を追加してそれを修正します。
ステップ 6 — MQTT SSL の設定
SSL暗号化を有効にするためには、MosquittoにLet’s Encryptの証明書がどこに保存されているかを教える必要があります。以前に開始した設定ファイルを開いてください。
- sudo nano /etc/mosquitto/conf.d/default.conf
ファイルの最後に以下を貼り付けて、すでに追加した2行をそのままにしておいてください。
. . .
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にこのポートをlocalhostインターフェースにのみバインドするよう指示しているので、外部からアクセスできません。外部からのリクエストは、私たちのファイアウォールによっておそらくブロックされるでしょうが、明示的であることは良いことです。
listener 8883 はポート 8883 に暗号化されたリスナーを設定します。これは、MQTT + SSL の標準ポートで、通常は MQTTS と呼ばれます。次の3行、certfile、cafile、および keyfile は、Mosquitto に暗号化された接続を設定するために適切な Let’s Encrypt のファイルを指し示します。
ファイルを保存して終了し、設定を更新するためにMosquittoを再起動してください。
- sudo systemctl restart mosquitto
ファイアウォールを更新して、ポート8883への接続を許可します。
- sudo ufw allow 8883
Rule added
では、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's Encrypt証明書機関によって適切に署名されているかを検証します。このオプション(または類似の--cafileオプション)なしでは、mosquitto_pub と mosquitto_sub はSSL接続を試みないことに注意してください。たとえ標準のセキュアポート8883 に接続していてもです。
テストがうまくいけば、別の mosquitto_sub ターミナルに 再度こんにちは が表示されるでしょう。これは、あなたのサーバーが完全に設定されたことを意味します!MQTTプロトコルをWebSocketで動作させるように拡張したい場合は、最後のステップに従ってください。
ステップ7 — WebSocketを介したMQTTの設定(オプション)
ウェブブラウザー内でJavaScriptを使用してMQTTを話すために、プロトコルは標準のウェブソケットで動作するように適応されました。この機能が不要な場合は、このステップをスキップしても構いません。
私たちはMosquitto設定にもう1つのlistenerブロックを追加する必要があります。
- sudo nano /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の行が異なります。MQTT over websocketsのための公式な標準ポートはありませんが、8083が最も一般的です。
ファイルを保存して終了し、その後Mosquittoを再起動します。
- sudo systemctl restart mosquitto
さて、ファイアウォールでポート8083を開いてください。
- sudo ufw allow 8083
この機能をテストするために、公開のブラウザベースのMQTTクライアントを使用します。いくつかのオプションがありますが、Eclipse Paho JavaScriptクライアントはシンプルで使いやすいです。ブラウザでPahoクライアントを開いてください。次のような画面が表示されます:
接続情報を次のように記入してください:
- ホストは、あなたのMosquittoサーバーのドメインである必要があります。
mqtt.example.com。 - ポートは
8083であるべきです。 - ClientId はデフォルト値のjs-utility-DI1m6にしておくことができます。
- パスはデフォルト値の/wsにしておくことができます。
- ユーザー名はあなたのMosquittoのユーザー名にする必要があります。ここではサミーを使用しました。
- パスワードはあなたが選んだパスワードである必要があります.
残りのフィールドはデフォルト値のままで問題ありません。
接続を押した後、PahoのブラウザベースのクライアントはあなたのMosquittoサーバーに接続します。
メッセージを公開するには、Publish Messageペインに移動し、Topicをtestとして記入し、Messageセクションに任意のメッセージを入力します。次に、Publishを押します。そのメッセージはあなたのmosquitto_subターミナルに表示されます。
結論
私たちは現在、Let’s Encryptサービスからの自動更新SSL証明書を用いた、安全でパスワード保護されたMQTTサーバーを設置しました。これは、あなたが思いつくプロジェクトのための強力で安全なメッセージングプラットフォームとして機能します。MQTTプロトコルとよく互換性のある人気のあるソフトウェアとハードウェアには以下が含まれます:
- OwnTracksは、あなたの携帯電話にインストールできるオープンソースのGeoトラッキングアプリです。OwnTracksは定期的にあなたの位置情報をMQTTサーバーに報告し、その情報を保存して地図に表示したり、位置に基づいてアラートを作成したりIoTハードウェアを起動したりすることができます。
- Node-REDは、モノのインターネットを「配線」するためのブラウザベースのグラフィカルインターフェースです。一つのノードの出力を別のノードの入力にドラッグし、フィルターを介して、さまざまなプロトコル間、データベースに情報をルーティングすることができます。MQTTはNode-REDによって非常によくサポートされています。
- ESP8266はMQTT機能を備えた低価格のWi-Fiマイクロコントローラーです。温度データをトピックに公開するために接続することもできますし、もしかしたら気圧のトピックに登録して嵐が来るときにブザーを鳴らすこともできます!
これはMQTTエコシステムからの人気のある例のいくつかに過ぎません。このプロトコルを話すハードウェアやソフトウェアは他にもたくさんあります。すでにお気に入りのハードウェアプラットフォームやソフトウェア言語がある場合、それはおそらくMQTT機能を備えています。あなたの「モノ」が互いに話し合うのを楽しんでください!

