---
title: "MQTTブローカーとは？仕組み・主要ブローカー比較とMosquittoでの構築手順【2.1対応】"
url: "https://www.issoh.co.jp/tech/details/3894/"
published: 2024-10-21
updated: 2026-10-17
categories: ["プロトコル"]
publisher: "株式会社一創"
---

# MQTTブローカーとは？仕組み・主要ブローカー比較とMosquittoでの構築手順【2.1対応】

MQTTブローカー（MQTT broker）は、IoT機器どうしのメッセージを中継するサーバーソフトウェアです。センサーが送ったデータを受け取り、そのトピックを購読している機器やアプリだけに配ります。この記事では、ブローカーの仕組みと用語の違いを整理したうえで、Mosquitto・EMQX・HiveMQ・NanoMQ・クラウドのマネージド型を2026年10月時点の版とライセンスで比較し、無料の公開ブローカーの接続先、Mosquittoでの構築手順を示します。手順と設定はMosquitto 2.1.2で実際に動かし、その結果を載せています。

## まとめ：MQTTブローカーの役割と選び方・構築の要点

- **役割**：送信側（パブリッシャー）と受信側（サブスクライバー）の間に立ち、トピック単位でメッセージを振り分ける中継点。MQTTの仕様書は同じものを「Server」と呼ぶ。
- **学習・小規模・エッジ**：Eclipse Mosquitto（2.1.2）。Ubuntuのaptで入るのは2.0系（26.04は2.0.22）、Dockerの `eclipse-mosquitto:latest` は2.1.2。
- **大規模・クラスタ**：EMQX（6.3.2）。ただし5.9以降はBSL 1.1で、無償の本番利用は単一ノードまで（教育機関・非営利団体の非営利利用を除く）。
- **運用を任せたい**：AWS IoT Core（QoS 2は非対応）やAzure Event GridのMQTTブローカー。
- **試すだけ**：test.mosquitto.org・broker.hivemq.com・broker.emqx.io は無料。どれも1883番（平文）と8883番（TLS）に今つながるが、送った内容は他人から見える。
- **構築の落とし穴**：Mosquitto 2.0以降は listener を書かないとローカルからしか接続できず、書くと匿名接続が拒否される。2.1では `password_file` と `acl_file` が非推奨になり、プラグインでの指定へ移った。

以下、仕組み、比較、公開ブローカー、構築、つまずきやすい挙動、エッジのブリッジ構成、セキュリティの順に説明します。

## MQTTブローカーとは：Pub/Subでメッセージを仲介する中継サーバー

MQTTは、帯域や電力に制約のある機器向けに作られた軽量なメッセージングプロトコルです。現行のMQTT 5.0は[2019年3月7日にOASIS Standard](https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html)となり、国際規格の[ISO/IEC 20922:2016](https://www.iso.org/standard/69466.html)が対応しているのは一つ前の3.1.1です。プロトコル全体の仕組みとHTTPとの使い分けは[MQTTとは？Pub/Subの仕組み・QoS・MQTT 5.0の実装](/tech/details/15819/)で扱っており、この記事はブローカー側に絞ります。

### ブローカーがメッセージを振り分ける仕組み

MQTTのクライアントは互いに直接つながりません。送る側は「トピック」を付けてメッセージをブローカーへPUBLISHし、受け取る側はあらかじめブローカーへSUBSCRIBEしておきます。ブローカーはPUBLISHを受けるたびに、そのトピックに一致する購読者を探して配信します。

そのため送る側は受け取る側の数も接続先も知らずに済み、センサー1台の値を監視画面とデータベースが同時に受け取る、受信側を後から足す、といった変更が送信側を触らずにできます。その代わり、ブローカーを1台だけで構成すると、そのブローカーが止まったときにつながっている全クライアント間の中継が止まる単一障害点になります。

### MQTTブローカー・MQTTサーバー・MQTTプロトコルの違い

「MQTT」は通信の取り決め（プロトコル）の名前です。「MQTTブローカー」はそのプロトコルで接続を受け付け、メッセージを配るソフトウェアやサービスを指します。「MQTTサーバー」も同じものを指し、MQTT 5.0の仕様書はクライアントの相手方を一貫して「Server」と書いています。製品のドキュメントや日本語の解説では「ブローカー」が一般的です。ブローカーにつないで送受信する機器やアプリはクライアントと呼びます。Mosquittoのように同じパッケージにブローカー本体（`mosquitto`）とクライアント（`mosquitto_pub`・`mosquitto_sub`）が入っている製品もあるため、どちらを起動しているのかは意識しておく必要があります。

### トピックとワイルドカード（+・#）

トピックは `factory1/line1/temp` のようにスラッシュで区切った階層です。購読側だけがワイルドカードを使え、`+` は1階層、`#` は配下すべてに一致します。`factory1/+/temp` は全ラインの温度、`factory1/#` は工場1のすべてです。

階層は後から変えにくいので、最初に「拠点／設備／計測値」のように物理構成に沿って決めます。後述のACL（トピックごとの権限）もこの階層に沿って書くため、機器IDを階層に含めておくと「自分のトピックにだけ書ける」という設定が1行で済みます。

### ブローカーが受け持つQoS・Retain・LWT・セッション

配信の確実さはQoSで選びます。QoS 0は最大1回、QoS 1は最低1回（重複あり）、QoS 2は正確に1回です。購読者に届く実際のQoSは、送信側のQoSと購読時に認められたQoSの低い方になります。QoSの往復と使い分けは[MQTT QoSとは？0・1・2の違いと選び方](/tech/details/3611/)で、実装例とともに説明しています。

ほかにブローカーは、トピックごとに最後の1件を残すRetain、クライアントの異常切断時に代わりに送る遺言メッセージ（LWT）、切断中のQoS 1・2メッセージをためる永続セッションを受け持ちます。どれもブローカーのメモリやディスクを使うので、端末数が増えたときの容量見積もりに入れます。

## 主要MQTTブローカーの比較（版・ライセンス・規模）

自前で動かすブローカーは、ここ1年でライセンスや設定方法が変わったものがあります。版は2026年10月17日時点のGitHubの最新リリースです。

### 自前で運用するブローカー4種の比較表

| ブローカー             | 実装     | 最新版               | ライセンス               | 複数ノード   | 向く用途            |
| ----------------- | ------ | ----------------- | ------------------- | ------- | --------------- |
| Eclipse Mosquitto | C      | 2.1.2（2026-02-09） | EPL-2.0 または EDL-1.0 | 本体に機能なし | 学習・小規模・エッジ      |
| EMQX              | Erlang | 6.3.2（2026年10月）   | BSL 1.1             | 本番は商用契約 | 大規模・クラスタ        |
| HiveMQ CE         | Java   | 2026.5            | Apache-2.0          | 商用版の機能  | Java拡張・MQTT 5検証 |
| NanoMQ            | C      | 0.25.6            | MIT                 | －       | エッジ・ゲートウェイ      |

[MosquittoのChangeLog](https://github.com/eclipse-mosquitto/mosquitto/blob/v2.1.2/ChangeLog.txt)によると、2.1.0（2026-01-29）で `password_file`・`acl_file`・`per_listener_settings` が非推奨になり、3.0で削除される予定です。設定項目 `mosquitto.conf` にはクラスタの項目がなく、冗長化はブリッジや外部の仕組みで組みます。

EMQXは5.9以降が[Business Source License 1.1](https://docs.emqx.com/en/emqx/latest/get-started/deploy/license.html)です。LICENSEの追加許諾で単一ノードの本番利用は無償ですが、EMQXそのものを第三者へホスティングや組み込みの形で提供する用途は除かれます。教育機関と非営利団体は、営利目的でなければ本番でも制限なく使えます。各版は公開から4年後にApache 2.0へ切り替わります。無償範囲と6.3での変更点は[EMQXとは？OSS版の無償範囲とMosquittoとの違い](/tech/details/1498/)で詳しく扱っています。

[HiveMQ Community Edition](https://github.com/hivemq/hivemq-community-edition)はMQTT 3.1・3.1.1・5.0の全機能を実装していると公式READMEに書かれています。クラスタと高可用性は商用のHiveMQで提供される機能です。[NanoMQ](https://github.com/nanomq/nanomq)はLF EdgeのプロジェクトでEMQが開発を主導するC実装のブローカーです。READMEは組み込み環境向けに調整したと説明しており、MQTT 3.1・3.1.1・5.0に対応します。

### クラウドのマネージドMQTTブローカー（AWS IoT Core・Azure Event Grid）

ブローカーのサーバーの冗長化やスケールを自分で持ちたくない場合は、クラウドのマネージド型を使います。ただし機器ごとの証明書や接続ポリシーの管理は、マネージド型でも利用者の責任として残ります。[AWS IoT Core](https://docs.aws.amazon.com/iot/latest/developerguide/mqtt.html)はMQTT 3.1.1と5.0の両方に対応しますが、仕様との差異があり、QoS 2には対応しません。QoS 2前提の機器を移すときは、ここが最初の確認点になります。機能と料金、接続手順は[AWS IoT Coreとは？機能・料金・MQTT接続方法](/tech/details/2991/)にまとめています。

Azureでは[Event GridのMQTTブローカー機能](https://learn.microsoft.com/en-us/azure/event-grid/mqtt-support)が、MQTT 3.1.1とMQTT 5をTCPの8883番で受け付けます。名前空間の作り方や再試行の設計は[Azure Event Gridとは？名前空間とカスタムトピックの違い](/tech/details/17283/)を参照してください。マネージド型はメッセージサイズや接続数に製品ごとの上限があるので、導入前に上限表を確認します。

### 規模と運用体制で決める選び方

- **ブローカー1台の停止を許容でき、担当者が少ない**：Mosquittoが合います。単一プロセスで動き、設定ファイル1つで完結します。必要な性能は、実際の送信頻度・購読者数・ペイロードで負荷を測って確かめます。
- **ブローカーの停止が許されない・1台では負荷を受けきれない**：EMQXのクラスタかHiveMQの商用版です。EMQXを本番で2ノード以上にするなら商用ライセンスの費用を最初の見積もりに入れます。
- **運用担当がいない・既にAWSかAzureを使っている**：マネージド型です。サーバー保守がなくなる代わりに、QoS 2や独自プラグインのような機能の制約を受け入れます。

避けたいのは、規模が見えない段階で「大は小を兼ねる」とEMQXのクラスタやHiveMQの商用版から入ることです。数十台の検証で、クラスタの監視とライセンス管理の手間だけが先に発生します。Mosquittoで始めて、負荷の測定値や可用性の要件が出た時点で移る方が、トピック設計を活かしたまま乗り換えられます。製造業の設備データのように状態管理まで規約で揃えたい場合は、[Sparkplug Bとは？MQTT上の産業データ規約と状態管理](/tech/details/16864/)に対応するかどうかも選定条件に入ります。

## 無料で試せる公開MQTTブローカーの接続先とポート

クライアントの動作確認だけなら、ホスト名とポートを指定するだけで使える公開ブローカーで足ります。

### 3つの公開ブローカーのポート一覧（2026年10月に接続を確認）

| ホスト                | 平文   | TLS       | WebSocket | WebSocket（TLS） |
| ------------------ | ---- | --------- | --------- | -------------- |
| test.mosquitto.org | 1883 | 8883・8886 | 8080      | 8081           |
| broker.hivemq.com  | 1883 | 8883      | 8000      | 8884           |
| broker.emqx.io     | 1883 | 8883      | 8083      | 8084           |

ポートは[test.mosquitto.org](https://test.mosquitto.org/)、[HiveMQの公開ブローカーのページ](https://www.mqtt-dashboard.com/)、[EMQXの公開ブローカーのページ](https://www.emqx.com/en/mqtt/public-mqtt5-broker)の記載です。2026年10月17日に `mosquitto_pub` で各ポートへQoS 1で送信し、次の結果を得ました。

- broker.hivemq.com の8883番はOSの標準のCA証明書で接続できました。以前は「HiveMQの公開ブローカーはTLSなし」と説明されることがありましたが、現在はTLSの8883番と8884番を公開しています。
- test.mosquitto.org の8883番は、OSの標準のCA証明書では `Error: Protocol error` で失敗し、配布されている `mosquitto.org.crt` を `--cafile` に指定すると成功しました。標準のCA証明書で済ませたいときはLet’s Encryptの証明書を使う8886番を選びます。
- test.mosquitto.org の1884番は、ユーザー名 `rw`・パスワード `readwrite` を付けると成功し、付けないと `not authorised` で拒否されました。認証付きの接続を試す練習に使えます。

```
# HiveMQの公開ブローカーにTLSで送る（-p 8883 だとOSのCA証明書でTLSが自動で有効になる）
mosquitto_pub -h broker.hivemq.com -p 8883 -t issoh/test/3894 -m ping -q 1

# test.mosquitto.org の8883番は配布されている専用のCA証明書で検証する
curl -sO https://test.mosquitto.org/ssl/mosquitto.org.crt
mosquitto_pub -h test.mosquitto.org -p 8883 --cafile mosquitto.org.crt -t issoh/test/3894 -m ping
```

8883以外のポートでOSのCA証明書を使うときは `--tls-use-os-certs` を付けます。ブラウザのJavaScriptからはTCPで直接つなげないため、WebSocketのポートを使います。PythonのPahoクライアントはTCPが既定で、WebSocketも選べます。EMQXの公開ブローカーはWebSocketのパスが `/mqtt` です。

### 公開ブローカーを本番に使えない理由と使ってよい範囲

公開ブローカーは誰でもつながり、同じトピックを購読すれば他人の送った内容が読めます。EMQXのページは「All messages are visible to other users. Do not send sensitive data.」と明記し、HiveMQも本番データ向けではないと書いています。test.mosquitto.org は素の `#`（全トピック）の購読だけは禁止していますが、`sensors/#` のような範囲の購読はできるため、トピック名を推測されれば中身は読まれます。

使ってよいのは、クライアントライブラリの接続確認、トピック設計の試行、研修やデモまでです。トピック名には自分だけが使う接頭辞を付け、機器のIDや位置情報のような実データは流しません。Pythonのクライアントを書く場合の接続と再接続の実装は[Python MQTT実装｜paho-mqtt 2系のループ方式と再接続](/tech/details/16866/)にまとめています。

## MosquittoによるMQTTブローカーの構築手順

自前のブローカーを最短で立てるならMosquittoです。以下のコマンドと設定は、Mosquitto 2.1.2（macOSのHomebrew版）で実際に動かして結果を確かめたものです。Ubuntuでのパスに置き換えて示します。

### インストール：Ubuntuのaptは2.0系、Dockerのlatestは2.1系

入れ方によって版が違い、版によって推奨される設定の書き方が変わります。[Ubuntuの公式パッケージ](https://launchpad.net/ubuntu/+source/mosquitto)は24.04 LTSが2.0.18、26.04 LTSが2.0.22で、aptで入るのは2.0系です。Docker Hubの公式イメージ `eclipse-mosquitto:latest` は2026年10月時点で `2.1.2-alpine` と同じイメージを指しています。

```
# Ubuntu（2.0系が入る）
sudo apt update
sudo apt install mosquitto mosquitto-clients
mosquitto -h | head -1      # 版を確認する

# Docker（2.1系）。./mosquitto/config に mosquitto.conf・passwd・acl を置いてディレクトリごとマウントする
docker run -d --name mosquitto -p 1883:1883 \
  -v "$PWD/mosquitto/config:/mosquitto/config" eclipse-mosquitto:2.1.2-alpine
```

Dockerでは、後述の設定ファイルの中のパスをコンテナ内の `/mosquitto/config/passwd` のように書き換えます。[公式イメージの説明](https://hub.docker.com/%5F/eclipse-mosquitto)どおり、設定は `/mosquitto/config`、永続化データは `/mosquitto/data` に置く構成です。設定を変えたら `docker restart mosquitto` で反映します。

### 2.0以降の既定動作：listener未設定時のローカル限定モード

[Mosquitto 2.0の移行ガイド](https://mosquitto.org/documentation/migrating-to-2-0/)のとおり、listenerを1つも設定せずに起動すると、ブローカーは127.0.0.1と::1にだけバインドします。設定ファイルなしで起動すると、ログに次の行が出ました。

```
Starting in local only mode. Connections will only be possible from clients running on this machine.
Create a configuration file which defines a listener to allow remote access.
```

このとき同じマシンからの匿名接続は通り、LANのIPアドレス宛ての接続は失敗しました。Ubuntuのパッケージに入っている `/etc/mosquitto/mosquitto.conf` もlistenerを持たず `include_dir /etc/mosquitto/conf.d` を読むだけなので、apt直後は同じローカル限定の状態です。「インストールしたのに他の機器からつながらない」の原因の多くはこれです。

反対に `listener 1883` だけを書くと全インターフェースで待ち受けますが、匿名接続は `Connection Refused: not authorised` で拒否されます。2.0以降、listenerを設定したときの `allow_anonymous` の既定値は `false` だからです。外からつなぐには、認証を設定するか、検証用に限って `allow_anonymous true` を明示します。

### パスワード認証とACLの設定（2.0系と2.1系の書き方）

まずユーザーを登録します。`-c` はファイルを新規作成するオプションなので、2人目以降は付けません。

```
sudo mosquitto_passwd -c /etc/mosquitto/passwd sensor01
sudo mosquitto_passwd /etc/mosquitto/passwd dashboard
sudo chown mosquitto:mosquitto /etc/mosquitto/passwd
sudo chmod 0700 /etc/mosquitto/passwd
```

最後の2行は、ファイルの所有者や権限が実行ユーザーと合わないときに出る「Future versions will refuse to load this file.」という警告への対処です。2.1.2のソースでは、他ユーザーが読める権限、所有者やグループの不一致を検査し、今は警告だけで読み込みます。将来の版では読み込みを拒否すると予告されているので、今のうちに直しておきます。

次にトピックごとの権限をACLファイルに書きます。センサーは自分のトピックへの書き込みだけ、監視画面は読み取りだけにします。ACLファイルにも同じ権限の警告が出るので、作成後にpasswdと同じ `chown` と `chmod 0700` を当てます。

```
# /etc/mosquitto/acl
user sensor01
topic write factory1/sensor01/#

user dashboard
topic read factory1/#
```

設定ファイルの書き方は版で分かれます。aptで入る2.0系は従来どおり `password_file` と `acl_file` で指定します。2.1系ではこの2つが非推奨になり、[公式の移行文書](https://mosquitto.org/documentation/listeners/per-listener-settings/)が案内するプラグイン形式で書きます。

```
# 2.0系（Ubuntuのapt）: /etc/mosquitto/conf.d/local.conf
listener 1883
allow_anonymous false
password_file /etc/mosquitto/passwd
acl_file /etc/mosquitto/acl

# 2.1系: 同じ内容をプラグインで指定する（プラグインのパスはビルドにより異なる）
listener 1883
allow_anonymous false
plugin /usr/lib/mosquitto_password_file.so
plugin_opt_password_file /etc/mosquitto/passwd
plugin /usr/lib/mosquitto_acl_file.so
plugin_opt_acl_file /etc/mosquitto/acl
```

2.1.2でプラグイン形式を読み込むと、ログに「Plugin password-file loaded.」と出て、匿名・誤ったパスワード・ACL外のトピックがそれぞれ拒否されました。2.1系でも旧来の `password_file` はまだ動きますが、3.0で削除される予定なので、新しく書く設定はプラグイン形式にします。設定を変えたら `sudo systemctl restart mosquitto` で反映します。

### mosquitto\_sub／mosquitto\_pubによる送受信の確認

ターミナルを2つ開き、片方で購読、もう片方で送信します。`-v` を付けると受信側にトピック名も表示されます。

```
# ターミナル1：監視画面のユーザーで購読する
mosquitto_sub -h localhost -u dashboard -P '********' -t 'factory1/#' -v

# ターミナル2：センサーのユーザーで自分のトピックに送る
mosquitto_pub -h localhost -u sensor01 -P '********' -t factory1/sensor01/temp -m 21.5
```

ターミナル1に `factory1/sensor01/temp 21.5` と出れば、認証とACLを通って中継できています。ブローカー側の動きを見たいときは、サービスを止めて `mosquitto -c 設定ファイル -v` で前面起動すると、接続・拒否・配信のログが画面に流れます。

## Mosquittoの設定でつまずきやすい3つの挙動

次の3つはエラーの出方が分かりにくく、切り分けに時間がかかります。いずれもMosquitto 2.1.2で再現を確かめました。

### ACL拒否時の送信側の終了コードと警告表示

上のACLのまま、sensor01が他人のトピック `factory1/sensor99/temp` へ送ると、MQTT 3.1.1・QoS 0の `mosquitto_pub` は終了コード0で正常終了しました。ブローカーのログにだけ「Denied PUBLISH」が出て、購読側には何も届きません。MQTT 3.1.1にはQoS 0の送信を拒否されたことを送信側へ伝える手段がないためです。

同じ送信をMQTT 5・QoS 1（`-V 5 -q 1`）にすると、PUBACKに理由コード135（Not authorized）が返り、`Warning: Publish 1 failed: Not authorized.` と表示されました。それでも終了コードは0でした。ACLの書き間違いを早く見つけたい開発中は、MQTT 5とQoS 1で送り、ブローカーのログを並べて見るのが確実です。

### TLS証明書のホスト名不一致と「Protocol error」の切り分け

自前のCAでCN・SANを `localhost` にしたサーバー証明書を作り、8883番相当のlistenerに設定して試しました。`-h localhost --cafile ca.crt` は成功し、同じブローカーへ `-h 127.0.0.1` で接続すると `Error: Protocol error` で失敗しました。証明書の名前と接続先のホスト名が一致しないことが原因ですが、メッセージからはそう読み取れません。TLSのlistener（検証では18883番）にTLSのオプションを何も付けずに接続した場合は `Error: The connection was lost` でした。なお `mosquitto_pub` は `-p 8883` を指定するとOSのCA証明書でTLSを自動で有効にするため、標準の8883番ではこの失敗は起きません。

対処は、クライアントが実際に指定するホスト名（DNS名またはIPアドレス）をサーバー証明書のSANに入れることです。`--insecure` を付けると名前の検査を飛ばして接続できますが、なりすましを防ぐ検証そのものを外すので、切り分けの確認以外では使いません。

### 2.1でのmax\_packet\_size既定値の変更（2,000,000バイト）

2.1.0から、ブローカーが受け付ける1パケットの上限 `max_packet_size` の既定値が、MQTTの上限の256MBから2,000,000バイトに下がりました。1,999,000バイトのファイルは送れましたが、2,100,000バイトを送ると送信側は `Error: The connection was lost` で終わり、ブローカーのログには「disconnected: oversize packet」と出ました。

2.0系から上げたあとに画像やログファイルの送信だけが切れる場合は、まずブローカーのログに「oversize packet」が出ていないかを確かめます。大きなデータを送る必要があるなら `max_packet_size` を必要な値に設定します。ただし本来は、大きなファイルはオブジェクトストレージに置き、MQTTではその場所だけを送る設計の方が、ブローカーのメモリを圧迫しません。

## エッジのブローカーから上位へのブリッジ構成

工場や店舗に小さなブローカーを置き、そこから本社やクラウドのブローカーへ必要なトピックだけを転送する構成を、ブリッジと呼びます。現場の機器は手元のブローカーにつながるだけなので、回線が切れても現場内の通信は止まりません。AWSも[Greengrassのコンポーネント](https://docs.aws.amazon.com/ja%5Fjp/greengrass/v2/developerguide/mqtt-broker-moquette-component.html)としてMQTT 3.1.1のブローカー（Moquette、既定は8883番）やMQTT 5のブローカー（EMQX）を提供しており、エッジにブローカーを置く構成は一般的です。Greengrass全体の仕組みは[AWS IoT Greengrassとは？仕組み・機能・料金とIoT Coreとの違い](/tech/details/3159/)で説明しています。

Mosquittoでは、エッジ側の設定にブリッジを書きます。次の例は、エッジの `sensors/` 配下を上位へ `factory1/sensors/` として送り、上位の `factory1/cmd/` 配下をエッジへ `cmd/` として受け取ります。

```
# エッジ側の mosquitto.conf（ブリッジ部分）
connection to-cloud
address cloud.example.com:8883
topic sensors/# out 1 "" factory1/
topic cmd/# in 1 "" factory1/
cleansession false
persistence true
persistence_location /var/lib/mosquitto/
bridge_cafile /etc/mosquitto/certs/ca.crt
remote_username factory1-bridge
remote_password ********
```

`topic` 行は「パターン・方向・QoS・ローカル側の接頭辞・リモート側の接頭辞」の順です。手元の2つのMosquittoで試すと、エッジに送った `sensors/line1/temp 24.8` は上位で `factory1/sensors/line1/temp` として受信でき、上位に送った `factory1/cmd/line1/stop` はエッジで `cmd/line1/stop` として受信できました。

上位のブローカーを止めた状態でエッジにQoS 1で1件送り、上位を再起動すると、約4秒後にその1件が上位の購読者へ届きました。QoS 1と `cleansession false` の組み合わせで、ブリッジが切断中の分をためて再送しています。QoS 0で送った値はためられません。エッジのブローカー自体の再起動をまたいで残すには、この例のように `persistence true` と `persistence_location` でディスクへの保存も設定します。ただし組み込みの永続化はメモリ上のデータを終了時と一定間隔でディスクへ書く方式で、`autosave_interval` の既定は1,800秒です。突然の停電では最後の保存以降の分を失う可能性があるため、許容できる損失に合わせて間隔を短くします。

## MQTTブローカーのセキュリティで最低限やること

外部から到達できるブローカーには、次の4点を最低限そろえます。

- **暗号化**：平文の1883番は閉じ、TLSの8883番で待ち受ける。証明書のSANには接続に使うホスト名を入れる。
- **認証**：機器ごとにユーザーかクライアント証明書を分け、共用アカウントを作らない。
- **認可**：ACLで機器は自分のトピックへの書き込みだけに絞る。`#` の購読を許すのは監視用のユーザーだけにする。
- **到達経路**：ファイアウォールやセキュリティグループで接続元を限定し、管理用のポートは外に出さない。

```
# TLSのlistener。1883番のlistenerと置き換え、前述の認証・ACLの設定と組み合わせる
listener 8883
cafile /etc/mosquitto/certs/ca.crt
certfile /etc/mosquitto/certs/server.crt
keyfile /etc/mosquitto/certs/server.key
allow_anonymous false
```

この設定にパスワード認証を加えた構成で、TLS 1.3の接続が確立し、ログに「negotiated TLSv1.3」と出ました。クライアント証明書による相互認証、証明書の失効、ブローカーごとのACLの書き方の比較は[MQTTセキュリティ｜TLS 8883番・証明書認証・トピックACLの設計](/tech/details/16868/)で扱っています。IoT機器とブローカー、クラウドまでを含めたシステムの設計を外部に相談したい場合は、[AI/IoTソリューション](/service/ai/iot/)の支援内容も参考にしてください。

## よくある質問

### MQTTブローカーとは何ですか？

MQTTのメッセージを中継するサーバーソフトウェアです。送信側がトピックを付けて送ったメッセージを受け取り、そのトピックを購読しているクライアントだけに配ります。送信側と受信側が互いの接続先を知らなくてよいため、多数の機器が断続的につながるIoTで使われます。

### MQTTブローカーとMQTTサーバーは違うのですか？

同じものを指します。MQTT 5.0の仕様書は「Server」と書き、製品や日本語の解説では「ブローカー」と呼ぶのが一般的です。「MQTT」はプロトコルの名前で、ブローカー（サーバー）はそのプロトコルでメッセージを中継する実体です。

### MQTTブローカーは無料で使えますか？

使えます。MosquittoやHiveMQ Community Edition、NanoMQはオープンソースです。EMQXは5.9以降がBSL 1.1で、単一ノードの本番利用は無償ですが、2ノード以上の本番クラスタには商用契約が要ります。動作確認だけなら test.mosquitto.org などの公開ブローカーが無料ですが、送った内容は他人に見えるので本番には使えません。

### MQTTのポート番号はいくつですか？

平文のMQTTは1883番、TLSで暗号化したMQTTは8883番が標準です。WebSocket経由のポートは決まっておらず、公開ブローカーでも test.mosquitto.org は8080番、broker.hivemq.com は8000番、broker.emqx.io は8083番と異なります。

### Mosquittoのインストール方法は？

Ubuntuなら `sudo apt install mosquitto mosquitto-clients` で本体とクライアントが入ります（2.0系）。2.1系を使うならDockerの `eclipse-mosquitto:2.1.2-alpine` を使います。どちらも listener を設定しないとローカルからしか接続できず、設定すると匿名接続が拒否されるので、認証の設定までを1セットで行います。

## 関連記事

- [MQTTとは？Pub/Subの仕組み・QoS・MQTT 5.0の実装からHTTPとの使い分けまで実装者向けに解説](/tech/details/15819/)
- [MQTT QoSとは？0・1・2の違いと選び方をmosquitto・Pythonの実装例で解説](/tech/details/3611/)
- [MQTTセキュリティ｜TLS 8883番・証明書認証・トピックACLの設計を実装目線で解説](/tech/details/16868/)
- [EMQXとは？OSS版の無償範囲とMosquittoとの違い【6.3対応】](/tech/details/1498/)
- [AWS IoT Coreとは？機能・料金・MQTT接続方法をまとめて解説](/tech/details/2991/)

---

出典: [MQTTブローカーとは？仕組み・主要ブローカー比較とMosquittoでの構築手順【2.1対応】](<https://www.issoh.co.jp/tech/details/3894/>)（株式会社一創）
