Skip to content

X.509証明書認証 ​

X.509は、安全なインターネット通信で広く使われている標準的な公開鍵証明書フォーマットです。EMQXはTLS/SSL接続およびX.509証明書を用いたクライアント/サーバー間の双方向認証をサポートしており、より高いレベルのセキュリティを提供します。

動作原理 ​

EMQXはクライアントがX.509証明書を用いてTLS/SSL接続を確立することを可能にし、X.509証明書認証のために証明書情報とクライアントのバインドをサポートします。利用方法およびワークフローは以下の通りです:

  1. サーバー証明書を発行し、EMQXでTLS/SSLを有効化し、双方向認証を設定します。
  2. クライアント証明書を発行し、証明書および秘密鍵ファイルをデバイスに組み込み、TLS/SSL接続に使用します。
  3. クライアントはTLSハンドシェイク時に証明書をサーバーに送信し、自身の正当性を証明します。
  4. EMQXはクライアントの証明書を受け取ると、その証明書を検証してクライアントの身元を確認します。
  5. 検証が成功すると、サーバーはTLSハンドシェイクを完了し、安全な接続を確立します。

接続成功後、EMQXは証明書情報をクライアント属性にマッピングして証明書とクライアントのバインドを実現できます。さらに、JWT認証やパスワード認証など他のアプリケーション層認証方式と組み合わせて、多要素認証を実装可能です。

特徴と利点 ​

  • セキュリティ:X.509はデジタル証明書と公開鍵暗号を用いた安全で信頼性の高い認証機構を提供し、通信の機密性、完全性、認証を保証します。不正なデバイスのネットワークアクセスや悪意ある操作を防止します。
  • 相互運用性:X.509は広くサポートされている普遍的な標準です。多くのIoTデバイスがX.509証明書をサポートしており、デバイス間の認証および安全な通信を簡単かつ信頼性高く実現します。
  • スケーラビリティ:X.509は大規模なIoT展開に対応可能です。柔軟な証明書チェーンと管理機構を備え、複雑なIoT環境に適応し、多数のデバイスやエンティティの認証をサポートします。
  • 信頼できる第三者検証:X.509証明書は、厳格なセキュリティ審査と検証を受けた信頼できる認証局(CA)によって発行されることが多いです。デバイスは信頼されたCA発行の証明書を使用して、自身の身元と証明書の正当性を保証します。
  • 強力な暗号アルゴリズムのサポート:X.509は共通の対称・非対称暗号アルゴリズムを含む幅広い暗号アルゴリズムと鍵長をサポートし、IoTデバイスが強力な暗号化アルゴリズムを用いて通信の安全性を確保できます。
  • 柔軟な証明書設定と管理:X.509は柔軟な証明書設定および管理オプションを備えています。デバイスは必要に応じて適切な証明書属性や拡張フィールドを選択し、特定のIoTアプリケーション要件を満たせます。さらに、証明書失効や更新も証明書管理機構を通じて効果的に管理可能です。

これらの特徴により、X.509はIoTセキュリティに最適な選択肢となります。EMQXはX.509証明書認証を完全にサポートし、IoTデバイスの安全なアクセスと通信を容易に実現します。

X.509証明書認証の有効化 ​

X.509証明書認証は基本的にTLS/SSLの双方向認証です。設定方法はSSL/TLSの双方向認証の有効化を参照してください。

TIP

X.509証明書認証はパスワード認証やJWT認証よりも先に実行されます。

証明書情報のマッピング ​

EMQXはX.509証明書情報をユーザー名またはクライアントIDとしてマッピングし、証明書とクライアントのバインドを実現できます。これはダッシュボードまたは設定ファイルで設定可能です。

mTLSによる証明書フィールドマッピングの必須条件

peer_cert_as_usernameまたはpeer_cert_as_clientidをdisabled以外に設定する場合、SSLリスナーは必ず相互TLS(mTLS)を強制する必要があります:

  • verify = verify_peer
  • fail_if_no_peer_cert = true
  • cacertfileは管理下のCAバンドルに設定(任意の名前で証明書を発行可能な公開CAは信頼しないこと)

mTLSがない場合、クライアントは証明書を提示せずに接続したり、任意のCN/DNを持つ自己署名証明書を提示したりできます。EMQXはこれを検証せず、CN/DNをそのままユーザー名またはクライアントIDにマッピングします。攻撃者が選んだCN/DNにより、任意のIDを偽装可能です。空のCN/DNはHTTP認証など下流の認証機構で予期しない動作を引き起こすこともあります。mTLSを強制すると、EMQXはマッピング適用前にハンドシェイクを拒否します。

注意

空のユーザー名を防ぐ追加の対策として、listeners.{type}.{name}.enable_authn = quick_deny_anonymousを設定し、導出されたユーザー名が空のクライアントを認証チェーンに入れず即座に拒否することが推奨されます。これはmTLSを補完するものであり、偽造CN/DNに対する完全な防御ではありません。

クライアントのユーザー名として、ピア証明書のCN、DN、または証明書全体の内容などのフィールドを利用可能です。現在サポートされている証明書情報の解釈は以下の通りです:

  • cn:証明書のCNフィールド
  • dn:証明書のDN情報(CN=xxx,OU=xxx,O=xxx,L=xxx,ST=xxx,C=xxx形式)
  • crt:証明書のDER形式の内容
  • pem:DER証明書をPEM形式に変換した内容
  • md5:DERまたはPEM証明書内容のMD5値

PROXYプロトコルに関する注意点 ​

TLSを上流のロードバランサーで終端し、TCPリスナーでproxy_protocol = trueを有効にした場合、同様のID偽装リスクがあります。EMQXはロードバランサーがPROXY v2フレームで注入するCN/DNを信頼するためです。安全に証明書フィールドマッピングを利用するには:

  • ロードバランサー自身がmTLSを実施し、検証済みのCN/DNのみを転送すること。
  • PROXYプロトコル対応リスナーは信頼できるロードバランサーからのみアクセス可能にすること。listeners.{type}.{name}.access_rules = ["allow <trusted-LB-CIDR>", "deny all"]を設定し、ファイアウォールやプライベートネットワーク、Unixソケットなどのネットワークレベル制御と組み合わせて多層防御を行うこと。

PROXYプロトコルポートに直接アクセス可能な攻撃者は、任意の証明書フィールドを持つPROXY v2フレームを作成し、任意のクライアントを偽装可能です。

ダッシュボードでの設定方法 ​

  1. ダッシュボードを開き、管理 -> MQTT設定ページの一般タブを選択します。
  2. MQTT設定内で以下の項目を見つけて変更します:
    • ピア証明書をユーザー名として使用:X.509証明書情報をユーザー名としてマッピングします。
    • ピア証明書をクライアントIDとして使用:X.509証明書情報をクライアントIDとしてマッピングします。
  3. 変更を保存ボタンをクリックして設定を完了します。新規接続クライアントは設定に従ってマッピングされます。

設定ファイルでの設定方法 ​

  1. インストール環境に応じて./etcまたは/etc/emqx/etcディレクトリにある設定ファイルを開きます。
  2. MQTT設定は明示的に定義されていないため、以下を追加してデフォルト値を上書きします:
hocon
mqtt {
# 証明書情報をクライアントIDとして使用
peer_cert_as_clientid = "disabled" # "disabled" | "cn" | "dn" | "crt" | "pem" | "md5"
# 証明書情報をユーザー名として使用
peer_cert_as_username = "cn" # "disabled" | "cn" | "dn" | "crt" | "pem" | "md5"
}

クライアント属性を証明書のSubject Alternative Namesから初期化 ​

EMQX Enterprise 6.3.0以降、TLS接続がEMQXで終端される際に、クライアント証明書のSubject Alternative Names(SAN)からクライアント属性を初期化できます。サポートされるSANタイプはDNS名、IPv4およびIPv6アドレス、メールアドレス、URIです。

mqtt.client_attrs_init式内でcert_san.dns、cert_san.ip、cert_san.email、cert_san.uriを使用可能です。これらは配列であるため、nth()やjoin_to_string()などのVariform関数を使ってクライアント属性値を生成します。設定方法や例は証明書のSubject Alternative Namesからクライアント属性を初期化を参照してください。

peer_cert_as_usernameおよびpeer_cert_as_clientidはSANの抽出をサポートしていません。認証、認可、またはクライアント属性をサポートする他の機能でSANを利用するには、まずSANの値をクライアント属性として保存してください。