前書き
MQTTは、「モノのインターネット」デバイスへの軽量なパブリッシュ/サブスクライブ通信を提供するために設計されたマシンツーマシンメッセージングプロトコルです。 一般的には、車両のジオトラッキング車両、ホームオートメーション、環境センサーネットワーク、ユーティリティスケールのデータ収集に使用されます。
Mosquittoは人気のあるMQTTサーバー(またはMQTT用語では_broker_)であり、優れたコミュニティサポートがあり、インストールと構成が簡単です。
このチュートリアルでは、Mosquittoをインストールし、Let’s EncryptからSSL証明書を取得し、SSLを使用してパスワードで保護されたMQTT通信を保護するようにブローカーを設定します。
前提条件
このチュートリアルを開始する前に、次のものが必要です。
-
https://www.digitalocean.com/community/tutorials/initial-server-setup-with-debian-8 [このDebian 8サーバーセットアップチュートリアル]で詳しく説明されている、root以外のsudo対応ユーザーを持つDebian 8サーバー。
-
https://www.digitalocean.com/community/tutorials/how-to-set-up-a-firewall-with-ufw-on-ubuntu-14-04で説明されている「+ ufw 」で設定された基本的なファイアウォール[Ubuntu 14.04でUFWを使用してファイアウォールを設定する方法]。 Ubuntu中心のタイトルにもかかわらず、Debianにはデフォルトで ` ufw `が含まれていないため、最初に ` sudo apt-get install ufw +`を確認して、Debianをフォローできます。
-
https://www.digitalocean.com/community/tutorials/how-to-set-up-a-host-name-with-digitalocean [ホスト名をセットアップする方法]に従って、サーバーを指すドメイン名DigitalOcean]。 このチュートリアルでは、全体で「++」を使用します。
ステップ1-Mosquittoのインストール
Debianの `+ mosquitto +`パッケージは、必要な機能の一部をサポートしていないため、Mosquittoプロジェクトが提供する最新のリポジトリからインストールします。 まず、リポジトリ署名キーをダウンロードします。
wget http://repo.mosquitto.org/debian/mosquitto-repo.gpg.key
次に、 `+ apt-key +`でキーをインストールします。
sudo apt-key add mosquitto-repo.gpg.key
これにより、 `+ apt-get +`は、新しいリポジトリからインストールしたソフトウェアの整合性を検証できます。
次に、リポジトリURLを `+ / etc / apt / sources.list.d / `のファイルに追加して、ソフトウェアの場所を ` apt-get +`に伝えます。
sudo nano /etc/apt/sources.list.d/mosquitto.list
これにより、新しい空のファイルが開きます。 次の行をファイルに貼り付けます。
/etc/apt/sources.list.d/mosquitto.list
deb http://repo.mosquitto.org/debian jessie main
エディターを保存して閉じ、 `+ apt-get`で更新して新しいパッケージ情報を取り込みます。
sudo apt-get update
最後に、 `+ mosquitto +`パッケージとそのクライアントソフトウェアをインストールします。
sudo apt-get install mosquitto mosquitto-clients
デフォルトでは、Debianはインストール後にMosquittoサービスを開始します。 デフォルトの構成をテストしましょう。 インストールしたクライアントの1つを使用して、ブローカーのトピックをサブスクライブします。
_Topics_は、メッセージを発行および購読するラベルです。 これらは階層として配置されているため、たとえば、「+ sensors / outside / temp 」および「 sensors / outside / humidity +」を使用できます。 トピックの配置方法は、あなたとあなたのニーズ次第です。 このチュートリアルでは、簡単なテストトピックを使用して構成の変更をテストします。
サーバーに2回ログインすると、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 +`を押すと、他のターミナルに* hello world *ポップアップが表示されます。 最初のMQTTメッセージを送信しました!
2番目のターミナルで「+ CTRL + C 」を押して「 mosquitto_sub +」を終了しますが、サーバーへの接続は開いたままにします。 手順5の別のテストで再び使用します。
次に、新しいLet’s Encryptクライアントであるhttps://certbot.eff.org/[Certbot]を使用して、SSLでインストールを保護します。
ステップ2-証明書を暗号化するためのCertbotのインストール
Let’s Encryptは、自動化されたAPIを介して無料のSSL証明書を提供する新しいサービスです。 APIと通信できるクライアントは多数あり、Debianはデフォルトのリポジトリに公式クライアントを含めていますが、これは少し古く、必要な重要な機能が1つありません。
代わりに、Debianの `+ backports +`リポジトリからクライアントをインストールします。 これは、Debianのすでにリリースされたバージョンで選択可能なソフトウェアの新しいバージョンを利用できるようにする公式リポジトリです。 前のステップで行ったように、リポジトリをAPTソースリストに追加する必要があります。
まず、 `+ / etc / apt / sources.list.d / +`で新しいファイルを開きます。
sudo nano /etc/apt/sources.list.d/backports.list
次の行をファイルに貼り付けます。
/etc/apt/sources.list.d/backports.list
deb http://mirrors.digitalocean.com/debian jessie-backports main
ファイルを保存し、エディターを閉じます。 その後、パッケージ情報を更新します。
sudo apt-get update
そして最後に、Certbotと呼ばれる公式のLet’s Encryptクライアントをインストールし、APTにソースとして `+ jessie-backports +`を使用するよう指示します。
sudo apt-get install certbot -t jessie-backports
Certbotがインストールされたので、それを実行して証明書を取得しましょう。
ステップ3-Certbotの実行
Certbotは、ドメインを制御していることを証明するために、Let’s Encrypt APIによって発行された暗号化の課題に答える必要があります。 ポート + 80 +
(HTTP)および/または + 443 +
(HTTPS)を使用してこれを実現します。 ポート「80」のみを使用するため、そのポートで着信トラフィックを許可します。
sudo ufw allow http
OutputRule added
Rule added (v6)
これで、Certbotを実行して証明書を取得できます。 `-standalone +`オプションを使用して、CertbotにHTTPチャレンジリクエストを単独で処理するよう指示し、 `-standalone-supported-challenges http-01 `は通信をポート ` 80 `に制限します。 ` -d `は、証明書が必要なドメインを指定し、 ` certonly +`は、他の設定手順を行わずに証明書を取得するようにCertbotに指示します。
sudo certbot certonly --standalone --standalone-supported-challenges http-01 -d
コマンドを実行すると、メールアドレスを入力し、利用規約に同意するよう求められます。 そうすると、プロセスが正常に完了し、証明書が保存されている場所を示すメッセージが表示されます。
証明書を取得しました。 次に、Certbotが期限切れになったときに自動的に更新するようにする必要があります。
ステップ4-Certbot自動更新のセットアップ
Let’s Encryptの証明書は90日間のみ有効です。 これは、ユーザーが証明書の更新プロセスを自動化することを奨励するためです。 期限切れの証明書を定期的にチェックし、それらを自動的に更新するコマンドを設定する必要があります。
更新チェックを毎日実行するには、https://www.digitalocean.com/community/tutorials/how-to-use-cron-to-automate-tasks-on-a-vps [+ cron +
]を使用します。定期的なジョブを実行するための標準システムサービス。 `+ crontab `と呼ばれるファイルを開いて編集することにより、 ` cron +`に何をすべきかを伝えます。
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クライアントの古いバージョンに欠けていたものであり、デフォルトのDebianリポジトリではなくバックポートからインストールした理由です。 それなしでは、実際に証明書が更新されていなくても、Mosquittoを毎日再起動する必要があります。 MQTTクライアントは自動的に再接続するように設定する必要がありますが、正当な理由がないために毎日中断しないようにすることをお勧めします。
証明書の自動更新がすべて設定されたので、Mosquittoをより安全に設定することに戻ります。
ステップ5-MQTTパスワードの構成
パスワードを使用するようにMosquittoを設定して、メッセージを公開できるユーザーを制御できるようにします。 Mosquittoには、 `+ mosquitto_passwd `という特別なパスワードファイルを生成するユーティリティが含まれています。 このコマンドは、指定されたユーザー名のパスワードを入力するように促し、結果を ` / etc / mosquitto / passwd +`に配置します。
sudo mosquitto_passwd -c /etc/mosquitto/passwd
次に、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番目のターミナルウィンドウに再度切り替えて、今回はユーザー名とパスワードを使用して、* test *トピックにサブスクライブします。
mosquitto_sub -h localhost -t test -u "" -P ""
接続して座って、メッセージを待つ必要があります。 定期的にテストメッセージを送信するため、このターミナルを開いたままにしてチュートリアルの残りの部分で接続しておくことができます。
ユーザー名とパスワードを再度使用して、他の端末でメッセージを公開します。
mosquitto_pub -h localhost -t "test" -m "hello world" -u "" -P ""
メッセージはステップ1のように通過するはずです。 Mosquittoにパスワード保護を追加しました。 残念ながら、暗号化されていないパスワードをインターネット経由で送信しています。 次に、MosquittoにSSL暗号化を追加して、これを修正します。
ステップ6-MQTT SSLの構成
SSL暗号化を有効にするには、Let’s Encrypt証明書の保存場所を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//cert.pem
cafile /etc/letsencrypt/live//chain.pem
keyfile /etc/letsencrypt/live//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’s Encryptファイルを指し、暗号化された接続をセットアップします。
ファイルを保存して終了し、Mosquittoを再起動して設定を更新します。
sudo systemctl restart mosquitto
ファイアウォールを更新して、ポート「8883」への接続を許可します。
sudo ufw allow 8883
OutputRule added
Rule added (v6)
次に、SSLのいくつかの異なるオプションを使用して、 `+ mosquitto_pub +`を使用して再度テストします。
mosquitto_pub -h -t test -m "hello again" -p 8883 --capath /etc/ssl/certs/ -u "" -P ""
`+ localhost `の代わりに完全なホスト名を使用していることに注意してください。 SSL証明書は「+」に対して発行されるため、「+ localhost +」への安全な接続を試みると、ホスト名が証明書のホスト名と一致しないというエラーが表示されます(どちらも同じMosquittoサーバーを指している場合でも) 。
`-capath / etc / ssl / certs / +`は ` mosquitto_pub `のSSLを有効にし、ルート証明書を探す場所を指示します。 これらは通常、オペレーティングシステムによってインストールされるため、macOS、Windowsなどではパスが異なります。 ` mosquitto_pub`は、ルート証明書を使用して、Mosquitoサーバーの証明書がLet’s Encrypt認証局によって適切に署名されたことを確認します。 `+ mosquitto_pub `と ` mosquitto_sub `は、このオプション(または同様の `-cafile +`オプション)なしでは、標準のセキュアポート `+に接続している場合でもSSL接続を試行しないことに注意することが重要です。 8883 + `。
すべてがテストに合格すると、* hello again *が他の `+ mosquitto_sub +`ターミナルに表示されます。 これは、サーバーが完全にセットアップされたことを意味します! MQTTプロトコルを拡張してWebソケットで動作するようにしたい場合は、最後の手順に従ってください。
ステップ7-Websocket上のMQTTの構成(オプション)
Webブラウザ内からJavaScriptを使用してMQTTを話すために、プロトコルは標準のWebソケット上で動作するように適合されました。 この機能が必要ない場合は、この手順をスキップできます。
Mosqiuttoの設定にもう1つの `+ listener +`ブロックを追加する必要があります。
sudo nano /etc/mosquitto/conf.d/default.conf
ファイルの最後に、次を追加します。
/etc/mosquitto/conf.d/default.conf
. . .
listener 8083
protocol websockets
certfile /etc/letsencrypt/live//cert.pem
cafile /etc/letsencrypt/live//chain.pem
keyfile /etc/letsencrypt/live//privkey.pem
これは、ポート番号と `+ protocol websockets `行を除いて、前のブロックとほとんど同じです。 Websocketを介したMQTTの公式の標準化されたポートはありませんが、「 8083+」が最も一般的です。
ファイルを保存して終了し、Mosquittoを再起動します。
sudo systemctl restart mosquitto
ここで、ファイアウォールのポート「8083」を開きます。
sudo ufw allow 8083
この機能をテストするには、ブラウザベースの公開MQTTクライアントを使用します。 いくつかありますが、https://hobbyquaker.github.io/mqtt-admin/ [mqtt-admin]はシンプルで簡単です。 https://hobbyquaker.github.io/mqtt-admin/ [ブラウザでmqtt-adminを開きます]。 以下が表示されます。
image:https://assets.digitalocean.com/articles/mosquitto-debian/SJRJgLX.png [mqtt-adminの初期画面]
接続情報を次のように入力します。
-
* Protocol は wss *( w eb s ocket s ecureの略)でなければなりません。
-
* Host *は、Mosquittoサーバーのドメイン「++」である必要があります。
-
*ポート*は `+ 8083 +`でなければなりません。
-
* User はMosquittoユーザー名でなければなりません。ここでは、 sammy *を使用しました。
-
* Password *は、選択したパスワードです。
-
* ClientId はデフォルト値 mqtt-admin *のままにしておくことができます。
-
Save Settings *を押した後、 `+ mqtt-admin `はMosquittoサーバーに接続します。 次の画面で、*トピック*を*テスト*として入力し、*ペイロード*のメッセージを入力して、*公開*を押します。 メッセージは ` mosquitto_sub`ターミナルに表示されます。
結論
Let’s EncryptサービスからのSSL証明書を自動更新する、安全でパスワードで保護されたMQTTサーバーをセットアップしました。 これは、どんなプロジェクトを考えても、堅牢で安全なメッセージングプラットフォームとして機能します。 MQTTプロトコルで適切に動作する一般的なソフトウェアとハードウェアには次のものがあります。
-
OwnTracks、携帯電話にインストールできるオープンソースの地理追跡アプリ。 OwnTracksは定期的に位置情報をMQTTサーバーに報告します。MQTTサーバーは、マップに保存して表示したり、位置に基づいてアラートを作成してIoTハードウェアをアクティブにしたりできます。
-
Node-REDは、モノのインターネットを「配線」するためのブラウザベースのグラフィカルインターフェイスです。 あるノードの出力を別のノードの入力にドラッグすると、フィルターを介して、さまざまなプロトコル間で、データベースなどに情報をルーティングできます。 MQTTはNode-REDで非常によくサポートされています。
-
ESP8266は、MQTT機能を備えた安価なwifiマイクロコントローラーです。 温度データをトピックに公開するために配線するか、気圧のトピックにサブスクライブして、嵐が来ているときにブザーを鳴らすことができます!
これらは、MQTTエコシステムの一般的な例のほんの一部です。 プロトコルを話すハードウェアとソフトウェアがはるかに多くあります。 お気に入りのハードウェアプラットフォームまたはソフトウェア言語を既にお持ちの場合は、MQTT機能を備えている可能性があります。 あなたの「もの」が互いに話し合うのを楽しんでください!