MQTT(旧称:MQ Telemetry Transport、Message Queuing Telemetry Transport)は、メッセージ指向ミドルウェアのアプリケーション層で使用される、TCP/IPによるPub/Sub型データ配信モデルの軽量なデータ配信プロトコルである。

MQTTのMQは、歴史的にはMQSeriesから来ているが、メッセージキューの機能は持たない。

非力なデバイスやネットワークが不安定な場所でも動作しやすいように、メッセージ通信電文が軽量に設計されていることが特徴である。

Pub/Sub型メッセージング·パターンには、サーバとしてメッセージブローカーが必要である。

サーバは、メッセージのトピックに基づいて、それを必要としているクライアントにメッセージを配布する。

仕様はロイヤリティフリーで公開されていて、現在の仕様は5となっている。

## 歴史

1999年にIBMのアンディー・スタンフォード・クラークとArcom Control Systemsのアーレンニッパーによりプロトコルの最初のバージョンが執筆された。

その年の内にVersion 2を定義し、1999年10月22日にアップデートしたVersion 2.3でVersion3.1.1相当のパケットを備えるものとなった。

2000年にはVersion 3.0がリリースされた。

2007年にEurotechに買収されたArcom Control Systemsは社名もEurotechに変更したため、MQTTの仕様はIBMとEurotechが管理するものになった。

2010年にVersion 3.1がリリースされた。
このバージョンからロイヤリティフリーで公開されている。

2011年にEclipse Foundationが設立したPahoプロジェクトにIBMからMQTTクライアントの実装が提供された。

2014年10月29日にVersion 3.1.1がリリースされ11月13日に発表された。
このバージョンからOASISが仕様を管理している。
また、2016年6月にISO/IEC標準のISO/IEC 20922:2016として採用された。
。

2019年3月7日にVersion 5.0がリリースされ2019年3月19日に発表された。

## 特徴

MQTTには次のような特徴がある。

### 軽量なプロトコル

プロトコル電文仕様は軽量でシンプルになっていてヘッダーサイズは最小で2バイトである。

MQTTはロスレスで順序保証がされた双方向通信のプロトコル上で動作することが前提となっていて、TCP/IPとTLSとWebSocketが仕様で言及されている。ただし、これらのプロトコルを使用することに限定はしていない。

TLSを使う場合は8883、TLSを使わない場合は1883のTCPポートがIANAに登録されている。

### 柔軟性の高いメッセージ配布(Sub:購読)

配布先条件が`/`区切りの階層構造になっており、さらにワイルドカードによる指定ができる。
配布先はそのパターンにマッチした宛先になる。

- トピックベースでのPub/Sub
- 1対1、1対N、N対Nのメッセージ配布

### メッセージ配布の品質

三種類の QoS (Quality of Service) レベルの指定ができる。

QoSレベルは単一の送信者と単一の受信者の間で適用される。

つまりサーバが同一のメッセージを複数のクライアントに配布を行う場合はそれぞれのクライアントで異なるQoSレベルが使用される場合がある。

またメッセージを配布するクライアントとサーバ間、トピックに応じて配布するサーバとクライアント間でも同じことが言えるためアプリケーションメッセージの品質を定義するものではない。

#### QoS 0: At most once delivery

最高1回の送信を行う。
使用しているトランスポート層の性能に応じたメッセージ配布を行う。
メッセージが確実に届く保証はない。
メッセージ配布に失敗しても再送をしない。

#### QoS 1: At least once delivery

最低1回の送信を行う。
必ずメッセージを配布するが、重複する可能性がある。

#### QoS 2: Exactly once delivery

正確に1回の送信を行う。
必ずメッセージを配布して、重複も発生しない。

### メッセージ再配布機能

クライアントが再接続をしたときにセッションが残っている場合はクライアントとサーバの両方が確認応答がないPUBLISHパケットとPUBRELパケットを再送信する。

これはメッセージが再配布される唯一の機会である。

QoS 0のPUBLISHパケットの再送信は行われない。

### Willメッセージ

クライアントとの接続が正常にクローズされなかったときにサーバによって配布されるメッセージのこと。

クライアントがサーバに接続する際にCONNECTパケットにWillフラグとWillメッセージを含める。サーバはCONNECTパケットを受け入れた場合はWillメッセージをセッションに関連付けて保存する。

サーバはクライアントとのネットワーク接続が正常ではない方法でクローズされたとき保存しているWillメッセージを購読している別のクライアントに配布する。

MQTT Version 3.1までの仕様にはLast Will and Testamentと書かれていた。
そのためLWTと言う略称で説明される場合がある。

### Retain

クライアントがRetainフラグを有効にして配布したメッセージはサーバでトピックごとに上書き保存される。

クライアントがトピックの購読を行った際に保存されたメッセージがある場合はサーバにより購読したクライアントに配布される。

これによりクライアントはトピック購読前の最後のメッセージを受け取ることができる。

### セキュリティ

MQTTは仕様として具体的なセキュリティの規定はない。
基本的に実装依存と下位層が持つ既存のセキュリティ技術を利用することとなっている。
ただし以下の言及がある。

CONNECTパケットにユーザネームとパスワードを含めることができる。
これらを使ってBasic認証を行うことができる。
ただし、これらのフィールドをBasic認証のみに使うことに限定しておらず、パスワードフィールドをBearerトークンを渡すために使うことなども言及している。
MQTT Version 5.0からユーザネームを省略してパスワードのみクライアントからサーバに通知することができるようになった。

認可のために先述のユーザネームとパスワード以外にCONNECTパケットに含まれるクライアント識別子や下位層のプロトコルから得られるホスト名やIPアドレスが利用できることも言及している。

暗号化はTLSまたはVPNが利用できることに言及している。

OASISに管理が移管されたMQTT Version 3.1.1より、NISTのサイバーセキュリティフレームワークのMQTTを使用する際のガイドラインが用意された。

## パケットタイプ

MQTT Version 5.0では15種類のパケットタイプが定義されている。
パケットは固定ヘッダ、可変ヘッダ、ペイロードの3つの部分で構成される。

MQTTのパケットタイプは以下の3種類に分類される。

### コネクションの接続・切断

CONNECT、CONNACK、DISCONNECT、AUTH、PINGREQ、PINGRESPが分類される。

クライアントが自身の能力を示すパラメータを含むCONNECTを送信し、サーバがCONNACKで結果を返すことで通信が開始される。
MQTT Version 5.0でサーバのオプション機能をクライアントに通知するためにCONNACKに多くのパラメータが追加された。

クライアントのシャットダウンやエラーなどの要因によりクライアントがDISCONNECTを送信することで通信が終了する。
MQTT Version 5.0よりサーバからもDISCONNECTを送信する場合がある。

接続を維持するためにPINGREQとPINGRESPが使用される。
Keep Aliveが目的なのでこのタイマーの満了前にクライアントからPINGREQが送信され、サーバがPINGRESPで応答することで接続が維持される。

認証を強化するためにMQTT Version 5.0でAUTHが追加された。
2往復以上のハンドシェイクが必要な認証アルゴリズム行う場合や、通信中の再認証が必要になった場合に使用される。
クライアント・サーバの双方から手順が開始される可能性がある。

### メッセージの配布

PUBLISH、PUBACK、PUBREC、PUBREL、PUBCOMPが分類される。

メッセージ配布はPUBLISHで開始される。
PUBLISHはクライアントによるメッセージの配布とサーバによるメッセージの転送の2パターンで使用される。
そのためここに分類されるパケットタイプはクライアント・サーバともに送信・受信のいずれの場合もありうる。

QoS 1の場合はメッセージ配布が完了したことを示すためにPUBACKがPUBLISHの受信側から送信される。

QoS 2の場合はメッセージ配布が完了したことを示すPUBREC、メッセージ配布に関するリソースが不要になったことを示すPUBREL、PUBCOMPが追加で使われる。

### トピックの購読・キャンセル

SUBSCRIBE、SUBACK、UNSUBSCRIBE、UNSUBACKが分類される。

クライアントは購読したいトピックをフィルタリングするための文字列をUTF-8エンコードしてSUBSCRIBEで送信し、サーバがSUBACKで結果を返す。

購読をキャンセルするときはクライアントがUNSUBSCRIBEを送信し、サーバがUNSUBACKで結果を返す。

## ブローカー

MQTTをサポートするブローカー(MQサーバ)は数多くある。それぞれのサーバがサポートする機能には、基本機能の他、サーバ特有の機能がある。

主なMQTTブローカーには以下のようなものがある。

### OSS

- Mosquitto
- RabbitMQ(Pluginが必要)
- Apache\_ActiveMQ
- MQTTnet - .NETによる実装。ライブラリであるが、短いコードで拡張可能な独自のブローカーを実装できる。

### 商用

- IBM MessageSight(ハードウェア)
- IBM WebSphere MQ Telemetry
- MqttDesk MQTT Client -

## 使用しているプロジェクト

### Facebook Messenger

FacebookのメッセンジャーにMQTTを使用している。

### IECC Scalable

DeltaRail Group (現:Resonate Group)のIECCシグナリング制御システムの最新バージョンではシステムとシグナリングシステムの他の構成要素との通信にMQTTを使用している。

## セキュリティの課題

2018年8月16日にAvast Softwareはスマートホームシステムの制御で使われるMQTTサーバの多くがパスワードで保護されていないと言うレポートを発表した。
レポートによると全世界で49,000台以上MQTTサーバが公開されており、そのうち32,000台以上がパスワードで保護されておらず通信内容を容易に確認できる。
レポートではMQTTの仕様および実装されたソフトウェアやライブラリにはセキュリティの問題はなくシステム構成時の問題であるとしている。

2018年12月4日にトレンドマイクロはM2M通信プロトコルの脆弱性に関するレポートを発表した。
その中でMQTTのトピックに不正なUTF-8文字列を設定することによるDoS攻撃と、残り文字数フィールドを利用したバッファオーバーフロー攻撃が紹介されている。

2024年3月1日にトレンドマイクロはMQTTプロトコルの盗聴や改竄のリスクについてレポートを発表した。
レポートによるとTLSで保護しているものの認証を必要としないMQTTサーバが数万台ありそのうち9000台程度が実際に稼働している。
レポートは顧客がベンダーにセキュリティの確保を求めていない、もしくは認識していないことが原因であると分析している。