CentOS 7にMosquitto MQTT Messaging Brokerをインストールして保護する方法

前書き

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

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

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

前提条件

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

  • 非ルート、sudo対応ユーザー、および基本的なファイアウォールがセットアップされたCentOS 7サーバー。 これ(およびそれ以上)はすべてNew CentOS 7 Server Checklistでカバーされます。

  • How to Set Up a Host Name with DigitalOceanに従って、サーバーを指すドメイン名。 このチュートリアルでは、全体を通してmqtt.example.comを使用します。

  • オプションで、nanoテキストエディタ。 このチュートリアルでは全体でnanoを使用し、いつでもsudo yum -y install nanoを使用してインストールするか、お気に入りのテキストエディターに置き換えることができます。

[[step-1 -—- installing-mosquitto]] ==ステップ1—Mosquittoのインストール

CentOS 7には、デフォルトでmosquittoパッケージがありません。 それをインストールするには、まず、Enterprise LinuxのExtra PackagesまたはEPELと呼ばれる追加のソフトウェアリポジトリをインストールします。 このリポジトリには、CentOS、Red Hat、およびその他のエンタープライズ指向のLinuxディストリビューションに適切にインストールされる追加のソフトウェアがいっぱいです。

root以外のユーザーでログインし、yumパッケージマネージャーを使用してepel-releaseパッケージをインストールします。

sudo yum -y install epel-release

これにより、EPELリポジトリ情報がシステムに追加されます。 -yオプションは、プロセス全体を通じていくつかのプロンプトに自動的に「はい」と答えます。 これで、mosquittoパッケージをインストールできます。

sudo yum -y install mosquitto

パッケージにはシンプルなデフォルト構成が付属しているため、インストールをテストするために実行してみましょう。

sudo systemctl start mosquitto

また、システムを再起動したときに確実に起動するように、サービスを有効にする必要があります。

sudo systemctl enable mosquitto

それでは、デフォルトの構成をテストしましょう。 mosquittoパッケージには、いくつかのコマンドラインMQTTクライアントが付属しています。 そのうちの1つを使用して、ブローカーに関するトピックをサブスクライブします。

Topicsは、メッセージを公開およびサブスクライブするラベルです。 これらは階層として配置されているため、たとえば、sensors/outside/tempsensors/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クライアントであるCertbotを使用して、SSLでインストールを保護します。

[[step-2 -—- installing-and-running-certbot-for-let-39-s-encrypt-certificates]] ==ステップ2— Let’sEncrypt証明書用のCertbotのインストールと実行

Let's Encryptは、自動化されたAPIを介して無料のSSL証明書を提供する新しいサービスです。 公式のLet's EncryptクライアントはCertbotと呼ばれ、前のステップでインストールしたEPELリポジトリに含まれています。

yumを使用してCertbotをインストールします。

sudo yum -y install certbot

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

firewall-cmdを使用してHTTPサービスを追加します。

sudo firewall-cmd --permanent --add-service=http

ファイアウォールをリロードして、変更を有効にします。

sudo firewall-cmd --reload

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

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

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

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

[[step-3 -—- setting-up-certbot-automatic-renewals]] ==ステップ3—Certbot自動更新の設定

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

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

sudo EDITOR=nano crontab -e

EDITOR=nanoは、crontabファイルをnanoエディターで開きます。 デフォルトのviエディターを使用する場合は、オフのままにします。

これで、デフォルトの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を再起動して新しい証明書を取得します。

証明書の自動更新がすべて設定されたので、Mosquittoをより安全に設定することに戻ります。

[[step-4 -—- configuring-mqtt-passwords]] ==ステップ4—MQTTパスワードの構成

パスワードを使用するようにMosquittoを設定しましょう。 Mosquittoには、mosquitto_passwdと呼ばれる特別なパスワードファイルを生成するユーティリティが含まれています。 このコマンドは、指定されたユーザー名のパスワードを入力するように求め、結果を/etc/mosquitto/passwdに配置します。

sudo mosquitto_passwd -c /etc/mosquitto/passwd sammy

ここで、デフォルトの構成ファイルを置き換え、Mosquittoにこのパスワードファイルを使用してすべての接続にログインを要求するように指示します。 まず、既存のmosquitto.confを削除します。

sudo rm /etc/mosquitto/mosquitto.conf

そして、新しい空の設定を開きます。

sudo nano /etc/mosquitto/mosquitto.conf

以下に貼り付けます。

/etc/mosquitto/mosquitto.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にパスワード保護を追加しました。 残念ながら、暗号化されていないパスワードをインターネット経由で送信しています。 次に、MosquittoにSSL暗号化を追加して、これを修正します。

[[step-5 -—- configuring-mqtt-ssl]] ==ステップ5— MQTTSSLの構成

SSL暗号化を有効にするには、Let's Encrypt証明書の保存場所をMosquittoに伝える必要があります。 以前に開始した構成ファイルを開きます。

sudo nano /etc/mosquitto/mosquitto.conf

ファイルの最後に以下を貼り付けて、追加した2行を残します。

/etc/mosquitto/mosquitto.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部分は、このポートをlocalhostインターフェイスにのみバインドするようにMosquittoに指示しているため、外部からアクセスすることはできません。 いずれにせよ、外部リクエストはファイアウォールによってブロックされていたはずですが、明示するのは良いことです。

listener 8883は、ポート8883に暗号化されたリスナーを設定します。 これは、MQTT + SSLの標準ポートであり、MQTTSとも呼ばれます。 次の3行、certfilecafile、およびkeyfileはすべて、Mosquittoが適切なLet’sEncryptファイルをポイントして暗号化された接続をセットアップすることを示しています。

ファイルを保存して終了します。

Mosquittoを再起動して新しい構成をロードする前に、デフォルトのmosquittoサービスファイルで1つ修正する必要があります。 これは、systemdmosquittoの実行方法を決定するために使用するファイルです。 お気に入りのエディターで開きます。

sudo nano /etc/systemd/system/multi-user.target.wants/mosquitto.service

User=mosquittoという行を探して削除し、ファイルを保存して終了します。

Mosquittoは引き続きmosquittoユーザーとして実行されますが、最初に起動したときはroot特権があり、Let's Encrypt証明書(rootに制限されています)をロードできます。アクセス、セキュリティ上の理由から)。 証明書をロードした後、mosquittoユーザーにドロップダウンします。

systemd自体をリロードする必要があるため、サービスファイルに加えた変更が認識されます。

sudo systemctl daemon-reload

そして今、Mosquittoを再起動して設定を更新できます。

sudo systemctl restart mosquitto

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

sudo firewall-cmd --permanent --add-port=8883/tcp

そして、ファイアウォールをリロードします。

sudo firewall-cmd --reload

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

mosquitto_pub -h mqtt.example.com -t test -m "hello again" -p 8883 --cafile /etc/ssl/certs/ca-bundle.crt -u "sammy" -P "password"

localhostの代わりに完全なホスト名を使用していることに注意してください。 SSL証明書はmqtt.example.comに対して発行されるため、localhostに安全に接続しようとすると、ホスト名が証明書のホスト名と一致しないというエラーが表示されます(両方が同じモスキートを指している場合でも)サーバ)。

--cafile /etc/ssl/certs/ca-bundle.crtmosquitto_pubのSSLを有効にし、ルート証明書を探す場所を指示します。 これらは通常、オペレーティングシステムによってインストールされるため、Mac OS、Windowsなどではパスが異なります。 mosquitto_pubは、ルート証明書を使用して、Mosquittoサーバーの証明書がLet’sEncrypt認証局によって適切に署名されていることを確認します。 %の標準の安全なポートに接続している場合でも、mosquitto_pubmosquitto_subはこのオプション(または同様の--capathオプション)なしではSSL接続を試行しないことに注意することが重要です。 (t6)s。

すべてがテストに問題がなければ、hello againが他のmosquitto_subターミナルに表示されます。 これは、サーバーが完全にセットアップされたことを意味します! MQTTプロトコルを拡張してWebソケットで動作するようにしたい場合は、最後の手順に従ってください。

[[step-6 -—- configuring-mqtt-over-websockets-optional]] ==ステップ6— MQTT Over Websocketの設定(オプション)

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

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

sudo nano /etc/mosquitto/mosquitto.conf

ファイルの最後に、次を追加します。

/etc/mosquitto/mosquitto.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 firewall-cmd --permanent --add-port=8083/tcp

最後にもう一度ファイアウォールをリロードします。

sudo firewall-cmd --reload

この機能をテストするには、ブラウザベースの公開MQTTクライアントを使用します。 そこにはいくつかありますが、mqtt-adminは単純で単純です。 Open mqtt-admin in your browser。 以下が表示されます。

mqtt-admin’s initial screen

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

  • Protocolwsswebsocketsecureの略)である必要があります。

  • Hostは、Mosquittoサーバーのドメインmqtt.example.comである必要があります。

  • Port8083である必要があります。

  • UserはMosquittoのユーザー名である必要があります。ここでは、sammyを使用しました。

  • Passwordは選択したパスワードである必要があります。

  • ClientIdは、デフォルト値のmqtt-adminのままにしておくことができます。

Save Settingsを押すと、mqtt-adminはMosquittoサーバーに接続します。 次の画面で、Topictestとして入力し、Payloadのメッセージを入力して、Publishを押します。 メッセージはmosquitto_subターミナルに表示されます。

結論

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

  • OwnTracks、携帯電話にインストールできるオープンソースの地理追跡アプリ。 OwnTracksは定期的に位置情報をMQTTサーバーに報告します。MQTTサーバーは、マップに保存して表示したり、位置に基づいてアラートを作成してIoTハードウェアをアクティブにしたりできます。

  • Node-REDは、モノのインターネットを「配線」するためのブラウザベースのグラフィカルインターフェイスです。 あるノードの出力を別のノードの入力にドラッグすると、フィルターを介して、さまざまなプロトコル間で、データベースなどに情報をルーティングできます。 MQTTはNode-REDで非常によくサポートされています。

  • ESP8266は、MQTT機能を備えた安価なwifiマイクロコントローラーです。 温度データをトピックに公開するために配線するか、気圧のトピックにサブスクライブして、嵐が来ているときにブザーを鳴らすことができます!

これらは、MQTTエコシステムの一般的な例のほんの一部です。 プロトコルを話すハードウェアとソフトウェアがはるかに多くあります。 お気に入りのハードウェアプラットフォームまたはソフトウェア言語を既にお持ちの場合は、MQTT機能を備えている可能性があります。 あなたの「もの」が互いに話し合うのを楽しんでください!