Skip to content

認可

EMQXにおける認可とは、MQTTクライアントのパブリッシュ/サブスクライブ操作に対する権限管理を指します。クライアントがパブリッシュ/サブスクライブ操作を行う際、EMQXは特定の手順に従うか、ユーザー指定のクエリ文を用いて設定されたデータソースからクライアントの権限リストを照会します。照会結果に基づき、EMQXは現在の操作を許可または拒否します。

クライアントの単一の権限データは以下の要素で構成されます:

権限クライアント操作操作の詳細
Allow/DenyクライアントID/ユーザー名/IPPublish/Subscribe/Publish-Subscribeトピック/QoS/保持メッセージ

TIP

EMQX 5.1.1以降、操作の詳細におけるQoSおよび保持メッセージのチェックがサポートされました。

クライアントの権限リストは事前に特定のデータソース(データベース、ファイルなど)に保存しておく必要があります。対応するデータレコードを更新することで、実行時にリストを更新可能です。

EMQXではデフォルトでファイルベースのオーソライザーが設定されており、そのまま利用できます。認可はACLファイルに設定された事前定義ルールに基づいて処理されます。

データストレージオブジェクトとの統合

EMQXの認可機構は、組み込みデータベース、ファイル、MySQL、PostgreSQL、MongoDB、Redisなど多様なデータストレージオブジェクトとの統合をサポートしています。権限データはREST APIやEMQXダッシュボードを通じて管理可能です。

さらに、EMQXはユーザーが開発したHTTPサービスと接続し、異なる認可要件に対応することも可能です。

バックエンドのデータストレージに応じて、以下のような種類のEMQXオーソライザーがあります。各オーソライザーは独自の設定オプションを持ちます。詳細は表中のリンクを参照してください。

データベース説明
ACLファイルファイルに設定された静的ルールによる認可
組み込みデータベース組み込みデータベースをルールストレージとした認可
MySQLMySQLをルールストレージとした認可
PostgreSQLPostgreSQLをルールストレージとした認可
MongoDBMongoDBをルールストレージとした認可
RedisRedisをルールストレージとした認可
LDAPLDAPディレクトリをルールストレージとした認可
HTTP外部HTTPサービスを利用した認可

以下はEMQXのMySQLオーソライザーの設定例です。

例:

bash
{

    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はチェーン内のオーソライザーの順序に従い順番に認可を実行します。認可チェーンが設定されている場合、最初のオーソライザーで一致する認可情報が取得できないと、次のオーソライザーに切り替えて処理を継続します。

認可チェックの流れは以下の通りです:

  1. EMQXがクライアントの権限情報を正常に取得した場合、クライアントの操作と取得した権限リストを照合します。

    • 一致すれば、権限設定に基づき操作を許可または拒否します。
    • 一致しなければ、次のオーソライザーに切り替えて処理を継続します。
  2. EMQXがクライアントの権限情報を取得できなかった場合、他のオーソライザーが設定されているか確認します。

    • 設定されていれば、次のオーソライザーに切り替えて処理を継続します。
    • 最後のオーソライザーであれば、no_matchの設定に従いクライアントの操作を許可または拒否します。

注意

認可の問題を避けるため、ACLファイルオーソライザーは必要に応じて無効化または削除してください。デフォルトで末尾に {allow, all} があり、すべての認可リクエストを許可してしまうためです。

オーソライザーの順序調整や稼働状況の確認方法は、オーソライザー管理を参照してください。

クライアント認可キャッシュ

EMQXはセッションベースの認可データキャッシュ機構を提供しています。このキャッシュはクライアントのセッション状態に認可結果を保存し、同一接続内での繰り返し認可ルール評価を減らします。クライアント認可キャッシュはクライアントのパブリッシュ/サブスクライブ操作の権限チェック効率を向上させ、多数のクライアントリクエストによる認可データバックエンドへのアクセス負荷軽減に寄与します。

クライアント認可キャッシュの動作

クライアントが接続しパブリッシュ/サブスクライブ操作を行う際:

  1. EMQXは現在のセッションに保存された認可キャッシュを確認します。
  2. セッションキャッシュに一致するルールがあれば、それを直接使用します。
  3. キャッシュが存在しないか期限切れの場合、設定されたオーソライザーで完全な認可チェックを行います。
  4. 結果はセッションにキャッシュされ、同一接続内で再利用されます。

TIP

キャッシュはクライアントセッション固有であり、クライアントの切断または再接続時にクリアされます。

ダッシュボードでのクライアント認可キャッシュ設定

EMQXダッシュボードでクライアント認可キャッシュを有効化・設定できます:

  1. アクセス制御 -> 認可 -> 設定 に移動します。

  2. 以下のオプションを設定します:

    項目名説明
    キャッシュを有効にするクライアントセッションごとの認可キャッシュを有効/無効に切り替えます。
    キャッシュ最大件数クライアントごとのキャッシュ最大エントリ数。デフォルト:32
    キャッシュ有効期限キャッシュエントリの有効期間。デフォルト:1分
    除外トピックキャッシュを無効にするトピックのリスト。
    一致しない場合の動作オーソライザーが一致しなかった場合の動作。allow(許可)/deny(拒否)。デフォルト:allow
    拒否時の動作操作が拒否された場合の動作。ignore(操作リクエストを無視)/disconnect(クライアント接続を切断)。デフォルト:ignore
    キャッシュクリアアクティブなセッション認可キャッシュを手動で全てクリアするボタン。

これらの設定は設定ファイルからも行えます。詳細は設定ファイルを参照してください。

TIP

適切に設定すればキャッシュはパフォーマンスを大幅に向上させます。システムの状況に応じて設定を調整することを推奨します。

外部リソースキャッシュ

セッションベースのキャッシュに加え、EMQXはMySQL、MongoDB、Redisなどの外部バックエンドから取得した認可結果をノードレベルでキャッシュする機能も提供しています。この機能により、リモートデータソースへの繰り返しアクセスを減らしパフォーマンスを向上させます。

注意

外部リソースキャッシュは外部データソースにのみ適用されます。組み込みデータベースやファイルベースのオーソライザーには適用されません。

外部リソースキャッシュの動作

パブリッシュ/サブスクライブ操作が外部バックエンドへのクエリをトリガーした場合:

  1. EMQXは外部リソースキャッシュ(ノード全体で共有)を確認します。
  2. キャッシュに有効な結果があれば、キャッシュヒットとカウントし外部バックエンドへの呼び出しは行いません。
  3. 結果がなければ、キャッシュミスとカウントし外部バックエンドにクエリを送ります。
  4. バックエンドから返された結果はキャッシュに保存され、キャッシュ挿入メトリクスが増加します。

注意

セッションベースの認可キャッシュと異なり、外部リソースキャッシュはノード単位で全クライアント間で共有され、クライアントセッションを跨いで持続します。

外部リソースキャッシュの有効化と設定

EMQXダッシュボードから外部リソースキャッシュを有効化および設定できます。

  1. アクセス制御 -> 認可 に移動します。

  2. 右上の 外部リソースキャッシュ設定 ボタンをクリックします。右側からサイドパネルが表示されます。

  3. パネル内で 外部リソースキャッシュを有効にする ボタンを使ってキャッシュ機能をオンまたはオフにします。有効化したら、以下のキャッシュ設定を行います。

    フィールド名説明
    最大キャッシュアイテム数ノードごとの最大キャッシュエントリ数。デフォルト:1,000,000
    最大メモリキャッシュメモリ使用量の上限。デフォルト:100 MB
    キャッシュTTLキャッシュエントリの有効期間。デフォルト:1分
  4. 更新 をクリックして設定を適用します。

これらの設定はクラスター全体に適用され、すべてのノードで一貫した動作を保証します。

外部リソースキャッシュの状態監視

キャッシュメトリクスを表示し、リアルタイムで使用状況を監視するには:

  1. External Resource Cache Settings の横にある矢印をクリックし、External Resource Cache Status を選択します。サイドパネルが表示され、キャッシュメトリクスが確認できます。
  2. ドロップダウンメニューを使って、ノード単位またはクラスター全体のメトリクスを表示できます。

メトリクスには以下が含まれます:

  • Memory Usage:キャッシュが現在使用している合計メモリ量。
  • Cache Entries:保存されているキャッシュ結果の総数。
  • Cache Hits:EMQXがキャッシュ内で有効な結果を見つけ、外部バックエンドへの呼び出しを回避した回数。
    • 表示されるメトリクス:現在のレート、5分間平均、最大レート
  • Cache Misses:EMQXがキャッシュ内で結果を見つけられず、バックエンドクエリが発生した回数。
    • 表示されるメトリクス:現在のレート、5分間平均、最大レート
  • Cache Inserts:ミス後にキャッシュに新しい結果が追加された回数。
    • 表示されるメトリクス:現在のレート、5分間平均、最大レート

パネル下部にはノードリストがあり、クラスター内の各ノードごとの Memory UsageCache EntriesCache Hits の概要を確認できます。

パネル右上のボタンで統計情報の更新やリセットが可能です。

認可プレースホルダー

EMQXのオーソライザー設定ではプレースホルダーを使用可能です。認可処理時にこれらは実際のクライアント情報に置き換えられ、現在のクライアントに合致するクエリやHTTPリクエストを構築します。

有効なプレースホルダーは ${PATH.TO.VALUE} の形式で、PATH.TO.VALUEはオブジェクト内の値へのドット区切りパスです。使用可能な文字は英数字、ドット(.)、アンダースコア(_)です。サポートされていない文字を含むプレースホルダーは文字列として扱われます。

データクエリ内のプレースホルダー

プレースホルダーはクエリ文の構築に使われます。例えば、EMQX MySQLオーソライザーのデフォルトクエリは ${username} を使っています:

sql
SELECT action, permission, topic FROM mqtt_acl where username = ${username}

クライアント(名前:emqx_u)が接続リクエストを送ると、構築されるクエリは以下のようになります:

sql
SELECT action, permission, topic FROM mqtt_acl where username = 'emqx_u'

クエリ文でサポートされるプレースホルダーは以下の通りです:

  • ${username}:実行時にユーザー名に置き換えられます。ユーザー名はCONNECTパケットのUsernameフィールドから取得されます。peer_cert_as_usernameが有効な場合は証明書のフィールドや内容で上書きされます。
  • ${clientid}:実行時にクライアントIDに置き換えられます。通常はCONNECTパケットでクライアントが明示的に指定します。use_username_as_clientidpeer_cert_as_clientidが有効な場合はユーザー名や証明書のフィールド・内容で上書きされます。
  • ${peerhost}:実行時にクライアントのIPアドレスに置き換えられます。EMQXはProxy Protocolをサポートしており、TCPプロキシやロードバランサーの背後にあっても実際のIPアドレスを取得可能です。
  • ${peerport}:実行時にクライアントの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}:クライアント属性。NAMEmqtt.client_attrs_initで設定された属性名抽出ルールにより置き換えられます。

プレースホルダーはトピックのセグメントとして使用可能で、例:a/b/${username}/c/d のように記述します。

プレースホルダーの展開を避けたい場合、EMQX 5.4以降は $${$} とエスケープできます。例えば、t/${$}{username} は展開されず文字通り t/${username} と解釈されます。

TIP

クエリ文で eq 構文を使う場合、eq の後に続くトピックはプレースホルダー展開をサポートしません。この挙動は将来のバージョンで変更される可能性があります。

eq 構文はトピックフィルターと完全一致を判定するもので、フィルターにマッチする任意のトピックを意味しません。例:eq t/#t/# にのみマッチし、t/1t/2 にはマッチしません。

認可チェックの優先順位

キャッシュや認可チェッカーに加え、認可結果は認証フェーズのスーパーユーザーロールと権限セットの影響を受けます。

スーパーユーザーの場合、すべての操作は認可チェックをスキップします。アクセス制御リスト(ACL)が設定されている場合、EMQXは認可チェッカー実行前にクライアントの権限データを優先して参照します。優先順位は以下の通りです:

bash
スーパーユーザー > 権限データ > 認可チェック

認可機構の設定

EMQXは認可設定を以下の3つの方法で行えます:ダッシュボード、設定ファイル、HTTP API。

ダッシュボードでの認可設定

EMQXダッシュボードは直感的にオーソライザーを設定できるインターフェースです。関連パラメータの設定、稼働状況の確認、認可チェーン内の位置調整が可能です。

ダッシュボードによる認証設定

設定ファイルでの認可設定

設定ファイルの authorization フィールドに認可設定を記述できます。一般的な構成例は以下の通りです:

bash
authorization {
  sources = [
    { ...   },
    { ...   }
  ]
  no_match = allow
  deny_action = ignore
  cache {
    max_size = 32
    excludes = ["t/1", "t/2"]
    ttl = 1m
  }
}

各項目の説明:

  • sources(任意):順序付き配列。各要素は対応するオーソライザーのデータソースを定義します。詳細は各オーソライザーの設定ファイルを参照してください。

  • no_match:設定されたオーソライザーのいずれも認可ルールを見つけられなかった場合のデフォルト動作。値は allow または deny。デフォルトは allow。この設定によりブラック/ホワイトリスト機能も有効になります。

  • deny_action:パブリッシュ/サブスクライブ操作が拒否された場合の次の処理。値は ignore または disconnect。デフォルトは ignoreignore は操作を静かに無視し、disconnect はクライアント接続を切断します。

  • cache:クライアント認可キャッシュの設定。以下を含みます:

    • cache.enable:クライアント認可キャッシュの有効/無効。デフォルトは true。JWTパケットのみで認可を行う場合は false に設定することを推奨します。

    • cache.max_size:キャッシュ内の最大要素数。デフォルトは32。上限を超えた古いレコードは削除されます。

    • cache.excludes:キャッシュ対象外のトピックリスト。デフォルトは空リスト []

    • cache.ttl:キャッシュの有効期間。デフォルトは 1m(1分)。

HTTP APIでの認可設定

認可管理用のAPIエンドポイントは以下の通りです:

  • /api/v5/authorization/settings:一般パラメータ、no_matchdeny_actioncacheの管理
  • /api/v5/authorization/sources:オーソライザーの管理と順序調整
  • /api/v5/authorization/cache:クライアント認可キャッシュのクリア
  • /api/v5/authorization/sources/built_in_databasebuilt_in_databaseオーソライザーの認可ルール管理

詳細な操作手順はHTTP APIを参照してください。

オーソライザー管理

ダッシュボードの アクセス制御 -> 認可 ページでオーソライザーの閲覧・管理が可能です。

オーソライザーの順序調整

認可チェーンで述べた通り、オーソライザーは設定された順序で実行されます。その他ドロップダウンから「上へ」「下へ」「先頭へ移動」「末尾へ移動」を選択して順序を変更できます。authorization.sources設定項目でも順序を調整可能です。

オーソライザーの状態確認

状態列で接続状態を確認できます:

状態意味トラブルシューティング
Connectedすべてのノードがデータソースに正常に接続されている。-
Disconnected一部または全ノードがデータソース(データベース、ファイル)に接続できていない。データソースの稼働状況を確認;
問題解決後にオーソライザーを手動で再起動(無効化有効化
Connecting一部または全ノードがデータソースに再接続中。データソースの稼働状況を確認;
問題解決後にオーソライザーを手動で再起動(無効化有効化

稼働メトリクス

オーソライザーの概要ページで各種統計メトリクスを確認できます。主なメトリクスは以下の通りです:

  • Allow:許可された認可数
  • Deny:拒否された認可数
  • No match:クライアントの認可データが見つからなかった回数
  • Ignored:認可が適用されなかったかエラーで判定できなかったため無視された認可クエリ数
  • Rate(tps):認可処理の実行レート

また、ノード状態から各ノードの認可状況や実行状況も確認可能です。

認可全体の稼働メトリクスを確認したい場合は、メトリクス - 認証&認可を参照してください。