セキュリティチェックリスト
このチェックリストは、EMQXのデプロイメントを本番トラフィックに公開する前に確認するためのものです。セキュリティ層ごとに整理されており、オペレーティングシステムからダッシュボードまでの全経路を検証できます。初期展開時、大規模なトポロジー変更後、および定期的なセキュリティレビューの一環としてご利用ください。
フェーズ1:インフラストラクチャおよびOS
- ノードが通常または攻撃的な接続負荷下で失敗しないように、オペレーティングシステムのファイルディスクリプタ制限およびサービスレベルの
LimitNOFILE設定を接続規模に合わせて引き上げます。 - SYNフラッド保護、接続追跡容量、信頼できるインターフェースのみでのリスナー公開など、長時間維持されるMQTTトラフィックに対してTCPスタックとファイアウォールの設定を強化します。
- クライアントが実際に必要とするリスナーのみを公開します。信頼できないネットワークでは、
8883や8084のような暗号化リスナーを優先し、1883のような平文リスナーは内部または移行用ケースに制限してください。Listener Configuration および Enable SSL/TLS Connection を参照してください。 - クラスター内で使用されるポートマッピングについては、Cluster Security を参照し、ノード間のポートはセキュリティグループやファイアウォールルールで制限します。
- ノードに複数のインターフェースがある場合は、Erlang分散トラフィックをプライベートネットワークインターフェースのみにバインドします。
- ロードバランサーやTCPプロキシの背後にEMQXをデプロイする場合、実際のクライアントIPアドレスやクライアント証明書の詳細が必要なリスナーのみでProxy Protocolを有効にします。
- リスナーでProxy Protocolを有効にした場合、そのアドレスとポートは指定されたプロキシまたはロードバランサーのみに公開します。EMQXでは
listeners.{type}.{name}.access_rules = ["allow <trusted-LB-CIDR>", "deny all"]とネットワークレベルの制御(ファイアウォール、プライベートネットワーク、Unixソケット)を組み合わせてこれを強制してください。そうしないと、直接ポートに到達したクライアントが任意のピア証明書フィールドを持つPROXY v2フレームを作成し、任意のIDを偽装できます。 - WebSocketリスナー(
wsまたはwss)がx-forwarded-forヘッダーを書き換える信頼できるプロキシの背後にない場合、listeners.{type}.{name}.websocket.proxy_address_header = ""(およびwebsocket.proxy_port_header = "")を設定し、IPベースの認可ルール、禁止クライアント、フラッピング検出、監査ログが実際のTCPピアアドレスを使用するようにします。ヘッダーが有効な場合、導出される送信元IPはクライアント提供であり、信頼できるプロキシがヘッダーを書き換えない限り保護されません。プロキシが受信ヘッダーに追記するだけでは保護されません。Forwarded Client Address を参照してください。
フェーズ2:Erlangおよびクラスター
- クラスター内のすべてのノードでデフォルトのノードクッキーを置き換え、すべてのメンバーで同じ高エントロピーのシークレットを使用します。Set Node Cookie を参照してください。
emqx.conf、ACLファイル、証明書、秘密鍵、その他の機密情報は厳格なファイル権限と安全なシークレット管理プロセスで保護します。- シークレット型フィールドは可能な限りインライン値ではなく
file://参照として保存します。SSLキーのパスフレーズ、ブリッジやコネクターのパスワード、APIキーなどシークレットとして文書化されているフィールドは、値をfile:///path/to/secretに設定し、EMQXが起動時およびリロード時にファイルから読み込むようにします。これにより、平文のシークレットが設定ファイル、APIリクエストボディ、設定バックアップ、バージョン管理から除外され、設定共有やエクスポート時の漏洩リスクが低減します。Load Secrets from a File を参照してください。 - クラスター間通信のポートは内部に限定し、トラフィックが信頼度の低いネットワークやパブリッククラウド境界を越える場合はTLSを有効にします。Cluster Security を参照してください。
- ノード追加、ネットワーク移動、デプロイメントトポロジー変更後は、ファイアウォールルール、証明書、クラスター参加制御を再確認してください。
フェーズ3:トランスポートセキュリティ
- トラフィックが信頼できないネットワークを越える場合は、本番MQTTリスナーにTLSを使用してください。Network and TLS を参照してください。
- 組織のセキュリティ基準に従い、レガシープロトコルバージョンや弱い暗号スイートを無効化し、展開前にステージング環境で最終リスナー設定を検証します。
- 信頼されたCAまたは内部PKIによって発行された証明書を使用し、有効期限前にローテーションしてください。
- デバイスIDをクライアント証明書で検証する必要がある場合は、相互TLSを有効にします。このモデルでは、TLSハンドシェイク時にクライアント証明書チェーンと証明書の存在を検証します。X.509 Certificate Authentication を参照してください。
- ピア証明書フィールドを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 を参照してください。 - 証明書失効が重要な環境では、CRLチェック または OCSPスタップリング の導入を検討してください。
- HTTP認証者、データベース、その他の統合先など外部リソースへのアウトバウンド接続にはTLSを有効にしてください。
フェーズ4:MQTTアクセス制御およびリソース保護
パブリックリスナーを公開する前に、少なくとも1つの認証機構を設定してください。認証が有効でない場合、EMQXはすべてのクライアントの接続を許可します。Authentication を参照してください。
共有のユーザー名、パスワード、証明書よりも、デバイス単位またはアプリケーション単位の認証情報を推奨します。
認証機構が許す場合は、MQTTクライアントIDを認証済みIDにバインドしてください。例えば、JWTの
clientidクレームを検証したり、証明書フィールドをpeer_cert_as_clientidでマッピングしたり、HTTP認証者で不一致を拒否したり、認証者を Client-Info ルールと組み合わせたりします。これを行わない場合:- 認証情報が漏洩すると、攻撃者は長いSession Expiry Intervalを持つ無制限のセッションをランダムなクライアントIDで作成でき、アイドル状態の永続セッションが蓄積してブローカーのメモリを枯渇させる恐れがあります。
- 有効な認証情報を持つ攻撃者が被害者のクライアント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 を参照してください。
ACLトピックテンプレート内で
${clientid}、${username}、${client_attrs.X}を使用する場合(Authorization Placeholders参照)、これらのID値にMQTTトピックのワイルドカード(+、#)やトピック区切り文字(/)が含まれないよう検証してください。検証されていないIDがclients/${clientid}/dataのようなテンプレートに代入されると、クライアントIDが+の場合はすべての他クライアントのサブトピックへのアクセスを許可するワイルドカードパターンに展開され、tenantA/+や/を含む場合は割り当てられたサブツリーから逸脱します。上流で厳密なID形式を強制し、Client-Info ルール、JWTクレームパターン、HTTP認証者での拒否などを利用してください。ACLに依存して不正な置換を検出するのではなく、接続を拒否してください。HTTP認証、HTTP認可、データ統合コネクター、ブリッジ、アクションなど外部サービスへのアウトバウンドリクエスト設計時は、EMQXが機密として認識するフィールドまたはヘッダーにシークレットを格納してください。これにより、関連ログ、トレース、設定APIレスポンスで値が
******とマスクされます。マスクはフィールド名やヘッダー名で制御されます。HTTPヘッダーに認証情報を置く場合は標準のAuthorization(またはProxy-Authorization)ヘッダーを使用してください。その他の設定フィールドではpassword、token、secret、secret_key、jwtのような認識済みの機密キー名を使用してください。x-custom-secretのような非標準カスタムヘッダーや慣例外のフィールド名は認識されず、debugレベルログやエラーメッセージに平文で表示される可能性があります。本番環境で認可に依存する前に、許容的なデフォルトルールは削除または調整してください。
ファイルベースのACLでは、適切にデフォルト拒否の姿勢を採用し、ルールを
{deny, all}で終わらせたり、authorization.no_match = denyを設定したりしてください。Use ACL File を参照してください。信頼できないネットワークやパブリックネットワークに公開するブローカーでは、
authorization.deny_action = disconnect(デフォルトはignore)の設定を検討してください。クライアントが許可されていないトピックへのパブリッシュやサブスクライブを試みた場合、EMQXは接続を切断します。これにフラッピング検出を組み合わせると、繰り返し再接続して認可拒否を引き起こすクライアントを自動的に禁止できます。deny_actionはグローバル設定であり、拒否された操作を試みる正当なクライアントも切断されるため、通常は許可されたトピックのみでパブリッシュ・サブスクライブするクライアントに適用してください。再接続の嵐時に誤って禁止されないようフラッピング検出の閾値を調整してください。Authorization を参照してください。認可キャッシュ設定と認可者の順序を見直し、ポリシー変更が期待通りに反映されるようにしてください。
不正または悪意のあるクライアントの影響を軽減するため、MQTTリソース使用制限を設定してください。パケットサイズ、トピックレベル数、サブスクリプション数、インフライトウィンドウ、キューイングメッセージ数などを確認してください。MQTT Configuration を参照してください。
必要に応じてリスナーレベルでレート制御を適用し、接続やパブリッシュのバーストを制限してください。Rate Limiter Configuration を参照してください。
不正または不安定なクライアントを制御するために、Banned Clients と Flapping Detect を活用してください。
Cluster Linkingを有効にしている場合は、ピア接続を受け入れるリスナーで認証を強制し、
$LINK/コントロールネームスペースを専用のCluster LinkingクライアントIDに制限し、その他は拒否してください。Secure Cluster Linking を参照してください。
フェーズ5:管理およびメンテナンス
- 本番利用前にデフォルトのダッシュボードパスワードを変更し、管理者アクセス権を確認してください。System を参照してください。
- ダッシュボードは信頼できるネットワーク内に限定し、管理者アクセスにはHTTPSを推奨します。可能な場合はダッシュボードリスナーをlocalhost、プライベートインターフェース、または保護された管理ネットワークにバインドしてください。Dashboard Configuration を参照してください。
- Management -> Cluster Settings -> Rule Engine Security でSSRF保護を有効にし、コネクター設定のテスト、作成、更新時にHTTPおよびMQTTコネクターのターゲットを検証します。EMQX 6.0.4以降、このポリシーは他のコネクタータイプやランタイム接続をカバーしません。委任管理者がルールエンジンリソースを作成・変更できる場合や完全なアウトバウンドネットワーク境界が必要な場合は、ホストレベルのイグレス制御を追加してください。Rule Engine Security および Mitigate SSRF with Rule Engine Policy and Firewall Rules を参照してください。
- 管理APIを公開する場合は、ダッシュボード認証情報ではなくAPIキーを使用し、必要最小限のロールを付与し、可能な限り有効期限を設定してください。REST API および System を参照してください。
- EMQX Enterpriseを使用している場合は、管理ユーザー向けにシングルサインオン(SSO)を検討し、利用可能な場合はIDプロバイダーで多要素認証(MFA)を強制してください。
- 定期的なバックアップをスケジュールし、リストア手順をリハーサルしてください。証明書やACLファイルがEMQXデータディレクトリ外に保存されている場合は別途バックアップが必要です。Backup and Restore を参照してください。
- 監査ログを有効にし、異常検知やインシデント対応のためにログやメトリクスをオブザーバビリティスタックに集約してください。Audit Log、Logs Configuration、Logs and Observability を参照してください。
変更後の再検証
- 証明書ローテーション、リスナー変更、ロードバランサー更新、クラスター拡張、バックアップポリシー変更、認証・認可チェーンの変更後にこのチェックリストを再実行してください。
- 匿名クライアントの拒否、無効証明書によるTLSハンドシェイク失敗、許可外トピックへのパブリッシュ・サブスクライブ拒否など、想定される失敗モードを本番切り替え前に検証してください。