序章

MQTT は、マシンツーマシンメッセージングプロトコルであり、「モノのインターネット」デバイスへの軽量のパブリッシュ/サブスクライブ通信を提供するように設計されています。 これは一般的に、車両の地理追跡、ホームオートメーション、環境センサーネットワーク、およびユーティリティ規模のデータ収集に使用されます。

Mosquitto は人気のあるMQTTサーバー(またはMQTT用語ではブローカー)であり、優れたコミュニティサポートを備えており、インストールと構成が簡単です。

このチュートリアルでは、Mosquittoをインストールし、Let’s EncryptからSSL証明書を取得し、SSLを使用してパスワードで保護されたMQTT通信を保護するようにブローカーを設定します。

前提条件

このチュートリアルを開始する前に、次のものが必要です。

  • このUbuntu16.04サーバーセットアップチュートリアルで詳しく説明されているように、root以外のsudo対応ユーザーと基本的なファイアウォールがセットアップされたUbuntu16.04サーバー。
  • DigitalOcean を使用してホスト名を設定する方法に従って、サーバーを指すドメイン名。 このチュートリアルでは、全体を通してmqtt.example.comを使用します。

ステップ1—Mosquittoのインストール

Ubuntu 16.04のデフォルトのソフトウェアリポジトリには、かなり新しいバージョンのMosquittoがあります。 root以外のユーザーでログインし、apt-getでMosquittoをインストールします。

  1. sudo apt-get install mosquitto mosquitto-clients

デフォルトでは、Ubuntuはインストール後にMosquittoサービスを開始します。 デフォルト設定をテストしてみましょう。 インストールしたばかりのMosquittoクライアントの1つを使用して、ブローカーのトピックをサブスクライブします。

トピックは、メッセージを公開およびサブスクライブするラベルです。 これらは階層として配置されているため、たとえばsensors/outside/tempsensors/outside/humidityを使用できます。 トピックをどのように配置するかは、あなたとあなたのニーズ次第です。 このチュートリアル全体を通して、簡単なテストトピックを使用して構成の変更をテストします。

サーバーにもう一度ログインすると、2つの端末が並んでいます。 新しいターミナルで、mosquitto_subを使用してテストトピックをサブスクライブします。

  1. mosquitto_sub -h localhost -t test

-hはMQTTサーバーのホスト名を指定するために使用され、-tはトピック名です。 mosquitto_subはメッセージの到着を待機しているため、ENTERを押しても出力は表示されません。 他の端末に戻り、メッセージを公開します。

  1. mosquitto_pub -h localhost -t test -m "hello world"

mosquitto_pubのオプションは、mosquitto_subと同じですが、今回は追加の-mオプションを使用してメッセージを指定します。 ENTERを押すと、もう一方の端末に helloworldがポップアップ表示されます。 最初のMQTTメッセージを送信しました。

2番目の端末にCTRL+Cと入力して、mosquitto_subを終了しますが、サーバーへの接続は開いたままにします。 ステップ5の別のテストに再び使用します。

次に、新しいLet’s EncryptクライアントであるCertbotを使用して、SSLでインストールを保護します。

ステップ2—証明書を暗号化するためのCertbotのインストール

Let’s Encryptは、自動化されたAPIを介して無料のSSL証明書を提供する新しいサービスです。 APIと通信できるクライアントはたくさんあり、Ubuntuのデフォルトリポジトリには公式クライアントが含まれていますが、少し古く、必要な重要な機能が1つ欠けています。

代わりに、UbuntuPPAまたはパーソナルパッケージアーカイブから公式クライアントをインストールします。 これらは、より最近の、またはよりあいまいなソフトウェアをパッケージ化する代替リポジトリです。 まず、リポジトリを追加します。

  1. sudo add-apt-repository ppa:certbot/certbot

同意するには、ENTERを押す必要があります。 その後、パッケージリストを更新して、新しいリポジトリのパッケージ情報を取得します。

  1. sudo apt-get update

そして最後に、certbotと呼ばれる公式のLet’sEncryptクライアントをインストールします。

  1. sudo apt-get install certbot

certbotがインストールされたので、それを実行して証明書を取得しましょう。

ステップ3—Certbotを実行する

certbotは、ドメインを制御していることを証明するために、Let’sEncryptAPIによって発行された暗号化の課題に答える必要があります。 これを実現するために、ポート80(HTTP)および/または443(HTTPS)を使用します。 ポート80のみを使用するので、今すぐそのポートでの着信トラフィックを許可しましょう。

  1. sudo ufw allow http
Output
Rule added

これで、Certbotを実行して証明書を取得できます。 --standaloneオプションを使用して、CertbotにHTTPチャレンジリクエストを独自に処理するように指示し、--standalone-supported-challenges http-01は通信をポート80に制限します。 -dは、証明書を取得するドメインを指定するために使用され、certonlyは、他の構成手順を実行せずに証明書を取得するようにCertbotに指示します。

  1. sudo certbot certonly --standalone --standalone-supported-challenges http-01 -d mqtt.example.com

コマンドを実行すると、電子メールアドレスを入力し、利用規約に同意するように求められます。 そうすると、プロセスが成功し、証明書がどこに保存されているかを示すメッセージが表示されます。

証明書を持っています。 次に、Certbotが期限切れになりそうになったときに自動的に更新するようにする必要があります。

ステップ4—Certbot自動更新の設定

Let’s Encryptの証明書は、90日間のみ有効です。 これは、ユーザーが証明書の更新プロセスを自動化することを奨励するためです。 定期的に実行するコマンドを設定して、期限切れの証明書を確認し、それらを自動的に更新する必要があります。

更新チェックを毎日実行するために、定期的なジョブを実行するための標準システムサービスであるcronを使用します。 crontabというファイルを開いて編集することにより、cronに何をすべきかを指示します。

  1. sudo crontab -e

テキストエディタを選択するように求められます。 お気に入りを選択すると、ヘルプテキストが含まれているデフォルトのcrontabが表示されます。 ファイルの最後に次の行を貼り付けて、保存して閉じます。

crontab
. . .
15 3 * * * certbot renew --noninteractive --post-hook "systemctl restart mosquitto"

この行の15 3 * * *の部分は、「毎日午前3時15分に次のコマンドを実行する」ことを意味します。 Certbotの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に配置します。

  1. sudo mosquitto_passwd -c /etc/mosquitto/passwd sammy

次に、Mosquittoの新しい構成ファイルを開き、このパスワードファイルを使用してすべての接続にログインを要求するように指示します。

  1. 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を再起動して、変更をテストする必要があります。

  1. sudo systemctl restart mosquitto

パスワードなしでメッセージを公開してみてください。

  1. mosquitto_pub -h localhost -t "test" -m "hello world"

メッセージは拒否する必要があります:

Output
Connection Refused: not authorised. Error: The connection was refused.

パスワードで再試行する前に、2番目のターミナルウィンドウに再度切り替えて、今回はユーザー名とパスワードを使用して「テスト」トピックにサブスクライブします。

  1. mosquitto_sub -h localhost -t test -u "sammy" -P "password"

接続して座って、メッセージを待つ必要があります。 テストメッセージを定期的に送信するため、チュートリアルの残りの部分では、この端末を開いたまま接続したままにしておくことができます。

次に、ユーザー名とパスワードを使用して、他の端末でメッセージを公開します。

  1. mosquitto_pub -h localhost -t "test" -m "hello world" -u "sammy" -P "password"

メッセージはステップ1のように通過するはずです。 Mosquittoにパスワード保護を追加しました。 残念ながら、暗号化されていないパスワードをインターネット経由で送信しています。 次に、SSL暗号化をMosquittoに追加して修正します。

ステップ6—MQTTSSLの構成

SSL暗号化を有効にするには、Let’sEncrypt証明書が保存されている場所をMosquittoに通知する必要があります。 以前に開始した構成ファイルを開きます。

  1. 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行、certfilecafile、およびkeyfileはすべて、Mosquittoが適切なLet’sEncryptファイルをポイントして暗号化された接続を設定します。

ファイルを保存して終了し、Mosquittoを再起動して設定を更新します。

  1. sudo systemctl restart mosquitto

ポート8883への接続を許可するようにファイアウォールを更新します。

  1. sudo ufw allow 8883
Output
Rule added

次に、mosquitto_pubを使用して、SSLのいくつかの異なるオプションを使用して再度テストします。

  1. 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で動作するようにする場合は、最後の手順に従うことができます。

ステップ7— Websocketを介したMQTTの構成(オプション)

Webブラウザ内からJavaScriptを使用してMQTTを話すために、プロトコルは標準のWebSocketで機能するように調整されました。 この機能が必要ない場合は、この手順をスキップできます。

Mosqiutto構成にlistenerブロックをもう1つ追加する必要があります。

  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を再起動します。

  1. sudo systemctl restart mosquitto

次に、ファイアウォールでポート8083を開きます。

  1. sudo ufw allow 8083

この機能をテストするために、パブリックなブラウザーベースのMQTTクライアントを使用します。 そこにはいくつかありますが、 EclipsePahoJavaScriptクライアントはシンプルで簡単に使用できます。 ブラウザでPahoクライアントを開きます。 次のように表示されます。

Paho Client Screen

次のように接続情報を入力します。

  • Host は、Mosquittoサーバーのドメインmqtt.example.comである必要があります。
  • ポート8083である必要があります。
  • ClientIdはデフォルト値のjs-utility-DI1m6のままにしておくことができます。
  • Pathはデフォルト値の/wsのままにしておくことができます。
  • ユーザー名はMosquittoユーザー名である必要があります。 ここでは、sammyを使用しました。
  • Password は、選択したパスワードである必要があります。

残りのフィールドはデフォルト値のままにしておくことができます。

接続を押すと、PahoブラウザベースのクライアントがMosquittoサーバーに接続します。

メッセージを公開するには、メッセージの公開ペインに移動し、トピックテストとして入力し、メッセージセクションにメッセージを入力します。 次に、公開を押します。 メッセージはmosquitto_sub端末に表示されます。

結論

Let’s EncryptサービスからのSSL証明書を自動更新することで、パスワードで保護された安全なMQTTサーバーをセットアップしました。 これは、あなたが夢見ているどんなプロジェクトに対しても、堅牢で安全なメッセージングプラットフォームとして機能します。 MQTTプロトコルでうまく機能する一般的なソフトウェアとハードウェアには次のものがあります。

  • OwnTracks 、携帯電話にインストールできるオープンソースの地理追跡アプリ。 OwnTracksは定期的に位置情報をMQTTサーバーに報告します。これを保存して地図に表示したり、アラートを作成して場所に基づいてIoTハードウェアをアクティブ化したりできます。
  • Node-RED は、モノのインターネットを「配線」するためのブラウザベースのグラフィカルインターフェイスです。 あるノードの出力を別のノードの入力にドラッグすると、フィルターを介して、さまざまなプロトコル間で、データベースなどに情報をルーティングできます。 MQTTはNode-REDによって非常によくサポートされています。
  • ESP8266 は、MQTT機能を備えた安価なwifiマイクロコントローラーです。 温度データをトピックに公開するために1つを接続するか、気圧トピックをサブスクライブして、嵐が来たときにブザーを鳴らすことができます。

これらは、MQTTエコシステムからのいくつかの人気のある例です。 プロトコルを話すハードウェアとソフトウェアはもっとたくさんあります。 お気に入りのハードウェアプラットフォームまたはソフトウェア言語がすでにある場合は、おそらくMQTT機能があります。 あなたの「もの」がお互いに話し合うのを楽しんでください!