如何使用 WildFly 连接到受 Kerberos 保护的 Apache Phoenix 数据源?

Posted

技术标签:

【中文标题】如何使用 WildFly 连接到受 Kerberos 保护的 Apache Phoenix 数据源?【英文标题】:How to connect to a Kerberos-secured Apache Phoenix data source with WildFly? 【发布时间】:2017-03-28 11:30:01 【问题描述】:

我最近花了几个星期试图让 WildFly 成功连接到 Kerberized Apache Phoenix 数据源。关于如何做到这一点的文档数量惊人地有限,但现在我已经破解了它,我正在分享。

环境:

WildFly 9+。等效的 JBoss 版本也应该可以工作(但未经测试)。 WildFly 8 不包含所需的 org.jboss.security.negotiation.KerberosLoginModule 类(但您可以破解它,请参阅 Kerberos sql server datasource in Wildfly 8.2)。我使用的是 WildFly 10.1.0.Final,并使用了独立部署。 Apache Phoenix 4.2.0.2.2.4.10。我没有测试任何其他版本。 Kerberos v5。我的 KDC 在 Windows Active Directory 上运行,但这不会产生明显的差异。 我的 Hadoop 环境是 HortonWorks 版本,由 Ambari 维护。 Ambari 确保所有配置文件和 Kerberos 实现设置都是正确的。

【问题讨论】:

【参考方案1】:

首先,您需要向 WildFly 的 standalone.xml 添加一个系统属性,以指定 Kerberos 配置文件的位置:

...
</extensions>

<system-properties>
    <property name="java.security.krb5.conf" value="/path/to/krb5.conf"/>
</system-properties>
...

我不打算在这里讨论krb5.conf 文件的格式,因为它取决于您自己的Kerberos 实现。重要的是它包含 KDC 的默认领域和网络位置。在 Linux 上,您通常可以在 /etc/krb5.conf/etc/security/krb5.conf 找到它。如果您在 Windows 上运行 WildFly,请确保在路径中使用正斜杠,例如"C:/Source/krb5.conf"

其次,将两个新的安全域添加到standalone.xml - 一个称为“客户端”,供 ZooKeeper 使用,另一个称为“主机”,供 WildFly 使用。不要问我为什么(这让我很痛苦)但是“客户端”安全域的名称​​必须与服务器上 Zookeeper 的 JAAS 客户端配置文件中定义的名称匹配.如果您使用 Ambari 进行设置,则“客户端”是默认名称。另请注意,您不能简单地将jaas.config 文件作为系统属性提供,您必须在此处定义它:

<security-domain name="Client" cache-type="default">
    <login-module code="com.sun.security.auth.module.Krb5LoginModule" flag="required">
        <module-option name="useTicketCache" value="true"/>
        <module-option name="debug" value="true"/>
    </login-module>
</security-domain>
<security-domain name="host" cache-type="default">
    <login-module code="org.jboss.security.negotiation.KerberosLoginModule" flag="required" module="org.jboss.security.negotiation">
        <module-option name="useTicketCache" value="true"/>
        <module-option name="debug" value="true"/>
        <module-option name="refreshKrb5Config" value="true"/>
        <module-option name="addGSSCredential" value="true"/>
    </login-module>
</security-domain>

模块选项会因您的实施而异。我从默认的 Java 票证缓存中获取票证,该缓存在 JRE 的 java.security 文件中定义,但如果需要,您可以在此处提供密钥表。请注意,将storeKey 设置为true 破坏了我的实现。查看 Java 文档以了解所有选项。请注意,每个安全域都使用不同的登录模块:这并非偶然——Phoenix 不知道如何使用org.jboss... 版本。

现在您需要在phoenix-&lt;version&gt;-client.jar 中为WildFly 提供org.apache.phoenix.jdbc.PhoenixDriver 类。在 WildFly 目录下创建如下目录树:

/modules/system/layers/base/org/apache/phoenix/main/

main目录下,粘贴你可以在服务器上找到的phoenix--client.jar(例如/usr/hdp/&lt;version&gt;/phoenix/client/bin)并创建一个module.xml文件:

<?xml version="1.0" ?>

<module xmlns="urn:jboss:module:1.1" name="org.apache.phoenix">

    <resources>
        <resource-root path="phoenix-<version>-client.jar">
            <filter>
                <exclude-set>
                    <path name="javax" />
                    <path name="org/xml" />
                    <path name="org/w3c/dom" />
                    <path name="org/w3c/sax" />
                    <path name="javax/xml/parsers" />
                    <path name="com/sun/org/apache/xerces/internal/jaxp" />
                    <path name="org/apache/xerces/jaxp" />
                    <path name="com/sun/jersey/core/impl/provider/xml" />
                </exclude-set>
            </filter>
        </resource-root>
        <resource-root path=".">
        </resource-root>
    </resources>

    <dependencies>
        <module name="javax.api"/>
        <module name="sun.jdk"/>
        <module name="org.apache.log4j"/>
        <module name="javax.transaction.api"/>
        <module name="org.apache.commons.logging"/>
    </dependencies>
</module>

您还需要将服务器中的hbase-site.xmlcore-site.xml 粘贴到main 目录中。这些通常位于/usr/hdp/&lt;version&gt;/hbase/conf/usr/hdp/&lt;version&gt;/hadoop/conf。如果你不添加这些,你会得到很多无用的 ZooKeeper getMaster 错误!如果您希望驱动程序登录到与 WildFly 相同的位置,那么您还应该在 main 目录中创建一个 log4j.xml 文件。您可以在网络上的其他地方找到示例。在 WildFly 部署时,&lt;resource-root path="."&gt;&lt;/resource-root&gt; 元素将这些 xml 文件添加到类路径中。

最后,在&lt;subsystem xmlns="urn:jboss:domain:datasources:2.0"&gt; 部分添加一个新的数据源和驱动程序。您可以使用 CLI 或直接编辑 standalone.xml 来执行此操作,我是后者:

<datasource jndi-name="java:jboss/datasources/PhoenixDS" pool-name="PhoenixDS" enabled="true" use-java-context="true">
    <connection-url>jdbc:phoenix:first.quorumserver.fqdn,second.quorumserver.fqdn:2181/hbase-secure</connection-url>
    <connection-property name="phoenix.connection.autoCommit">true</connection-property>
    <driver>phoenix</driver>
    <validation>
        <check-valid-connection-sql>SELECT 1 FROM SYSTEM.CATALOG LIMIT 1</check-valid-connection-sql>
    </validation>
    <security>
        <security-domain>host</security-domain>
    </security>
</datasource>
<drivers>
    <driver name="phoenix" module="org.apache.phoenix">
        <xa-datasource-class>org.apache.phoenix.jdbc.PhoenixDriver</xa-datasource-class>
    </driver>
</drivers>

first.quorumserver.fqdn,second.quorumserver.fqdn 替换为适合您环境的正确ZooKeeper 仲裁字符串非常重要。你可以在 HBase 配置目录的hbase-site.xml 中找到它:hbase.zookeeper.quorum您无需将 Kerberos 信息添加到连接 URL 字符串!

tl;dr

确保 hbase-site.xmlcore-site.xml 在您的类路径中。 确保您有一个 &lt;security-domain&gt;,其名称符合 ZooKeeper 的预期(可能是“客户端”),它使用 com.sun.security.auth.module.Krb5LoginModule。 Phoenix 连接 URL 必须包含整个 ZooKeeper 仲裁。你不能错过一台服务器!确保它与hbase-site.xml 中的值匹配。

参考资料:

Using Kerberos for Datasource Authentication Phoenix data source configuration by Mark S

【讨论】:

告诉我,如何在安全集群上手动启动查询服务器和客户端(瘦客户端和胖客户端) - ***.com/questions/46444676/…

以上是关于如何使用 WildFly 连接到受 Kerberos 保护的 Apache Phoenix 数据源?的主要内容,如果未能解决你的问题,请参考以下文章