Skip to content

セキュリティプロファイル ​

バージョン6.3以降、EMQXはノード全体のセキュリティプロファイルをサポートしています。このプロファイルはセキュリティ関連のデフォルト動作のセットを選択します。EMQXは以下の2つのプロファイルを提供しています。

  • legacy(デフォルト):以前のEMQXバージョンのデフォルト動作を維持します。
  • hardened:厳格でセキュアなデフォルト動作を適用します。

EMQX 7.0ではデフォルトでhardenedを使用する予定です。初期デプロイメントにはhardenedを使用してください。legacyからの移行前に、以下の動作変更を確認してください。

プロファイルの選択 ​

プロファイルはEMQX_SECURITY_PROFILE環境変数で選択します。これはemqxコマンドが起動時に読み込むemqx.envファイルに設定します。

  • rpmおよびdebインストール:/etc/emqx/emqx.env
  • Dockerイメージ:/opt/emqx/etc/emqx.env
  • tar.gzインストール:etc/emqx.env

ファイル内のEMQX_SECURITY_PROFILE行のコメントを外し、値を設定します。

bash
EMQX_SECURITY_PROFILE=hardened

その後、ノードを再起動してください。

emqx.env内の値は環境変数から継承した値を上書きし、パッケージのアップグレード時にも編集内容は保持されます。環境変数に直接設定することも可能です。例えばdocker run -e EMQX_SECURITY_PROFILE=hardenedや、フォアグラウンド起動前にexport EMQX_SECURITY_PROFILE=hardenedなどです。

EMQXは起動時に一度だけこの変数を読み込み、設定ファイルの解析前に適用するため、設定ファイル内でプロファイルを設定することはできません。有効な値はlegacy、hardened、または空(デフォルト選択)です。それ以外の値はノードの起動を停止させます。クラスター内の全ノードで同じ値を設定してください。

TIP

セキュリティプロファイルはあくまでデフォルト動作を変更するものです。以下に記載の多くの動作は、選択したプロファイルに関係なく個別に設定可能です。

有効なプロファイルの確認 ​

ダッシュボードで、Monitoring -> Cluster Overview -> Nodesをクリックし、Security Profile列を確認してください。この列には各ノードがlegacyまたはhardenedプロファイルで起動したかが表示されます。値は起動時に固定され、ノードの再起動後にのみ変更可能です。

稼働中の全ノードの値を比較し、クラスターが一貫したプロファイルを使用しているか確認してください。停止中のノードや6.3未満のバージョンのノードはセキュリティプロファイルを報告しません。

hardenedプロファイルの動作変更 ​

hardenedプロファイルはlegacyと比較して以下の動作を変更します。

ノードおよびクラスターのセキュリティ ​

  • 既知の安全でないErlangクッキーは拒否されます。 組み込みのデフォルトErlangクッキーや一般的なサンプル値emqxsecretcookieを使用している場合、ノードは起動しません。node.cookieを非デフォルト値に設定するか、EMQX_NODE__COOKIEを設定してからEMQXを起動してください。クラスター内の全ノードで同じクッキーを使用してください。

リスナーの公開範囲 ​

hardenedプロファイルは、明示的にバインドアドレスが指定されていないリスナーに対して、node.default_listener_address(バインドアドレスが明示されていないリスナーのノードレベル設定)で以下のデフォルトバインドアドレスを使用します。

  • MQTTリスナーはデフォルトでループバックにバインドされます。 MQTT TCP、SSL、WebSocket、セキュアWebSocket、QUICリスナーでbindが省略またはポートのみ指定の場合、ループバックインターフェースのみにバインドされます。外部接続を受け入れるには、例えばbind = "0.0.0.0:1883"のように明示的なバインドアドレスを設定してください。
  • ダッシュボードのHTTPリスナーはデフォルトでループバックにバインドされます。 ダッシュボードHTTPリスナーでbindが省略またはポートのみ指定の場合、ループバックインターフェースのみにバインドされます。外部接続を受け入れるには明示的なバインドアドレスを設定してください。

Dockerイメージのデフォルト

公式Dockerイメージはこれらのプロファイルデフォルトを上書きします。EMQX_NODE__DEFAULT_LISTENER_ADDRESSが未設定または空の場合、イメージのエントリポイントがallに設定します。そのため、bindが省略またはポートのみ指定のリスナーは、legacyおよびhardenedプロファイルの両方でコンテナ内の全インターフェースにバインドされます。この設定により、Dockerで公開されたポートからこれらのリスナーにアクセス可能です。リスナーがコンテナ外部から到達可能かどうかは、コンテナのネットワーク設定および公開ポートの設定に依存します。

この設定はゲートウェイリスナーにも適用されますが、ゲートウェイリスナーのデフォルトバインドアドレスはセキュリティプロファイルによって変更されません。対応する値や設定の詳細はDefault Listener Addressを参照してください。

認証 ​

  • 明示的な認証が必須です。 認証器が設定されていない場合や全ての認証器が無効の場合、クライアントは拒否されます。リスナーで匿名アクセスを明示的に許可するには、enable_authn = falseを設定してください。
  • 認証バックエンドの障害はアクセス拒否となります。 認証バックエンドのエラー、応答の不正、認証器の前提条件評価エラー、JWT検証キーの未取得は、次の認証器に進まずクライアントを拒否します。authentication_settings.ignore_backend_failures = trueを設定すると、後続の認証器にフォールバック可能です。
  • JWT認証器はJWTがない場合を無視しません。 JWT認証器は設定されたJWTフィールドを省略したクライアントを拒否します。on_missing_jwt = ignoreを設定すると、次の認証器に進めます。
  • 混合認証チェーンでは非JWT資格情報はJWT認証器をスキップする必要があります。 JWT認証器は不正なJWTを受け取ると認証に失敗します。JWT認証器と後続のパスワード認証器が同じフィールド(例:password)からJWTまたはパスワードを読み取る場合、JWT認証器にprecondition = "is_jwt(password)"を設定し、平文パスワードは次の認証器に進むようにしてください。
  • JWTのJWKS TLS検証が有効です。 JWT認証器はJWKS HTTPSエンドポイントからキーを取得する際にピア証明書とホスト名を検証します。信頼されていない証明書のエンドポイントは利用不可になります。特定のJWKSエンドポイントで検証を無効にするにはssl.verify = verify_noneを設定してください。

認可 ​

  • 認可バックエンドの障害は操作拒否となります。 認可バックエンドのエラー、不正なルール、テンプレート評価エラーは、後続の認可ソースに進まずパブリッシュやサブスクライブ操作を拒否します。authorization.ignore_backend_failures = trueを設定するとバックエンド障害を無視して次の認可ソースに進みます。
  • 認可トピックテンプレートの置換に禁止文字が含まれると操作拒否となります。 デフォルトでは、置換値に/、+、#が含まれるとlegacyではマッチなし、hardenedでは操作拒否となります。例えばクライアントIDがi/am/+/good/#の場合、ルール{allow, all, all, ["t/${clientid}/#"]}.にマッチします。個別の文字はauthorization.topic_template_allow.slash、authorization.topic_template_allow.plus、authorization.topic_template_allow.hashで許可可能です。
  • デフォルトのファイル認可ソースはdeny-by-defaultです。 デフォルトのacl.confは最後に{allow, {security_profile, legacy}}.を含み、legacyプロファイルでは操作を許可し、hardenedでは適用されません。hardenedではルールにマッチしない操作はauthorization.no_matchにフォールバックし、デフォルトはdenyです。許可的な動作にするには最終ルールを{allow, all}.に変更してください。{security_profile, legacy}および{security_profile, hardened}条件は任意のacl.confルール内(andやor式内も含む)で使用可能で、選択したプロファイルにのみ適用するカスタムルールを作成できます。
  • 内部サブスクリプションは認可されます。 Auto Subscribeなどの機能によるサブスクリプションはトピック検証、認可、機能チェック、サブスクライブフックを通過します。権限のある管理者による強制サブスクライブ操作はMQTT認可をバイパスし続けます。

遅延パブリッシュ ​

  • 遅延メッセージは再生時に再認可されます。 EMQXはメッセージがスケジュールされた時点で保存された認可コンテキストを使い、現在のパブリッシュ認可ルールと禁止レコードをチェックします。スケジュール時に認可されたメッセージでも再生時に破棄されることがあります。

重要なお知らせ

hardenedプロファイルでは、アップグレード前に作成された認可コンテキストを含まない保留中の遅延メッセージは破棄されます。legacyプロファイルではこれらのメッセージは再生され続けます。

拡張機能 ​

  • アクセス制御フックの失敗はリクエスト拒否となります。 認証または認可フックで例外が発生すると処理が中断されリクエストは拒否されます。これはプラグインやExHook拡張によるカスタム認証・認可で特に重要です。
  • ExHookのmessage.publish失敗はパブリッシュ拒否となります。 利用可能なExHookサーバーがない場合や、failed_actionがdenyのExHookサーバーがmessage.publish処理中に失敗すると、EMQXはメッセージのパブリッシュを防ぎます。legacyでは同様の失敗でもパブリッシュはブロックされません。
  • プラグインのインストールにはパッケージダイジェストが必要です。 emqx ctl plugins allow <Name-Vsn>はsha256:<hex>引数が必須です。この権限はプラグインパッケージをそのダイジェストに紐付け、EMQXはバイトが一致する場合のみインストールします。ダイジェストなしの権限は拒否され、クラスターのピアが送信したものも含みます。legacyでは引数は任意のままです。

ダッシュボード ​

  • デフォルトのダッシュボード認証情報は受け付けられません。 デフォルトパスワードpublicのローカルダッシュボードアカウントはログインできません。アップグレード前に作成された管理者アカウントも含みます。hardenedプロファイルに切り替える前にパスワードを変更してください。

デフォルトリスナーアドレス ​

node.default_listener_address設定オプションは、明示的なアドレスがないリスナーのバインドアドレス(例:bind = 1883のようなポートのみ指定)を設定します。MQTTリスナー、ゲートウェイリスナー、ダッシュボードHTTPリスナーに適用されます。明示的なIP:portバインドは常に優先されます。

EMQXは各ノードでローカルにデフォルトアドレスを決定し、リスナー起動時に適用します。設定されたbind値は変更されず、ポートのみのバインドが永続的なIP:port値になることはありません。そのため、同じリスナー設定でもノードごとに異なるアドレスでリスン可能です。

このオプションを使い、セキュリティプロファイルとは独立してリスナーの公開範囲を制御できます。例えばhardenedプロファイルを維持しつつ、デフォルトリスナーを全ネットワークインターフェースにバインドするには、ノードのemqx.confに以下を追加します。

hocon
node.default_listener_address = "all"

有効な値:

値バインドアドレス
loopback127.0.0.1。ダッシュボードはinet6オプションが設定されている場合、代わりに::1にバインドします。
nodenameErlangノード名の@以降のホスト部分。IPアドレスの場合はそのままバインドし、そうでなければ起動時に解決し、最初のIPv4アドレス、IPv4がなければ最初のIPv6アドレスにバインドします。
all全ネットワークインターフェース。デフォルトのIPv4設定では0.0.0.0です。アドレスファミリーはリスナー設定に依存します。
IPアドレス例えば192.168.1.10や::1のようなリテラルアドレス。多くのシステムでは::がIPv4とIPv6の両方を受け入れます。OSのbindv6only設定に依存します。
ホスト名起動時に解決されます。例:broker1.example.com。

このオプションが設定されていない場合、セキュリティプロファイルがMQTTリスナーとダッシュボードHTTPリスナーのデフォルトアドレスを決定します。legacyは全インターフェースにバインドし、hardenedはループバックにバインドします。ゲートウェイリスナーはどちらのプロファイルでも全インターフェースにバインドします。

このオプションはノードローカルであり、EMQXは起動時に一度だけ読み込みます。変更にはノードの再起動が必要です。EMQX_NODE__DEFAULT_LISTENER_ADDRESS環境変数でも設定可能です。

TIP

公式Dockerイメージのエントリポイントは、変数が未設定または空の場合にEMQX_NODE__DEFAULT_LISTENER_ADDRESS=allを設定します。これはコンテナのループバックインターフェースが公開ポート経由で到達できないためです。このデフォルトにより、ポートのみ指定のリスナーはどちらのプロファイルでも全ネットワークインターフェースにバインドされ、公開されたコンテナポートからアクセス可能になります。上書きするには、環境変数を明示的に他の有効な値に設定してください。明示的なIPアドレスを指定したリスナーバインドは変更されません。

セキュリティプロファイル間のバックアップ復元 ​

データバックアップはエクスポート元ノードのセキュリティプロファイルを記録します。デフォルトで、EMQXはhardenedノードに対し、記録されたプロファイルがlegacyのバックアップやメタデータがないバックアップのインポートを拒否します。legacyノードへのインポートは影響を受けません。

この保護を上書きする前にプロファイル間の違いを確認してください。互換性ルールや上書き方法はBackup and Restoreを参照してください。

ローリングアップグレード ​

クラスター内の全ノードは同じセキュリティプロファイルを使用する必要があります。ノード間でプロファイルが異なる場合、アクセス制御の判断はクライアントが接続するノードによって異なります。6.3未満のバージョンを実行するノードは常にlegacyとして動作します。

6.3未満のバージョンからローリングアップグレードを行う場合:

  1. アップグレードしたノードにEMQX_SECURITY_PROFILE=hardenedを設定しないでください。変数を未設定にするか、legacyに設定し、アップグレード済みノードが旧バージョンのノードと同様に動作するようにします。
  2. 全ノードのローリングアップグレードを完了させます。
  3. その後、以下の移行手順に従いクラスターをhardenedに切り替えます。

移行手順 ​

既存のデプロイメントをlegacyからhardenedに移行するには:

  1. 上記の各動作変更を確認し、厳格なデフォルトが適合しない場合は明示的に設定を適用します。
  2. デフォルトでないErlangクッキーを設定し、クラスター内の全ノードが同じ値を使用していることを確認します。
  3. 外部接続を受け入れる必要がある場合は、リスナーとダッシュボードに明示的なバインドアドレスが設定されているか、またはすべてのデフォルトリスナーに対してnode.default_listener_addressを設定していることを確認します。
  4. 全ノードに認証が設定されているか、または匿名アクセスが明示的に許可されていることを確認します。
  5. デフォルトパスワードを使用しているダッシュボードアカウントをすべて変更します。
  6. アップグレード後にhardenedを有効にする前に、アップグレード前に作成された保留中の遅延メッセージが再生されるのを待つか、EMQXがそれらを破棄することを受け入れてください。
  7. 全ノードにEMQX_SECURITY_PROFILE=hardenedを設定し、1台ずつ再起動します。

以前の動作を維持するには、EMQX_SECURITY_PROFILE=legacyを設定するか、変数を未設定のままにしてください。