如何使用 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 数据源?的主要内容,如果未能解决你的问题,请参考以下文章

如何配置 Wildfly 连接到 RabbitMQ?

如何在 Windows server 2012 上连接到端口 8080 wildfly?

如何将 WildFly 连接到远程 Artemis 服务器

无法从 WildFly 连接到 HBase

无法从 Wildfly 连接到 SQL Server 数据库

无法连接到 Dockerfile 中的 Wildfly