Skip to content

SSL/TLS接続の有効化

EMQXは、MQTTクライアントのアクセスを受け入れる際にSSL/TLSを介して安全な接続を確立できます。SSL/TLS暗号化機能はトランスポート層でネットワーク接続を暗号化し、通信データのセキュリティを強化しつつ、その完全性を保証します。

本ページでは、SSL/TLS接続の機能と利点、およびクライアントとEMQX間でSSL/TLS接続を確立する方法について紹介します。

セキュリティ上の利点

SSL/TLS接続を有効にすると、以下のセキュリティ上の利点があります:

  1. 強力な認証:通信の両当事者は、相手が保持するX.509デジタル証明書を検証してお互いの身元を確認します。これらの証明書は通常、信頼された認証局(CA)によって発行されており、偽造が困難です。
  2. 機密性:各セッションは両当事者が交渉したセッションキーで暗号化されます。第三者が通信内容を知ることはできず、たとえセッションキーが漏洩しても他のセッションの安全性には影響しません。
  3. 完全性:暗号化通信におけるデータ改ざんの可能性は極めて低いです。

2つの利用モード

MQTT接続を含むすべての接続に対してSSL/TLS暗号化接続を有効にし、アクセスとメッセージ送信のセキュリティを確保できます。クライアントのSSL/TLS接続については、利用シナリオに応じて以下の2つのモードから選択可能です:

利用モード利点欠点
クライアントとEMQX間で直接SSL/TLS接続を確立する。簡単に使用でき、追加のコンポーネントは不要。EMQXのリソース消費が増加し、接続数が多い場合はCPUやメモリの消費が高くなる可能性がある。
プロキシまたはロードバランサーでTLS接続を終了させる。EMQXのパフォーマンスに影響を与えず、ロードバランシング機能を提供。TCP SSL/TLS終了をサポートするクラウドベンダーのロードバランサーは限られている。加えて、ユーザー自身でHAProxyなどのソフトウェアをデプロイする必要がある。

プロキシまたはロードバランサーでTLS接続を終了させる方法については、クラスターのロードバランシングを参照してください。

一方向/双方向認証

EMQXは包括的なSSL/TLS機能をサポートしており、X.509証明書を用いたクライアント/サーバー間の一方向認証および双方向相互認証を実現できます:

認証方式説明検証方法長所と短所
一方向認証クライアントがサーバーの身元を検証するが、サーバーはクライアントの身元を検証しない。クライアントは通常証明書を提供する必要がなく、サーバー証明書が信頼された認証局(CA)によって発行されていることを検証するだけ。通信データの機密性と完全性は保証できるが、通信当事者の身元保証はできない。
双方向認証サーバーとクライアントが互いに身元を検証し合う。各デバイスに証明書を発行し、サーバーはクライアント証明書を検証して正当性を確認する。サーバーとクライアント間の相互信頼を確保し、中間者攻撃を防止できる。

SSL/TLS証明書

SSL/TLS接続を確立する前に、認証用のSSL/TLS証明書を準備する必要があります。EMQXはテスト目的でのみ使用可能なSSL/TLS証明書セット(インストールパッケージのetc/certsディレクトリにあります)を提供しています。本番環境で使用する場合は、信頼されたCAによって署名された信頼性の高い証明書を使用してください。証明書の取得方法については、SSL/TLS証明書の取得を参照してください。

一方向認証でのSSL/TLS有効化

EMQXはデフォルトでポート8883にSSL/TLSリスナーを有効にし、一方向認証を設定しています。証明書の差し替えやその他の設定変更は、ダッシュボードや設定ファイルから行えます。

ダッシュボードでの有効化

  1. EMQXダッシュボードにアクセスし、左側のナビゲーションメニューから Management -> Listeners をクリックします。

  2. Listenersページで、SSLリスナーのName列にあるdefaultをクリックします。

    • TLS Verify:一方向認証のためデフォルトで無効です。

    • Session Tickets:TLS 1.3のセッション再開を有効にします。クライアントはサーバーが発行した暗号化されたセッションチケットを提示することで、再接続時に以前確立したTLSセッションを再利用でき、完全なTLSハンドシェイクを回避し、レイテンシとCPU使用率を削減します。

      • disabled:セッションチケットを無効化(デフォルト)。接続ごとに完全なTLSハンドシェイクを実行します。
      • stateless:ステートレスセッションチケットを有効化。サーバーはセッション状態を保持せず、再接続性能が向上します。セッション再開後はTLSクライアント証明書情報が利用できないため、証明書ベースの認証や認可が不要な場合に適しています。
      • stateless_with_cert:証明書情報を含むステートレスセッションチケットを有効化。セッション再開後も証明書情報が利用可能で、mTLSなど証明書ベースの認証に適していますが、ネットワーク帯域の使用量が若干増加します。

      注意

      セッションチケットを生成するには、ノードレベルのオプションnode.tls_stateless_tickets_seedに空でない文字列(例:node.tls_stateless_tickets_seed = "averysecuresecret")を設定する必要があります。リスナーでセッションチケットを有効にしてもこのオプションが設定されていない場合、セッションチケットは生成されません。

      セッションチケットはTLS 1.3でのみサポートされ、クラスター環境でのスケーラビリティを確保するためステートレスモードのみ対応しています。EMQXはTLS 1.2のステートフルセッション再開をサポートしていません。

      また、EMQXはクライアントの早期データ送信(0-RTT)をサポートしていません。クライアントはTLSハンドシェイク完了までMQTTデータを送信できません。

    • TLS CertTLS Key、およびCA CertResetボタンをクリックして、現在の証明書ファイルをプライベート証明書ファイルに差し替えます。

    • SSL Versions:すべてのTLS/DTLSバージョンをサポートします。デフォルトはtlsv1.3tlsv1.2です。PSK認証にPSK暗号スイートを使用する場合は、ここにtlsv1.2tlsv1.1tlsv1を設定してください。PSK認証の詳細はPSK認証の有効化を参照してください。

    • Fail If No Peer CertTLS Verifyが有効な場合に使用します。デフォルトはfalseです。

      • trueに設定すると、クライアントが空の証明書を送信した場合に検証が失敗し、SSL/TLS接続が拒否されます。
      • falseに設定すると、クライアントが無効な証明書を送信した場合のみ検証が失敗し、空の証明書は有効とみなされます。つまり一方向認証の場合です。
    • Intermediate Certificate Depth:証明書パスの最大深度。デフォルトは10です。

    • Key Password:秘密鍵ファイルにパスワードが設定されている場合は入力します。

    • Enable OCSP Stapling:デフォルトで無効。SSL/TLS証明書の失効状況を取得する必要がある場合はトグルスイッチで有効化します。詳細はOCSP Staplingを参照してください。

    • Enable CRL Check:デフォルトで無効。接続クライアント証明書の失効確認が必要な場合はトグルスイッチで有効化します。詳細はCRL Checkを参照してください。

  3. 編集が完了したら、Updateボタンをクリックします。

設定ファイルでの有効化

設定ファイルのlisteners.ssl.default設定グループを変更してSSL/TLS接続を有効にすることもできます。

  1. プライベートSSL/TLS証明書ファイルをEMQXのetc/certsディレクトリに配置します。

  2. 設定ファイルbase.hocon(インストール方法により./etcまたは/etc/emqx/etcディレクトリにあります)を開きます。

  3. listeners.ssl.default設定グループを編集し、証明書ファイルを自身の証明書ファイルに置き換えます。

    一方向認証を有効にする場合は、verify = verify_noneを追加してください:

bash
listeners.ssl.default {
  bind = "0.0.0.0:8883"
  ssl_options {
    # クライアント証明書の真正性を検証するためにリスナーが使用する信頼されたCA(認証局)証明書を含むPEMファイル。
    # 一方向認証の場合、このファイルの内容は空でもよい。
    cacertfile = "etc/certs/rootCAs.pem"
    # リスナー用のSSL/TLS証明書チェーンを含むPEMファイル。
    # 証明書がルートCAから直接発行されていない場合は、中間CA証明書をリスナー証明書の後ろに連結してチェーンを形成する。
    certfile = "etc/certs/server-cert.pem"
    # SSL/TLS証明書に対応する秘密鍵を含むPEMファイル。
    keyfile = "etc/certs/server-key.pem"
    # クライアント証明書の真正性を検証するための設定。双方向認証(mTLS)では必ず 'verify_peer' に設定する必要がある。
    # 任意のクライアントの接続を許可する場合は 'verify_none' に設定する。
    verify = verify_none
    # クライアントが証明書を送信しない場合にハンドシェイクを失敗させるかどうか。双方向認証(mTLS)では必ずtrueに設定する必要がある。
    # falseの場合は、クライアントが無効な証明書を送信した場合のみ失敗する(一方向認証の場合)。
    fail_if_no_peer_cert = true
  }
}

EMQX v4の設定

EMQXでは、mqtt:sslのデフォルトリスニングポートは8883です。

OpenSSLツールで生成したemqx.pememqx.keyca.pemファイルをEMQXのetc/certs/ディレクトリにコピーし、以下の設定を参考にbase.hoconを修正します:

shell
## listener.ssl.$name はMQTT/SSLのIPアドレスとポートです
## 値: IP:Port | Port
listener.ssl.external = 8883

# SSL/TLS証明書に対応する秘密鍵を含むPEMファイル
listener.ssl.external.keyfile = etc/certs/emqx.key

# (省略)

        fail_if_no_peer_cert = false
      }
    }
  1. 設定を反映するためにEMQXを再起動します。

一方向認証でのクライアント接続テスト

MQTTX CLIを使ってテスト可能です。一方向認証では通常、クライアントはCA証明書を提供し、サーバーの身元を検証します:

bash
mqttx sub -t 't/1' -h localhost -p 8883 \
  --protocol mqtts \
  --ca certs/rootCA.crt

サーバー証明書のCommon Name(CN)がクライアントが接続時に指定したサーバーアドレスと一致しない場合、以下のエラーが発生します:

bash
Error [ERR_TLS_CERT_ALTNAME_INVALID]: Hostname/IP does not match certificate's altnames: Host: localhost. is not cert's CN: Server

この場合、クライアント証明書のCNをサーバーアドレスに合わせるか、--insecureオプションで証明書CN検証を無視できます:

bash
mqttx sub -t 't/1' -h localhost -p 8883 \
  --protocol mqtts \
  --ca certs/rootCA.crt \
  --insecure

双方向認証でのSSL/TLS有効化

双方向認証は一方向認証の拡張であり、EMQXがクライアント証明書も検証してクライアントの正当性を保証するように設定します。

これに加えて、クライアント用の証明書を発行する必要があります。具体的な操作はクライアント証明書の発行を参照してください。

ダッシュボードでの方法では、TLS VerifyEnableにし、Fail if No Peer Certオプションをtrueに設定して双方向認証を強制できます。

設定ファイルのlisteners.ssl.default設定グループに以下を追加しても構いません:

bash
listeners.ssl.default {
  ...
  ssl_options {
    ...
    # ピア検証を有効化
    verify = verify_peer
    # 双方向認証を強制。クライアントが証明書を提供できない場合、SSL/TLS接続は拒否される。
    fail_if_no_peer_cert = true
  }
}

双方向認証でのクライアント接続テスト

MQTTX CLIを使ってテスト可能です。双方向認証ではCA証明書に加え、クライアント自身の証明書も提供する必要があります:

bash
mqttx sub -t 't/1' -h localhost -p 8883 \
  --protocol mqtts \
  --ca certs/rootCA.crt \
  --cert certs/client-0001.crt \
  --key certs/client-0001.key

サーバー証明書のCNがクライアントが接続時に指定したサーバーアドレスと一致しない場合、以下のエラーが発生します:

bash
Error [ERR_TLS_CERT_ALTNAME_INVALID]: Hostname/IP does not match certificate's altnames: Host: localhost. is not cert's CN: Server

この場合、クライアント証明書のCNをサーバーアドレスに合わせるか、--insecureオプションで証明書CN検証を無視できます:

bash
mqttx sub -t 't/1' -h localhost -p 8883 \
  --protocol mqtts \
  --ca certs/rootCA.crt \
  --cert certs/client-0001.crt \
  --key certs/client-0001.key \
  --insecure

SSL/TLS証明書の更新

プライベートSSL/TLS証明書ファイルの有効期限が切れた場合は、./etcまたは/etc/emqx/etcディレクトリ内の古い証明書を新しいものに差し替えて手動で更新する必要があります。

EMQXは再起動なしでSSL/TLS証明書のローテーションをサポートしています。デフォルトでEMQXは120秒ごとにSSL/TLS証明書をリロードします。