セキュアな内部通信

Presto クラスタは、セキュアな通信を使用するように構成できます。Presto ノード間の通信は、SSL/TLS で保護できます。

内部 SSL/TLS 構成

SSL/TLS は config.properties ファイルで構成されます。ワーカーノードとコーディネーターノードの SSL/TLS は、同じプロパティセットを使用して構成されます。クラスタ内のすべてのノードを構成する必要があります。構成されていないノード、または正しく構成されていないノードは、クラスタ内の他のノードと通信できません。

Presto の内部通信で SSL/TLS を有効にするには、次の手順を実行します。

  1. HTTP エンドポイントを無効にします。

    http-server.http.enabled=false
    

    警告

    HTTP を有効にしたまま HTTPS を有効にすることができます。ほとんどの場合、これはセキュリティホールです。この構成を使用することを確信している場合は、ファイアウォールを使用して HTTP エンドポイントへのアクセスを、それを利用することを許可する必要があるホストのみに制限することを検討する必要があります。

  2. クラスタがクラスタノードの完全修飾ドメイン名 (FQDN) を使用して通信するように構成します。これは、次のいずれかの方法で実行できます。

    • DNS サービスが正しく構成されている場合、ノードがシステム構成から取得したホスト名(hostname --fqdn)を使用して自身をコーディネーターに紹介できるようにします。

      node.internal-address-source=FQDN
      
    • 各ノードの完全修飾ホスト名を手動で指定することもできます。これはホストごとに異なります。正しい SSL/TLS 証明書を作成しやすくするために、ホストは同じドメイン内にある必要があります。例: coordinator.example.comworker1.example.comworker2.example.com

      node.internal-address=<node fqdn>
      
  3. Java キーストアファイルを作成します。すべての Presto ノードは、同じクラスタ内の他のノードに接続できる必要があります。各ホストの完全修飾ホスト名を使用して各ノードに固有の証明書を作成し、すべてのホストの公開キーを含むキーストアを作成し、クライアントに指定することができます(下記手順 8 を参照)。ほとんどの場合、以下に示すように証明書にワイルドカードを使用する方が簡単です。

    keytool -genkeypair -alias example.com -keyalg RSA -keystore keystore.jks
    Enter keystore password:
    Re-enter new password:
    What is your first and last name?
      [Unknown]:  *.example.com
    What is the name of your organizational unit?
      [Unknown]:
    What is the name of your organization?
      [Unknown]:
    What is the name of your City or Locality?
      [Unknown]:
    What is the name of your State or Province?
      [Unknown]:
    What is the two-letter country code for this unit?
      [Unknown]:
    Is CN=*.example.com, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown correct?
      [no]:  yes
    
    Enter key password for <presto>
            (RETURN if same as keystore password):
    
  4. Presto クラスタ全体に Java キーストアファイルを配布します。

  5. HTTPS エンドポイントを有効にします。

    http-server.https.enabled=true
    http-server.https.port=<https port>
    http-server.https.keystore.path=<keystore path>
    http-server.https.keystore.key=<keystore password>
    
  6. 検出 URI を HTTPS に変更します。

    discovery.uri=https://<coordinator fqdn>:<https port>
    
  7. 内部通信で HTTPS を要求するように構成します。

    internal-communication.https.required=true
    
  8. 内部通信で Java キーストアファイルを使用するように構成します。

    internal-communication.https.keystore.path=<keystore path>
    internal-communication.https.keystore.key=<keystore password>
    

内部認証

クラスタのノード間のすべての内部通信を認証するために、内部認証を有効にすることができます。これは

  • クラスタのノード間で内部 TLS 暗号化のみを構成する場合、オプションです。

  • クライアントとコーディネーター間で外部認証方法のみを構成する場合、オプションです。

  • 上記の両方、つまり内部 TLS と外部認証の両方を構成する場合、必須です。

以下のセクションで説明されている、内部認証を有効にする方法は複数あります。

1. JWT

クラスタのノード間のすべての通信を認証するために、JWT 認証を有効にします。JWT を有効にし、共有シークレットを config.properties のクラスタのすべてのノードで同じ値に設定します。以下の設定を使用します。

internal-communication.jwt.enabled=true
internal-communication.shared-secret=<secret>

共有シークレットの値としては、大きなランダムキーをお勧めします。これは、次の Linux コマンドを使用して生成できます。

openssl rand 512 | base64

2. 証明書

外部認証方法とは異なる証明書認証方法をセットアップします。

たとえば、クライアントとコーディネーター間で PASSWORD 認証が使用されている場合、以下に示すのと同じ構成でこの認証方法を指定することにより、内部で CERTIFICATE 認証を使用できます。 内部 ssl/tls 構成で設定された既存のキーストア構成が、証明書認証に使用されます。

http-server.authentication.type=PASSWORD,CERTIFICATE

3. KERBEROS

Kerberos 認証が有効になっている場合、SSL/TLS プロパティに加えて、内部通信に有効な Kerberos 資格情報を指定します。

internal-communication.kerberos.enabled=true

注記

内部 Kerberos 認証に使用されるサービス名とキータブファイルは、Kerberosで説明されているサーバー Kerberos 認証プロパティ、http.server.authentication.krb5.service-namehttp.server.authentication.krb5.keytab からそれぞれ取得されます。ワーカーノードにも Kerberos の設定が完了していることを確認してください。内部通信の Kerberos プリンシパルは、Presto が実行されているノードのホスト名と Kerberos 構成からのデフォルトのレルムを追加した後、http.server.authentication.krb5.service-name から構築されます。

SSL/TLS を有効にした場合のパフォーマンス

暗号化を有効にすると、パフォーマンスに影響します。パフォーマンスの低下は、環境、クエリ、および同時実行性によって異なります。

Presto ノード間で大量のデータを転送する必要のないクエリ(例:SELECT count(*) FROM table)の場合、パフォーマンスへの影響は無視できます。

ただし、ノード間で相当量のデータを転送する必要がある CPU 集中型のクエリ(たとえば、再パーティショニングを必要とする分散結合、集計、ウィンドウ関数など)の場合、パフォーマンスへの影響は無視できません。ネットワークトラフィックと CPU 使用率によっては、速度低下は 10% から 100% 以上にもなります。

高度なパフォーマンスチューニング

場合によっては、乱数のソースを変更することで、パフォーマンスが大幅に向上することがあります。

デフォルトでは、TLS 暗号化はエントロピーのソースとして /dev/urandom システムデバイスを使用します。このデバイスのスループットは限られているため、ネットワーク帯域幅の高い環境(例:InfiniBand)では、ボトルネックになる可能性があります。このような状況では、config.properties のコーディネーターとすべてのワーカーで http-server.https.secure-random-algorithm プロパティを介して設定することにより、乱数生成アルゴリズムを SHA1PRNG に切り替えることをお勧めします。

http-server.https.secure-random-algorithm=SHA1PRNG

このアルゴリズムは、ブロッキング /dev/random デバイスから初期シードを取得することに注意してください。SHAPRNG アルゴリズムをシードするのに十分なエントロピーがない環境では、java.security.egd プロパティを jvm.config に追加することにより、ソースを /dev/urandom に変更できます。

-Djava.security.egd=file:/dev/urandom