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起動前にEMQX_NODE__COOKIEを設定してください。クラスター内のすべてのノードで同じクッキーを使用してください。

リスナーの公開範囲 ​

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

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

この設定はゲートウェイリスナーにも適用されますが、ゲートウェイリスナーのデフォルトバインドアドレスはセキュリティプロファイルによって変更されません。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)"を設定し、プレーンパスワードは次の認証機構に進むようにしてください。
  • 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アドレスを指定したリスナーバインドは変更されません。

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

データバックアップはエクスポート元ノードのセキュリティプロファイルを記録します。デフォルトでは、legacyとして記録されたバックアップやこのメタデータがないバックアップは、hardenedノードへのインポート時に拒否されます。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を設定するか、変数を未設定のままにしてください。