# セキュリティチェックリスト

このチェックリストは、EMQXのデプロイメントを本番トラフィックに公開する前にレビューするためのものです。セキュリティ層ごとに整理されており、オペレーティングシステムからダッシュボードまでの全経路を検証できます。初期展開時、主要なトポロジー変更後、および定期的なセキュリティレビューの一環としてご利用ください。

## フェーズ1：インフラストラクチャとOS

- ノードが通常または悪意のある接続負荷下で失敗しないように、オペレーティングシステムのファイルディスクリプタ制限およびサービスレベルの`LimitNOFILE`設定を接続規模に合わせて引き上げてください。
- SYNフラッド保護、接続追跡容量、信頼できるインターフェースのみでのリスナー公開など、長時間接続されるMQTTトラフィックに対してTCPスタックとファイアウォールの設定を強化してください。
- クライアントが実際に必要とするリスナーのみを公開してください。信頼できないネットワークでは、`8883`や`8084`などの暗号化リスナーを優先し、`1883`などの平文リスナーは内部または移行用ケースに制限してください。[Listener Configuration](../configuration/listener.md)および[Enable SSL/TLS Connection](../network/emqx-mqtt-tls.md)を参照してください。
- クラスター内で使用されるポートマッピングについては、[Cluster Security](../cluster/security.md)を参照し、ノード間のポートをセキュリティグループまたはファイアウォールルールで制限してください。
- ノードに複数のインターフェースがある場合は、Erlang分散トラフィックをプライベートネットワークインターフェースのみにバインドしてください。
- EMQXをロードバランサーやTCPプロキシの背後にデプロイする場合、実際のクライアントIPアドレスやクライアント証明書情報が必要なリスナーにのみ[Proxy Protocol](../cluster/lb.md)を有効にしてください。
- リスナーでProxy Protocolが有効な場合、そのアドレスとポートは指定されたプロキシまたはロードバランサーにのみ公開してください。EMQXでは`listeners.{type}.{name}.access_rules = ["allow <trusted-LB-CIDR>", "deny all"]`とネットワークレベルの制御（ファイアウォール、プライベートネットワーク、Unixソケット）を組み合わせてこれを強制します。そうしないと、ポートに直接到達したクライアントが任意のピア証明書フィールドを持つPROXY v2フレームを作成し、任意のIDを偽装できます。
- EMQX 6.3.0以降では、WebSocketリスナー（`ws`または`wss`）が信頼できるプロキシから転送ヘッダーを上書きしてクライアントアドレスやポートを取得する必要がない限り、`proxy_address_header`および`proxy_port_header`は空のデフォルトのままにしてください。
- これらのオプションは適切なパスで設定してください：
  - MQTTリスナー：`listeners.{type}.{name}.websocket`
  - OCPPおよびNATSゲートウェイリスナー：`gateway.<gateway-name>.listeners.{type}.{name}.websocket`
- クライアントがリスナーに直接アクセスできる場合、任意の設定済みヘッダーを送信可能です。これらのヘッダーは、プロキシがクライアント送信値を上書きする場合のみ信頼してください。値の追加はなりすましを防ぎません。ヘッダーが存在しないか無効な場合、EMQXは対応するTCPピアアドレスまたはポートを使用します。[Forwarded Client Address](../configuration/listener.md#forwarded-client-address-websocket-listeners)を参照してください。

## フェーズ2：Erlangとクラスター

- クラスター内のすべてのノードでデフォルトのノードクッキーを置き換え、すべてのメンバーで同じ高エントロピーのシークレットを使用してください。[Set Node Cookie](../cluster/security.md#set-node-cookie)を参照してください。
- `emqx.conf`、ACLファイル、証明書、秘密鍵、その他のシークレット情報は厳格なファイル権限と安全なシークレット管理プロセスで保護してください。
- 可能な限り、シークレット型フィールドはインライン値ではなく`file://`参照として保存してください。SSLキーのパスフレーズ、ブリッジやコネクタのパスワード、APIキーなど、シークレットとして文書化されているフィールドはすべて`file:///path/to/secret`の形式に設定し、EMQXが起動時およびリロード時にファイルから読み込むようにしてください。これにより、平文のシークレットが設定ファイル、APIリクエストボディ、設定バックアップ、バージョン管理に含まれず、共有やエクスポート時の漏洩リスクが低減します。[Load Secrets from a File](../configuration/secret-from-file.md)を参照してください。
- クラスタリングポートは内部に限定し、トラフィックが信頼度の低いネットワークやパブリッククラウド境界を越える場合はノード間通信にTLSを有効にしてください。[Cluster Security](../cluster/security.md)を参照してください。
- ノード追加、ネットワーク移動、デプロイメントトポロジー変更後はファイアウォールルール、証明書、クラスター参加制御を再確認してください。

## フェーズ3：トランスポートセキュリティ

- トラフィックが信頼できないネットワークを越える場合は、本番MQTTリスナーにTLSを使用してください。[Network and TLS](../network/overview.md)を参照してください。
- 組織のセキュリティ基準に従い、レガシープロトコルバージョンや弱い暗号スイートを無効化し、ステージング環境で最終的なリスナー設定を検証してください。
- 信頼できるCAまたは内部PKIが発行した証明書を使用し、有効期限前にローテーションしてください。
- デバイスのIDをクライアント証明書で検証する場合は相互TLSを有効にしてください。このモデルではTLSハンドシェイク中にクライアント証明書チェーンと証明書の存在を検証します。[X.509 Certificate Authentication](./authn/x509.md)を参照してください。
- ピア証明書フィールドをMQTTのユーザー名またはクライアントIDにマッピングする場合（`peer_cert_as_username` / `peer_cert_as_clientid`）、リスナーは必ずmTLSを強制してください（`verify = verify_peer`、`fail_if_no_peer_cert = true`）かつ管理下のCAバンドルを使用してください。これがないと、クライアントは攻撃者が選んだCN/DNを持つ自己署名証明書を提示して任意のIDを偽装できます。空のユーザー名の場合の追加対策として、`listeners.{type}.{name}.enable_authn = quick_deny_anonymous`を設定してください。[Certificate Information Mapping](./authn/x509.md#certificate-information-mapping)を参照してください。
- 証明書失効が重要な環境では、[CRLチェック](../network/crl.md)や[OCSPスタップリング](../network/ocsp.md)の導入を検討してください。
- HTTP認証、データベース、その他の統合先など外部リソースへのアウトバウンド接続にTLSを有効にしてください。

## フェーズ4：MQTTアクセス制御とリソース保護

- 公開リスナーを公開する前に少なくとも1つの認証機構を設定してください。デフォルトでは、認証が有効でない場合、EMQXはすべてのクライアントの接続を許可します。[Authentication](./authn/authn.md)を参照してください。
- 共有ユーザー名、パスワード、証明書ではなく、デバイスまたはアプリケーションごとの資格情報を推奨します。
- 認証機構が許す場合は、MQTTクライアントIDを認証済みIDにバインドしてください。例えば、JWTの`clientid`クレームを検証したり、証明書フィールドを[`peer_cert_as_clientid`](./authn/x509.md#certificate-information-mapping)でマッピングしたり、HTTP認証機構で不一致を拒否したり、[Client-Info](./authn/cinfo.md)ルールと組み合わせたりします。これを行わない場合：
  - 資格情報が漏洩すると、攻撃者はランダムなクライアントIDで無制限のセッションを作成でき、長い[Session Expiry Interval](../../get-started/messaging/mqtt-concepts.md)によりアイドル状態の永続セッションが蓄積され、ブローカーのメモリが枯渇します。
  - 攻撃者が有効な資格情報を持ち、被害者のクライアントIDを知っている場合、被害者のセッションを乗っ取れます。MQTTはクライアントIDのみでセッションを識別・再開します。攻撃者が同じクライアントIDで接続すると、EMQXは被害者を切断します。MQTT 5.0クライアントの場合、EMQXは理由コード`0x8E`（`Session taken over`）付きの`DISCONNECT`パケットを送信します。
  - `Clean Start = 0`の場合、攻撃者は被害者のセッションを再開し、既存のサブスクリプションを継承します。EMQXはサブスクリプション作成時に認可を行い、継承されたサブスクリプションを再評価しません。したがって攻撃者は自身の認可ルールで拒否されるメッセージも受信可能です。

  クライアントIDを認証済みIDにバインドすることで、接続時に認証機構がID不一致を拒否し、この乗っ取りを防止します。この継承サブスクリプションのリスクはパブリッシュには影響しません。EMQXは各パブリッシュ操作を現在のIDに対して認可します。
- X.509、JWT、SCRAM、または安全なデータベースに基づくパスワード認証など、信頼モデルに合った認証機構を選択してください。
- パスワード認証を使用する場合は、平文ではなくソルト付きパスワードハッシュを保存し、`bcrypt`や`pbkdf2`など強力なアルゴリズムを推奨します。
- トピック権限は可能な限り狭く設定し、ワイルドカードの使用は慎重にレビューしてください。[Authorization](./authz/authz.md)を参照してください。
- 認可トピックテンプレート内で`${clientid}`、`${username}`、`${client_attrs.X}`を使用する場合、補間値にこれらの文字が含まれる必要がない限り、`authorization.topic_template_allow.plus`、`authorization.topic_template_allow.hash`、`authorization.topic_template_allow.slash`を`false`にしてください。EMQX 6.3.0以降、これらのデフォルト設定により、クライアント由来の値にMQTTトピックワイルドカード（`+`、`#`）やトピック区切り文字（`/`）が含まれてもルールのトピックフィルターが広がるのを防ぎます。例えば、クライアントIDに`+`や`tenantA/+`を代入して`clients/${clientid}/data`とすると、本来のクライアント割当トピック外へのアクセスが許可される恐れがあります。
- 追加の安全策として、認可トピックテンプレートで使用する前にクライアントID値を検証してください。[Client-Info](./authn/cinfo.md)ルールやJWTクレームパターンで厳格な形式を強制するか、HTTP認証機構で非準拠値を拒否する設定も可能です。組み込みの検証とセキュリティプロファイルの挙動については[Topic Placeholders](./authz/authz.md#topic-placeholders)を参照してください。
- HTTP認証、HTTP認可、データ統合コネクター、ブリッジ、アクションなど外部サービスへのアウトバウンドリクエストを設計する際は、各シークレットをEMQXが機密として認識するフィールドまたはヘッダーに格納してください。これにより、関連ログ、トレース、設定APIレスポンスで値が`******`にマスクされます。マスクはフィールド名やヘッダー名で制御されます。HTTPヘッダーに資格情報を置く場合は、EMQXが常にマスクする標準の`Authorization`（または`Proxy-Authorization`）ヘッダーを使用してください。その他の設定フィールドのシークレットは、`password`、`token`、`secret`、`secret_key`、`jwt`など認識される機密キー名を付けてください。`x-custom-secret`のような非標準カスタムヘッダーや慣習外のフィールド名は認識されず、`debug`レベルのログやエラーメッセージに平文で表示される可能性があります。
- 本番環境で認可に依存する前に、許容的なデフォルトルールを削除または調整してください。
- ファイルベースのACLでは、適切な場合にデフォルト拒否の姿勢を採用してください。例えば、ルールの末尾に`{deny, all}`を付け、`authorization.no_match = deny`を設定します。[Use ACL File](./authz/file.md)を参照してください。
- 信頼できないまたは公開ネットワークに公開するブローカーでは、`authorization.deny_action = disconnect`（デフォルトは`ignore`）の設定を検討してください。クライアントが認可されていないトピックにパブリッシュまたはサブスクライブしようとした場合、EMQXは接続を切断します。これに[flapping detection](./flapping-detect.md)を組み合わせると、繰り返し再接続して認可拒否を引き起こすクライアントを自動的に禁止できます。`deny_action`はグローバル設定であり、拒否された操作を試みる正当なクライアントも切断されるため、クライアントが通常認可済みトピックのみを扱う場合に適用してください。再接続の嵐時に誤って禁止しないよう、flapping検出の閾値を調整してください。[Authorization](./authz/authz.md)を参照してください。
- 認可キャッシュ設定と認可者の順序をレビューし、ポリシー変更が期待通りに反映されることを確認してください。
- 不正または悪用的なクライアントの影響を軽減するため、MQTTリソース使用を制限してください。パケットサイズ、トピックレベル、サブスクリプション数、インフライトウィンドウ、キューイングされたメッセージなどの制限を見直してください。[MQTT Configuration](../configuration/mqtt.md)を参照してください。
- 必要に応じてリスナーレベルでレート制御を適用し、接続やパブリッシュのバーストを制限してください。[Rate Limiter Configuration](../configuration/limiter.md)を参照してください。
- 悪質または不安定なクライアントを制御するために、[Banned Clients](./blacklist.md)および[Flapping Detect](./flapping-detect.md)を活用してください。
- [Message Queue](../../develop/message-queue/message-queue-concept.md)または[MQTT Streams](../../develop/mqtt-stream/mqtt-stream-concept.md)が有効な場合、`$queue/`および`$stream/`ネームスペース（非推奨の`$q/`および`$s/`プレフィックスを含む）に対して別個の認可ルールを定義してください。EMQXは完全なプレフィックス付きサブスクリプショントピックフィルターを認可し、`$queue/<name>/`や`$stream/<name>/`の後の`<topic_filter>`部分を個別に認可しません。`#`や`+/#`のルールは`$`で始まるフィルターにはマッチしません。自動作成が有効な場合、この`<topic_filter>`部分を制限してください。これは新しいキューやストリームが受信・保存するパブリッシュメッセージを決定するためです。[Message Queue Security Considerations](../../develop/message-queue/message-queue-concept.md#security-considerations)および[MQTT Streams Security Considerations](../../develop/mqtt-stream/mqtt-stream-concept.md#security-considerations)を参照してください。
- クラスターリンクが有効な場合、ピア接続を受け入れるリスナーで認証を強制し、`$LINK/`制御ネームスペースを専用のクラスターリンククライアントIDに制限し、それ以外は拒否してください。[Secure Cluster Linking](../../develop/cluster-linking/security.md)を参照してください。

## フェーズ5：管理とメンテナンス

- 本番使用前にデフォルトのダッシュボードパスワードを変更し、管理アクセス権を持つユーザーを確認してください。[System](../dashboard/system.md)を参照してください。
- ダッシュボードは信頼できるネットワーク内に限定してください。管理者アクセスにはHTTPSを推奨し、可能な場合はダッシュボードリスナーをlocalhost、プライベートインターフェース、または保護された管理ネットワークにバインドしてください。[Dashboard Configuration](../configuration/dashboard.md)を参照してください。
- **Management** -> **Cluster Settings** -> **Rule Engine Security**でSSRF保護を有効にし、コネクター設定のテスト、作成、更新時にHTTPおよびMQTTコネクターのターゲットを検証してください。EMQX 6.0.4以降、このポリシーは他のコネクタータイプやランタイム接続には適用されません。委任管理者がルールエンジンリソースを作成・変更できる場合や完全なアウトバウンドネットワーク境界が必要な場合はホストレベルのイグレス制御を追加してください。[Rule Engine Security](../dashboard/cluster_settings.md#rule-engine-security)および[Mitigate SSRF with Rule Engine Policy and Firewall Rules](../cluster/security.md#mitigate-ssrf-with-rule-engine-policy-and-firewall-rules)を参照してください。
- 管理APIを公開する場合は、ダッシュボード資格情報の代わりにAPIキーを使用し、必要最小限のロールを付与し、可能な場合は有効期限を設定してください。[REST API](../api.md)および[System](../dashboard/system.md#api-key)を参照してください。
- EMQX Enterpriseを使用している場合、管理ユーザー向けに[シングルサインオン（SSO）](../dashboard/sso.md)を検討し、利用可能な場合はIDプロバイダーで多要素認証（MFA）を強制してください。
- 定期的なバックアップをスケジュールし、復元手順をリハーサルしてください。EMQXデータディレクトリ外に保存された証明書やACLファイルは別途バックアップが必要です。[Backup and Restore](../backup-restore.md)を参照してください。
- 監査ログを有効にし、異常検知やインシデント対応のためにログとメトリクスを観測スタックに集約してください。[Audit Log](../dashboard/audit-log.md)、[Logs Configuration](../configuration/logs.md)、および[Logs and Observability](../observability/overview.md)を参照してください。

## 変更後の再検証

- 証明書ローテーション、リスナー変更、ロードバランサー更新、クラスター拡張、バックアップポリシー変更、認証・認可チェーンの変更後にこのチェックリストを再実行してください。
- 匿名クライアントの拒否、無効な証明書によるTLSハンドシェイク失敗、許可されていないトピックへのパブリッシュやサブスクライブの拒否など、想定される失敗モードを本番切り替え前に検証してください。
