安全内部通信

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 身份验证以验证集群节点之间所有通信的真实性。在集群所有节点的config.properties中启用 JWT 并将共享密钥设置为相同的值,使用以下配置:

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

对于共享密钥值,建议使用一个大的随机密钥,可以使用以下 Linux 命令生成:

openssl rand 512 | base64

2. 证书

设置一种与外部身份验证方法不同的证书身份验证方法。

例如,如果在客户端与协调器之间使用密码身份验证,则可以通过在与下面给出的配置相同的配置中指定此身份验证方法,在内部使用证书身份验证。在内部 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 主体是从 http.server.authentication.krb5.service-name 构建的,在将运行 Presto 的节点主机名和 Kerberos 配置中的默认域附加到它之后。

启用 SSL/TLS 后的性能

启用加密会影响性能。性能下降可能会根据环境、查询和并发性而有所不同。

对于不需要在 Presto 节点之间传输太多数据的查询(例如 SELECT count(*) FROM table),性能影响可以忽略不计。

但是,对于需要在节点之间传输大量数据的 CPU 密集型查询(例如,需要重新分区的分散连接、聚合和窗口函数),性能影响可能会相当大。减速可能从 10% 到 100%+ 不等,具体取决于网络流量和 CPU 利用率。

高级性能调优

在某些情况下,更改随机数的来源会显着提高性能。

默认情况下,TLS 加密使用 /dev/urandom 系统设备作为熵源。该设备的吞吐量有限,因此在具有高网络带宽的环境(例如 InfiniBand)中,它可能会成为瓶颈。在这种情况下,建议尝试将随机数生成器算法切换到 SHA1PRNG,通过在协调器和所有工作节点的 config.properties 中设置 http-server.https.secure-random-algorithm 属性来设置。

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

请注意,此算法从阻塞的 /dev/random 设备获取初始种子。对于没有足够熵来播种 SHAPRNG 算法的环境,可以通过将 java.security.egd 属性添加到 jvm.config 来将源更改为 /dev/urandom

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