認可
EMQXにおける認可とは、MQTTクライアントのパブリッシュ/サブスクライブ操作に対する権限管理を指します。クライアントがパブリッシュ/サブスクライブ操作を行う際、EMQXは特定の手順に従うか、ユーザー指定のクエリ文を使用して設定されたデータソースからクライアントの権限リストを照会します。照会結果に基づき、EMQXは現在の操作を許可または拒否します。
クライアントの単一の権限データは以下の要素で構成されます。
| 権限 | クライアント | 操作 | 操作の詳細 |
|---|---|---|---|
| 許可/拒否 | クライアントID/ユーザー名/IP | パブリッシュ/サブスクライブ/パブリッシュ・サブスクライブ | トピック/QoS/保持メッセージ |
TIP
EMQX 5.1.1以降、操作の詳細におけるQoSおよび保持メッセージのチェックがサポートされました。
クライアントの権限リストは事前に特定のデータソース(データベースやファイル)に保存しておく必要があります。対応するデータレコードを更新することで、実行時にリストを更新可能です。
EMQXではデフォルトでファイルベースのオーソライザーが設定されており、直接利用できます。認可はACLファイルに設定された事前定義ルールに基づいて処理されます。
データストレージオブジェクトとの連携
EMQXの認可機構は、組み込みデータベース、ファイル、MySQL、PostgreSQL、MongoDB、Redisなどの多様なデータストレージオブジェクトとの統合をサポートしています。REST APIやEMQXダッシュボードを通じて権限データを管理可能です。
さらに、ユーザーが開発したHTTPサービスに接続して、さまざまな認可要件に対応することも可能です。
バックエンドのデータストレージに応じて、以下のような種類のEMQXオーソライザーが用意されています。各オーソライザーには独自の設定オプションがあります。詳細は表中のリンクを参照してください。
| データベース | 説明 |
|---|---|
| ACLファイル | ファイルに設定された静的ルールによる認可 |
| 組み込みデータベース | 組み込みデータベースをルールストレージとした認可 |
| MySQL | MySQLをルールストレージとした認可 |
| PostgreSQL | PostgreSQLをルールストレージとした認可 |
| MongoDB | MongoDBをルールストレージとした認可 |
| Redis | Redisをルールストレージとした認可 |
| LDAP | LDAPディレクトリをルールストレージとした認可 |
| HTTP | 外部HTTPサービスを利用した認可 |
以下はEMQXのMySQLオーソライザーの設定例です。
例:
{
type = mysql
database = "mqtt"
username = "root"
password = "public"
query = "SELECT permission, action, topic FROM mqtt_acl WHERE username = ${username}"
server = "10.12.43.12:3306"
}認可チェーン
EMQXは単一のオーソライザーではなく複数のオーソライザーを設定して認可チェーンを作成することができ、認可をより柔軟に行えます。EMQXはチェーン内のオーソライザーの順序に従って認可処理を順次実行します。認可チェーンが設定されている場合、最初のオーソライザーで一致する認証情報が取得できないと、次のオーソライザーに切り替えて処理を継続します。
認可チェックの流れは以下の通りです。
EMQXがクライアントの権限情報を正常に取得した場合、クライアントの操作と取得した権限リストを照合します。
- 一致すれば、権限設定に基づき操作を許可または拒否します。
- 一致しなければ、次のオーソライザーに切り替えて処理を続行します。
EMQXがクライアントの権限情報を取得できなかった場合、他に設定されたオーソライザーがあるか確認します。
- ある場合は次のオーソライザーに切り替えて処理を継続します。
- 最後のオーソライザーであれば、
no_match設定に従いクライアント操作の許可・拒否を決定します。
注意
認可の問題を避けるため、必要に応じてACLファイルオーソライザーを無効化または削除してください。ACLファイルオーソライザーはデフォルトで末尾に {allow, all} があり、すべての認可リクエストを許可するためです。
オーソライザーのチェーン内での順序調整方法や稼働状況の確認方法については、オーソライザーの管理を参照してください。
クライアント認可キャッシュ
EMQXはセッションベースの認可データキャッシュ機構を提供しています。このキャッシュはクライアントのセッション状態に認可結果を保存し、同一接続中の認可ルール評価の繰り返しを減らします。クライアント認可キャッシュ機構は、クライアントのパブリッシュ/サブスクライブ操作における権限チェックの効率を向上させ、大量のクライアントリクエストによる認可データバックエンドへのアクセス負荷を軽減します。
クライアント認可キャッシュの動作
クライアントが接続しパブリッシュ/サブスクライブ操作を行う際の流れ:
- EMQXは現在のセッションに保存された認可キャッシュを確認します。
- セッションキャッシュに一致するルールがあれば、それを直接使用します。
- キャッシュが存在しない(または期限切れ)場合、設定されたオーソライザーを用いて完全な認可チェックを実行します。
- 結果をセッションにキャッシュし、接続中の再利用に備えます。
TIP
キャッシュはクライアントのセッション固有であり、クライアントの切断や再接続時にクリアされます。
ダッシュボードでのクライアント認可キャッシュ設定
EMQXダッシュボードでクライアント認可キャッシュを有効化・設定できます。
アクセス制御 -> 認可 -> 設定 に移動します。
以下のオプションを設定します。
フィールド名 説明 キャッシュを有効にする クライアントセッションごとの認可キャッシュの有効/無効切替。 キャッシュ項目の最大数 クライアントごとのキャッシュエントリの最大数。デフォルト: 32。キャッシュデータの有効期限 各キャッシュエントリの寿命。デフォルト: 1分。除外トピック キャッシュ無効化対象のトピックリスト。 一致しない場合の動作 オーソライザーが一致しなかった場合の動作。選択肢: allow(許可)/deny(拒否)。デフォルト:allow。拒否時の動作 操作拒否時の動作。選択肢: ignore(操作リクエストを無視)/disconnect(クライアント接続を切断)。デフォルト:ignore。キャッシュクリア アクティブなセッション認可キャッシュを手動で全てクリアするボタン。 保存 をクリックして設定を適用します。
これらの設定は設定ファイルでも行えます。詳細は設定ファイルを参照してください。
TIP
適切に設定すればキャッシュはパフォーマンスを大幅に向上させます。システムの性能に応じて適時調整することを推奨します。
外部リソースキャッシュ
セッションベースのキャッシュに加え、EMQXはMySQL、MongoDB、Redisなどの外部バックエンドから取得した認可結果をノードレベルでキャッシュする機能も提供しています。これによりリモートデータソースへのアクセスを減らし、パフォーマンスを向上させます。
注意
外部リソースキャッシュは外部データソースにのみ適用されます。組み込みデータベースやファイルベースのオーソライザーには適用されません。
外部リソースキャッシュの動作
パブリッシュ/サブスクライブ操作で外部バックエンドへの照会が発生した場合:
- EMQXは外部リソースキャッシュ(同一ノード上の全クライアントで共有)を確認します。
- キャッシュに有効な結果があれば、キャッシュヒットとして外部バックエンドへの呼び出しを行いません。
- 結果がなければ、キャッシュミスとして外部バックエンドにクエリを送信します。
- バックエンドから返された結果はキャッシュに保存され、キャッシュ挿入のメトリクスが増加します。
注意
セッションベースの認可キャッシュと異なり、外部リソースキャッシュはノード全体で共有され、クライアントセッションをまたいで持続します。
外部リソースキャッシュの有効化と設定
EMQXダッシュボードで外部リソースキャッシュを有効化・設定できます。
アクセス制御 -> 認可 に移動します。
右上の 外部リソースキャッシュ設定 ボタンをクリックすると右側にサイドパネルが表示されます。
パネル内の 外部リソースキャッシュを有効にする ボタンで機能をオン/オフ切替可能です。有効化後、以下のキャッシュ設定を行います。
フィールド名 説明 キャッシュ項目の最大数 ノードごとのキャッシュエントリ最大数。デフォルト: 1,000,000。最大メモリ使用量 キャッシュのメモリ使用上限。デフォルト: 100 MB。キャッシュTTL キャッシュエントリの有効期間。デフォルト: 1分。更新 をクリックして設定を適用します。
これらの設定はクラスター全体に適用され、全ノードで一貫した動作を保証します。
外部リソースキャッシュのステータス監視
キャッシュメトリクスを表示し、リアルタイムで使用状況を監視するには:
- External Resource Cache Settings の横にある矢印をクリックし、External Resource Cache Status を選択します。サイドパネルが表示され、キャッシュメトリクスが確認できます。
- ドロップダウンメニューを使って、ノード単位またはクラスター全体のメトリクスを表示できます。
メトリクスには以下が含まれます:
- Memory Usage:キャッシュが現在使用している合計メモリ量。
- Cache Entries:保存されているキャッシュ結果の総数。
- Cache Hits:EMQXがキャッシュ内で有効な結果を見つけ、外部バックエンドへの呼び出しを回避した回数。
- 表示されるメトリクス:現在のレート、5分間平均、最大レート
- Cache Misses:EMQXがキャッシュ内で結果を見つけられず、バックエンドクエリが発生した回数。
- 表示されるメトリクス:現在のレート、5分間平均、最大レート
- Cache Inserts:ミス後にキャッシュに新しい結果が追加された回数。
- 表示されるメトリクス:現在のレート、5分間平均、最大レート
パネル下部にはノードリストがあり、クラスター内の各ノードごとの Memory Usage、Cache Entries、Cache Hits の概要を確認できます。
パネル右上のボタンで統計情報の更新やリセットが可能です。
認可プレースホルダー
EMQXのオーソライザーは設定内でプレースホルダーを使用できます。認可処理時にこれらのプレースホルダーは実際のクライアント情報に置換され、現在のクライアントに合致するクエリやHTTPリクエストが構築されます。
有効なプレースホルダーは ${PATH.TO.VALUE} の形式で、PATH.TO.VALUEはオブジェクト内の値へのドット区切りパスです。使用可能な文字は英数字、ドット(.)、アンダースコア(_)です。サポート外の文字を含むプレースホルダーは単なるテキストとして扱われます。
データクエリ内のプレースホルダー
プレースホルダーはクエリ文の構築に使われます。例えば、EMQXのMySQLオーソライザーのデフォルトクエリSQLは ${username} プレースホルダーを使用しています。
SELECT action, permission, topic FROM mqtt_acl where username = ${username}クライアント(名前:emqx_u)が接続要求を送ると、構築されるクエリ文は以下のようになります。
SELECT action, permission, topic FROM mqtt_acl where username = 'emqx_u'クエリ文でサポートされるプレースホルダーは以下の通りです。
${username}: 実行時にユーザー名に置換されます。ユーザー名はCONNECTパケットのUsernameフィールドから取得されます。peer_cert_as_usernameが有効の場合は証明書のフィールドまたは内容により上書きされます。${clientid}: 実行時にクライアントIDに置換されます。通常はCONNECTパケットでクライアントが明示的に指定します。use_username_as_clientidまたはpeer_cert_as_clientidが有効な場合は、ユーザー名や証明書のフィールド・内容で上書きされます。${peerhost}: 実行時にクライアントのIPアドレスに置換されます。EMQXはProxy Protocolをサポートしており、TCPプロキシやロードバランサーの背後にデプロイされていても実際のIPアドレスを取得可能です。${peername}: 実行時にクライアントのIPアドレスとポートに置換されます。形式はIP:PORTです。${cert_common_name}: 実行時にクライアントTLS証明書のCommon Nameに置換されます。ロードバランサーがクライアント証明書情報をTCPリスナーに送信する場合はProxy Protocol v2の使用を推奨します。${cert_subject}: 実行時にクライアントTLS証明書のSubjectに置換されます。ロードバランサーがクライアント証明書情報をTCPリスナーに送信する場合はProxy Protocol v2の使用を推奨します。${client_attrs.NAME}: クライアント属性。NAMEは事前定義設定に基づく属性名に置換されます。クライアント属性の詳細はMQTTクライアント属性を参照してください。${zone}: 実行時にクライアントのゾーンに置換されます。${zone}プレースホルダーは認可テンプレート内で直接使用可能です。ゾーン設定の詳細はゾーンオーバーライドを参照してください。
トピック内のプレースホルダー
EMQXはトピック内でもプレースホルダーを使用でき、動的なトピックをサポートします。サポートされるプレースホルダーは以下の通りです。
${clientid}${username}${client_attrs.NAME}: クライアント属性。NAMEはmqtt.client_attrs_initで設定された属性名抽出ルールに置換されます。
プレースホルダーはトピックのセグメントとして使用可能で、例:a/b/${username}/c/d。
プレースホルダーの展開を避けるため、EMQX 5.4以降は $ を ${$} とエスケープ可能です。例えば、t/${$}{username} は展開されずに文字通り t/${username} と扱われます。
TIP
クエリ文でeq構文を使用する場合、eqの後に続くトピックはプレースホルダー展開をサポートしません。この挙動は将来のバージョンで変更される可能性があります。
eq構文はトピックフィルターを厳密に一致させるためのもので、フィルターにマッチする任意のトピックを意味しません。例:eq t/# は t/# にのみマッチし、t/1やt/2にはマッチしません。
認可チェックの優先順位
キャッシュや認可チェッカーに加え、認可結果は認証フェーズでのスーパーユーザーロールと権限セットの影響を受ける場合があります。
スーパーユーザーの場合、すべての操作は認可チェックをスキップします。アクセス制御リスト(ACL)が設定されている場合、EMQXは認可チェッカーを実行する前にクライアントの権限データを優先します。優先順位は以下の通りです。
スーパーユーザー > 権限データ > 認可チェック認可機構の設定方法
EMQXは認可を設定する方法として、ダッシュボード、設定ファイル、HTTP APIの3種類を提供しています。
ダッシュボードによる認可設定
EMQXダッシュボードは直感的にEMQXオーソライザーを設定できる方法で、関連パラメータの設定、稼働状況の確認、認可チェーン内での位置調整が可能です。

設定ファイルによる認可設定
設定ファイルのauthorizationフィールドで認可を設定できます。一般的な設定構造は以下の通りです。
authorization {
sources = [
{ ... },
{ ... }
]
no_match = deny
deny_action = ignore
cache {
max_size = 32
excludes = ["t/1", "t/2"]
ttl = 1m
}
}ここで、
sources(任意):順序付き配列。各要素は対応するオーソライザーのデータソースを定義します。詳細設定は各種設定ファイルを参照してください。no_match:設定されたオーソライザーのいずれも認可ルールを見つけられなかった場合のデフォルト動作。値はallowまたはdeny。EMQX 6.0以降、デフォルトはdenyに変更されました。deny_action:パブリッシュ/サブスクライブ操作が拒否された場合の次の動作。値はignoreまたはdisconnect。デフォルトはignore。ignoreの場合は操作要求を静かに無視し、disconnectの場合はクライアント接続を切断します。cache:クライアント認可キャッシュの設定。以下を含みます。cache.enable:クライアント認可キャッシュを有効化するかどうか。デフォルトはtrue。認可がJWTパケットのみで行われる場合はfalseに設定することを推奨します。cache.max_size:キャッシュ内の最大要素数。デフォルトは32。上限を超えると古いレコードから削除されます。cache.excludes:キャッシュ生成を除外するトピックのリスト。デフォルトは空配列[]。cache.ttl:キャッシュの有効期間。デフォルトは1m(1分)。cache.max_size:キャッシュ内の最大要素数。デフォルトは32。指定数を超えると古いレコードから削除されます。
認可管理用のAPIエンドポイントは以下の通りです。
/api/v5/authorization/settings:一般パラメータ、no_match、deny_action、cacheの管理。/api/v5/authorization/sources:オーソライザーの管理と順序設定。/api/v5/authorization/cache:クライアント認可キャッシュのクリア。/api/v5/authorization/sources/built_in_database:built_in_databaseオーソライザーの認可ルール管理。
HTTP APIによる認可設定
オーソライザーの管理
/api/v5/authorization/settings:一般パラメーター、no_match、deny_action、cacheの管理。/api/v5/authorization/sources:オーソライザーの管理と順序設定。/api/v5/authorization/cache:クライアント認可キャッシュのクリア。/api/v5/authorization/sources/built_in_database:built_in_databaseオーソライザーの認可ルール管理。
操作手順の詳細はHTTP APIを参照してください。
オーソライザーの管理
ダッシュボードの アクセス制御 -> 認可 ページでオーソライザーの閲覧と管理が可能です。
オーソライザー順序の調整
認可チェーンで述べたように、オーソライザーは設定された順序に従って実行されます。その他ドロップダウンから上へ移動、下へ移動、先頭へ移動、末尾へ移動を選択して順序を変更できます。authorization.sources設定項目でも順序調整が可能です。
オーソライザーの状態確認
状態列で接続状況を確認できます。
| 状態 | 意味 | トラブルシューティング |
|---|---|---|
| 接続済み | 全ノードがデータソースに正常に接続されている状態。 | - |
| 未接続 | 一部または全ノードがデータソース(データベース、ファイル)に接続できていない状態。 | データソースの稼働状況を確認。 問題解決後、オーソライザーを手動で再起動(無効化→有効化)してください。 |
| 接続中 | 一部または全ノードがデータソースに再接続中の状態。 | データソースの稼働状況を確認。 問題解決後、オーソライザーを手動で再起動(無効化→有効化)してください。 |
実行中のメトリクス
オーソライザーの概要ページで統計メトリクスを確認できます。以下の指標が表示されます。
- 許可数: 認可が通過した回数。
- 拒否数: 認可が失敗した回数。
- 一致なし数: クライアントの認可データが見つからなかった回数。
- 無視数: 認可が適用されなかったかエラーにより判定不能となった認可クエリの回数。
- レート(tps): 認可処理の実行レート。
また、ノードステータスから各ノードの認可状況や実行状況も確認可能です。
認可全体の実行メトリクスを確認したい場合は、メトリクス - 認証&認可を参照してください。