Ubuntu 20.04にMosquitto MQTTメッセージングブローカーをインストールして保護する方法
Ubuntu 20.04にMosquitto MQTTメッセージングブローカーをインストールして保護する方法
このページで
- 前提条件
- ステップ1 - Mosquittoサーバーおよびクライアントをインストールする
- ステップ2 - MQTTパスワード認証の設定
- ステップ3 - Mosquittoクライアントをテストする
- ステップ4 - SSLをインストールする
- ステップ5 - MQTT SSLの設定
- ステップ6 - SSL更新の設定
- ステップ7 - ウェブソケットを設定する
- 結論
Mosquittoは、メッセージキューイングテレメトリトランスポート(MQTT)プロトコルを使用したオープンソースのメッセージブローカーです。このプロトコルは、モノのインターネット(IoT)デバイスへの軽量な通信を提供するために設計されています。一般的に、車両のGPS追跡、ホームオートメーション、環境センサー、そして大規模なデータ収集に使用されます。
MQTTプロトコルはTCP/IPモデルの上で動作します。軽量であるため、小さなコードフットプリントでリソースが最小限のデバイス用のアプリケーションを作成できます。それはパブリッシュ/サブスクライブモデルに依存しています。このモデルでは、クライアントがMosquittoサーバーに接続し、サーバーはブローカーとして機能して、チャネルにサブスクライブしている他のクライアントに情報を送信します。
このチュートリアルでは、Mosquittoをインストールし、通信を保護するためにSSLを使用するようにブローカーを設定します。
前提条件
- sudo権限を持つ非rootユーザーがいるUbuntu 20.04サーバー。
- あなたのサーバーに向けられたドメイン名(
myqtt.example.com)です。
ステップ1 - Mosquittoサーバーおよびクライアントをインストールする
Ubuntuは古い1.6バージョンのMosquittoを提供しています。最新のバージョンをインストールするには、公式のMosquittoリポジトリを追加してください。
sudo add-apt-repository ppa:mosquitto-dev/mosquitto-ppa
Mosquittoサーバーとクライアントをインストールします。
sudo apt install mosquitto mosquitto-clients
サーバーのステータスを確認してください。
sudo systemctl status mosquitto
? mosquitto.service - Mosquitto MQTT Broker
Loaded: loaded (/lib/systemd/system/mosquitto.service; enabled; vendor preset: enabled)
Active: active (running) since Tue 2022-01-25 09:18:40 UTC; 25s ago
Docs: man:mosquitto.conf(5)
man:mosquitto(8)
Main PID: 119694 (mosquitto)
Tasks: 1 (limit: 2274)
Memory: 1.0M
CGroup: /system.slice/mosquitto.service
??119694 /usr/sbin/mosquitto -c /etc/mosquitto/mosquitto.conf
Jan 25 09:18:39 <userid> systemd[1]: Starting Mosquitto MQTT Broker...
Jan 25 09:18:40 <userid> systemd[1]: Started Mosquitto MQTT Broker.
ステップ 2 - MQTT パスワード認証を設定する
Mosquittoには、mosquitto_passwdと呼ばれるパスワードファイルを生成するユーティリティが付属しています。Mosquittoは、すべての設定を/etc/mosquittoディレクトリに保存します。
/etc/mosquitto/passwdにユーザー名usernameのための暗号化されたパスワードファイルを生成するには、次のコマンドを実行してください。お好きなパスワードを入力してください。
sudo mosquitto_passwd -c /etc/mosquitto/passwd username
Password:
Reenter password:
次に、/etc/mosquitto/conf.d ディレクトリに default.conf ファイルを作成し、編集のために開きます。
sudo nano /etc/mosquitto/conf.d/default.conf
次の行を貼り付けて、パスワードファイルの場所を指定してください。リスナーフィールドを省略すると、構成に関係なく常に匿名で接続します。
listener 1883
password_file /etc/mosquitto/passwd
Ctrl + X を押してファイルを保存し、プロンプトが表示されたら Y を入力します。
変更を実装するためにMosquittoサーバーを再起動してください。
sudo systemctl restart mosquitto
ステップ3 - Mosquittoクライアントをテストする
使用ケースに応じて、Mosquittoクライアントを使用して異なるトピックでメッセージを送受信できます。クライアントは、サブスクライバーまたはパブリッシャーのいずれかです。
次のステップはトピックにサブスクライブすることです。MQTTプロトコルでは、トピックとはサーバー/ブローカーが接続されたクライアントに対してメッセージをフィルタリングするために使用する文字列を指します。ここに、ホームオートメーションアプリケーションで使用できるいくつかのサンプルトピックがあります。
- 家/照明/リビングルーム
- 家/ライト/キッチン
- 家/照明/主寝室
- 家/照明/子供の寝室
トピックにサブスクライブするには、mosquitto_sub -t コマンドを実行し、その後にトピックを付けます。例えば、home/lights/kitchen トピックにサブスクライブするには、次のコマンドを実行します。
mosquitto_sub -u username -P YOUR_PASSWORD -t "home/lights/kitchen"
既存のウィンドウを閉じないでください。次のコマンドを使用して、home/lights/kitchenトピックにメッセージを公開するために新しいターミナルウィンドウを開いてください。
mosquitto_pub -u username -P YOUR_PASSWORD -m "ON" -t "home/lights/kitchen"
最初のターミナルウィンドウに戻ると、ON ペイロードが受信されます。
ON
次に、2番目のターミナルから同じトピックについてOFFメッセージを送信してください。
mosquitto_pub -u username -P YOUR_PASSWORD -m "OFF" -t "home/lights/kitchen"
最初の端末には、新しく公開されたメッセージが表示されます。
ON
OFF
認証されていないコメントを送信しようとすると、失敗します。例えば、次のコマンドを試してください。
mosquitto_sub -t "home/lights/sitting_room"
Connection error: Connection Refused: not authorised.
推奨はされませんが、認証なしでコマンドを実行したい場合は、次の行を/etc/mosquitto/conf.d/default.confファイルに追加する必要があります。
allow_anonymous true
ステップ4 - SSLをインストールする
Let's Encryptを使ってSSL証明書をインストールするには、Certbotツールをダウンロードする必要があります。それにはSnapdパッケージインストーラーを使用します。
Snap インストーラーをインストールします。
sudo apt install snapd
Snapdのバージョンが最新であることを確認してください。
sudo snap install core
sudo snap refresh core
Certbotをインストールします。
sudo snap install --classic certbot
次のコマンドを使用して、Certbotコマンドが実行されるように、/usr/binディレクトリへのシンボリックリンクを作成します。
sudo ln -s /snap/bin/certbot /usr/bin/certbot
SSL証明書を生成する。
sudo certbot certonly --standalone --agree-tos --no-eff-email --staple-ocsp --preferred-challenges http -m [email -d mqtt.example.com
上記のコマンドは、サーバーの/etc/letsencrypt/live/mqtt.example.comディレクトリに証明書をダウンロードします。
ディフィー・ヘルマン群証明書を生成します。
sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
Let's Encryptの自動更新のために、チャレンジ用のWebルートディレクトリを作成します。
sudo mkdir -p /var/lib/letsencrypt
SSLを更新するためにCronジョブを作成します。これは毎日実行されて証明書を確認し、必要であれば更新します。それに先立って、まずはファイル/etc/cron.daily/certbot-renewを作成し、編集のために開きます。
sudo nano /etc/cron.daily/certbot-renew
次のコードを貼り付けてください。
#!/bin/sh
certbot renew --cert-name mqtt.example.com --webroot -w /var/lib/letsencrypt/
Ctrl + X を押してファイルを保存し、促されたらYと入力します。
タスクファイルの権限を変更して、実行可能にします。
sudo chmod +x /etc/cron.daily/certbot-renew
ステップ5 - MQTT SSLの設定
SSL証明書が準備できたので、Mosquittoにそれらへのアクセスを提供する必要があります。これには、Mosquittoがアクセスできる場所に証明書をコピーする必要があります。
sudo cp /etc/letsencrypt/live/mqtt.example.com/fullchain.pem /etc/mosquitto/certs/server.pem
sudo cp /etc/letsencrypt/live/mqtt.example.com/privkey.pem /etc/mosquitto/certs/server.key
インストール中に作成された mosquitto ユーザーに /etc/mosquitto/certs ディレクトリの所有権を変更します。
sudo chown mosquitto: /etc/mosquitto/certs
MosquittoのSSL暗号化を有効にする次のステップは、SSL証明書の場所を指定することです。設定ファイルを編集のために開いてください。
sudo nano /etc/mosquitto/conf.d/default.conf
ファイルの末尾に次のコードを貼り付けてください。
. . .
listener 8883
certfile /etc/mosquitto/certs/server.pem
cafile /etc/ssl/certs/ISRG_Root_X1.pem
keyfile /etc/mosquitto/certs/server.key
dhparamfile /etc/ssl/certs/dhparam.pem
ファイルを保存するには、Ctrl + X を押し、プロンプトが表示されたら Y を入力します。ファイルの最後に改行を残すことを忘れないでください。
listener 8883 部分は暗号化されたリスナーを設定します。これは MQTT + SSL の標準ポートで、MQTTS と呼ばれています。次の4行は SSL ファイルの場所を指定しています。
設定を更新するためにMosquittoを再起動してください。
sudo systemctl restart mosquitto
ポート8883への接続を許可するためにファイアウォールを更新する必要があります。
sudo ufw allow 8883
次に、mosquitto_pub コマンドを使って機能をテストする必要があります。
mosquitto_pub -h mqtt.example.com -t "home/lights/kitchen" -m "hello" -p 8883 --capath /etc/ssl/certs/ -u username -P YOUR_PASSWORD
ご覧のとおり、ポート番号やSSL証明書へのパスなど、いくつかの追加パラメータを含めています。SSLを使用する必要がある場合は、常に完全なホスト名、つまりmqtt.example.comを指定する必要があります。そうしないと、エラーが発生します。
毎回、--capathディレクティブを追加する必要があります。これは、Mosquittoクライアントにオペレーティングシステムによってインストールされたルート証明書を探すよう指示します。
ステップ6 - SSL更新の設定
Certbot は、証明書が期限切れになる前に自動的に更新します。しかし、更新された証明書を /etc/mosquitto/certs ディレクトリにコピーし、Mosquitto サービスを再起動するように指示する必要があります。
私たちはシェルスクリプトを作成することでそれを行います。mosquitto-copy.shというファイルを/etc/letsencrypt/renewal-hooks/deployディレクトリに作成してください。
sudo nano /etc/letsencrypt/renewal-hooks/deploy/mosquitto-copy.sh
以下のコードをそれに貼り付けます。MY_DOMAIN変数の値をあなたのドメインに置き換えます。$ {RENEWED_LINEAGE}変数は、更新時に/etc/letsencrypt/live/mqtt.example.comディレクトリを指します。
Set which domain this script will be run for
MY_DOMAIN=mqtt.example.com
Set the directory that the certificates will be copied to.
CERTIFICATE_DIR=/etc/mosquitto/certs
if [ "${RENEWED_DOMAINS}" = "${MY_DOMAIN}" ]; then
# Copy new certificate to Mosquitto directory
cp ${RENEWED_LINEAGE}/fullchain.pem ${CERTIFICATE_DIR}/server.pem
cp ${RENEWED_LINEAGE}/privkey.pem ${CERTIFICATE_DIR}/server.key
# Set ownership to Mosquitto
chown mosquitto: ${CERTIFICATE_DIR}/server.pem ${CERTIFICATE_DIR}/server.key
# Ensure permissions are restrictive
chmod 0600 ${CERTIFICATE_DIR}/server.pem ${CERTIFICATE_DIR}/server.key
# Tell Mosquitto to reload certificates and configuration
pkill -HUP -x mosquitto
fi
Ctrl + X を押してファイルを保存し、プロンプトが表示されたら Y を入力します。
ファイルを実行可能にしてください。
sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/mosquitto-copy.sh
このスクリプトは、証明書の更新が成功するたびに自動的に実行されます。
Mosquitto と Nginx のようなウェブサーバーを実行している場合、Certbot に更新前にサーバーを停止し、終了後に再起動するように指示する必要があります。そのためには、ファイル etc/letsencrypt/renewal/mqtt.example.com.conf を開いてください。
sudo nano /etc/letsencrypt/renewal/mqtt.example.com.conf
ファイルの最後に次の行を追加してください。使用しているウェブサーバーに応じてコマンドを変更してください。
pre_hook = systemctl stop nginx
post_hook = systemctl start nginx
Ctrl + X を押してファイルを保存し、促されたらYと入力します。
Certbotのドライランを実行して確認してください。
sudo certbot renew --dry-run
エラーが見当たらなければ、すべてが設定されていることを意味します.
ステップ7 - ウェブソケットを設定する
Mosquittoを設定して、Webソケット機能を使用してJavaScriptからブラウザ内でMQTTプロトコルを使用することができます。それを有効にするには、設定ファイルを開いてください。
sudo nano /etc/mosquitto/conf.d/default.conf
ファイルの末尾に次の行を貼り付けてください。
. . .
listener 8083
protocol websockets
certfile /etc/mosquitto/certs/server.pem
cafile /etc/ssl/certs/ISRG_Root_X1.pem
keyfile /etc/mosquitto/certs/server.key
dhparamfile /etc/ssl/certs/dhparam.pem
Ctrl + X を押してファイルを保存し、促されたらYと入力します。
気付けば、ポート番号とプロトコルのフィールドを除いて、SSLを有効にするために使用したのと同じブロックです。8083は、MQTTがWebSocketを介して通信するために最も一般的に使用されるポートです。
Mosquittoサービスを再起動してください。
sudo systemctl restart mosquitto
ポート8083を開いてください。
sudo ufw allow 8083
WebSocketの機能をテストするために、ブラウザベースのMQTTクライアントを使用する必要があります。利用可能なクライアントはたくさんありますが、私たちの目的のためにHiveMQ WebSocketクライアントを使用します。ブラウザでクライアントを起動すると、以下のようになります。
上のスクリーンショットに示されているように、フィールドを示された通りに入力してください。
- ホストはあなたのMosquittoサーバーのドメイン、mqtt.example.comであるべきです。
- ポートは8083であるべきです。
- ClientIDフィールドはそのままにしておくことができます。
- ユーザー名はあなたのMosquittoユーザー名であるべきです。
- パスワードは上記で作成したパスワードである必要があります。
- SSL ボックスをチェックしてください。
接続ボタンを押すと、HiveMQクライアントがMosquittoサーバーに接続されます。
接続されたら、home/lights/kitchenをトピックとして入力し、任意のメッセージを入力して公開を押してください。
メッセージは、成功した接続を確認するために、あなたのmosquitto_subターミナルウィンドウに表示されます。
これは、Websocketsの実装が成功していることを示しています。
結論
これで、Ubuntu 20.04ベースのマシンにおける安全なパスワード保護されたSSL暗号化MQTTサーバーのセットアップが完了しました。質問がある場合は、下のコメントに投稿してください。


