较新版本的 Apache HBase(> = 0.92)将支持连接到支持 SASL 身份验证的 ZooKeeper Quorum(可在 ZooKeeper 版本 3.4.0 或更高版本中使用)。
介绍如何设置 HBase 与 ZooKeeper Quorum 进行相互认证。 ZooKeeper / HBase 相互认证( HBASE-2418 )是完整安全 HBase 配置( HBASE-3025 )的一部分。为简化说明,本节忽略了所需的其他配置(安全 HDFS 和协处理器配置)。建议首先使用 HBase 管理的 ZooKeeper 配置(而不是独立的 ZooKeeper 仲裁),以便于学习。
您需要有一个有效的 Kerberos KDC 设置。对于将运行 ZooKeeper 服务器的每个$HOST
,您应该具有zookeeper/$HOST
原则。对于每个这样的主机,为zookeeper/$HOST
添加一个服务密钥(使用kadmin
或kadmin.local
工具的ktadd
命令)并将此文件复制到$HOST
,并使其仅对将运行 zookeeper 的用户可读在$HOST
上。请注意此文件的位置,我们将在下面使用它作为 _ $ PATH_TO_ZOOKEEPER KEYTAB 。
同样,对于将运行 HBase 服务器(主服务器或区域服务器)的每个$HOST
,您应该有一个原则:hbase/$HOST
。对于每个主机,添加一个名为 hbase.keytab 的密钥表文件,其中包含hbase/$HOST
的服务密钥,将此文件复制到$HOST
,并使其仅对将运行 HBase 服务的用户可读$HOST
。注意这个文件的位置,我们将在下面使用它作为 _ $ PATH_TO_HBASE KEYTAB 。
每个将成为 HBase 客户端的用户也应获得 Kerberos 主体。此主体通常应该为其分配密码(与 HBase 服务器相反,密钥表文件),只有该用户知道。应设置客户端的主体maxrenewlife
,以便可以对其进行足够的续订,以便用户可以完成其 HBase 客户端进程。例如,如果用户运行长达 3 天的长期运行 HBase 客户端进程,我们可以在kadmin
中创建此用户的主体:addprinc -maxrenewlife 3days
。 ZooKeeper 客户端和服务器库通过运行定期唤醒以执行刷新的线程来管理自己的票证更新。
在将运行 HBase 客户端的每台主机上(例如hbase shell
),将以下文件添加到 HBase 主目录的 conf 目录中:
Client {
com.sun.security.auth.module.Krb5LoginModule required
useKeyTab=false
useTicketCache=true;
};
我们将此 JAAS 配置文件称为 _ $ CLIENT CONF 。
在将运行 zookeeper,master 或 regionserver 的每个节点上,在节点的 _HBASE HOME 目录的 conf 目录中创建一个 JAAS 配置文件,如下所示:
Server {
com.sun.security.auth.module.Krb5LoginModule required
useKeyTab=true
keyTab="$PATH_TO_ZOOKEEPER_KEYTAB"
storeKey=true
useTicketCache=false
principal="zookeeper/$HOST";
};
Client {
com.sun.security.auth.module.Krb5LoginModule required
useKeyTab=true
useTicketCache=false
keyTab="$PATH_TO_HBASE_KEYTAB"
principal="hbase/$HOST";
};
其中 _ $ PATH_TO_HBASE KEYTAB 和 _ $ PATH_TO_ZOOKEEPER KEYTAB 文件是您在上面创建的文件,$HOST
是该节点的主机名。
Server
部分将由 ZooKeeper 仲裁服务器使用,而Client
部分将由 HBase 主服务器和区域服务器使用。此文件的路径应替换下面 hbase-env.sh 列表中的文本 _ $ HBASE_SERVER CONF 。
此文件的路径应替换下面 hbase-env.sh 列表中的文本 _ $ CLIENT CONF 。
修改 hbase-env.sh 以包含以下内容:
export HBASE_OPTS="-Djava.security.auth.login.config=$CLIENT_CONF"
export HBASE_MANAGES_ZK=true
export HBASE_ZOOKEEPER_OPTS="-Djava.security.auth.login.config=$HBASE_SERVER_CONF"
export HBASE_MASTER_OPTS="-Djava.security.auth.login.config=$HBASE_SERVER_CONF"
export HBASE_REGIONSERVER_OPTS="-Djava.security.auth.login.config=$HBASE_SERVER_CONF"
其中 _ $ HBASE_SERVER CONF 和 _ $ CLIENT CONF 是上面创建的 JAAS 配置文件的完整路径。
在将运行 zookeeper,master 或 regionserver 的每个节点上修改 hbase-site.xml 以包含:
<configuration>
<property>
<name>hbase.zookeeper.quorum</name>
<value>$ZK_NODES</value>
</property>
<property>
<name>hbase.cluster.distributed</name>
<value>true</value>
</property>
<property>
<name>hbase.zookeeper.property.authProvider.1</name>
<value>org.apache.zookeeper.server.auth.SASLAuthenticationProvider</value>
</property>
<property>
<name>hbase.zookeeper.property.kerberos.removeHostFromPrincipal</name>
<value>true</value>
</property>
<property>
<name>hbase.zookeeper.property.kerberos.removeRealmFromPrincipal</name>
<value>true</value>
</property>
</configuration>
其中$ZK_NODES
是 ZooKeeper Quorum 主机的逗号分隔的主机名列表。
通过在适当的主机上运行以下一组或多组命令来启动 hbase 群集:
bin/hbase zookeeper start
bin/hbase master start
bin/hbase regionserver start
添加一个类似于的 JAAS 配置文件:
Client {
com.sun.security.auth.module.Krb5LoginModule required
useKeyTab=true
useTicketCache=false
keyTab="$PATH_TO_HBASE_KEYTAB"
principal="hbase/$HOST";
};
其中 _ $ PATH_TO_HBASE KEYTAB 是上面创建的 HBase 服务在此主机上运行的密钥表,$HOST
是该节点的主机名。把它放在 HBase home 的配置目录中。我们将此文件的完整路径名称称为 _ $ HBASE_SERVER CONF 。
修改您的 hbase-env.sh 以包含以下内容:
export HBASE_OPTS="-Djava.security.auth.login.config=$CLIENT_CONF"
export HBASE_MANAGES_ZK=false
export HBASE_MASTER_OPTS="-Djava.security.auth.login.config=$HBASE_SERVER_CONF"
export HBASE_REGIONSERVER_OPTS="-Djava.security.auth.login.config=$HBASE_SERVER_CONF"
在将运行 master 或 regionserver 的每个节点上修改 hbase-site.xml 以包含:
<configuration>
<property>
<name>hbase.zookeeper.quorum</name>
<value>$ZK_NODES</value>
</property>
<property>
<name>hbase.cluster.distributed</name>
<value>true</value>
</property>
<property>
<name>hbase.zookeeper.property.authProvider.1</name>
<value>org.apache.zookeeper.server.auth.SASLAuthenticationProvider</value>
</property>
<property>
<name>hbase.zookeeper.property.kerberos.removeHostFromPrincipal</name>
<value>true</value>
</property>
<property>
<name>hbase.zookeeper.property.kerberos.removeRealmFromPrincipal</name>
<value>true</value>
</property>
</configuration>
where $ZK_NODES
is the comma-separated list of hostnames of the ZooKeeper Quorum hosts.
同样在每个主机上,创建一个 JAAS 配置文件,其中包含:
Server {
com.sun.security.auth.module.Krb5LoginModule required
useKeyTab=true
keyTab="$PATH_TO_ZOOKEEPER_KEYTAB"
storeKey=true
useTicketCache=false
principal="zookeeper/$HOST";
};
其中$HOST
是每个 Quorum 主机的主机名。我们将此文件的完整路径名称为 _ $ ZK_SERVER CONF 。
使用以下命令在每个 ZooKeeper Quorum 主机上启动 ZooKeepers:
SERVER_JVMFLAGS="-Djava.security.auth.login.config=$ZK_SERVER_CONF" bin/zkServer start
通过在相应节点上运行以下一组或多组命令来启动 HBase 集群:
bin/hbase master start
bin/hbase regionserver start
如果上面的配置成功,您应该在 ZooKeeper 服务器日志中看到类似于以下内容的内容:
11/12/05 22:43:39 INFO zookeeper.Login: successfully logged in.
11/12/05 22:43:39 INFO server.NIOServerCnxnFactory: binding to port 0.0.0.0/0.0.0.0:2181
11/12/05 22:43:39 INFO zookeeper.Login: TGT refresh thread started.
11/12/05 22:43:39 INFO zookeeper.Login: TGT valid starting at: Mon Dec 05 22:43:39 UTC 2011
11/12/05 22:43:39 INFO zookeeper.Login: TGT expires: Tue Dec 06 22:43:39 UTC 2011
11/12/05 22:43:39 INFO zookeeper.Login: TGT refresh sleeping until: Tue Dec 06 18:36:42 UTC 2011
..
11/12/05 22:43:59 INFO auth.SaslServerCallbackHandler:
Successfully authenticated client: authenticationID=hbase/ip-10-166-175-249.us-west-1.compute.internal@HADOOP.LOCALDOMAIN;
authorizationID=hbase/ip-10-166-175-249.us-west-1.compute.internal@HADOOP.LOCALDOMAIN.
11/12/05 22:43:59 INFO auth.SaslServerCallbackHandler: Setting authorizedID: hbase
11/12/05 22:43:59 INFO server.ZooKeeperServer: adding SASL authorization for authorizationID: hbase
在 ZooKeeper 客户端(HBase 主服务器或区域服务器)上,您应该看到类似于以下内容的内容:
11/12/05 22:43:59 INFO zookeeper.ZooKeeper: Initiating client connection, connectString=ip-10-166-175-249.us-west-1.compute.internal:2181 sessionTimeout=180000 watcher=master:60000
11/12/05 22:43:59 INFO zookeeper.ClientCnxn: Opening socket connection to server /10.166.175.249:2181
11/12/05 22:43:59 INFO zookeeper.RecoverableZooKeeper: The identifier of this process is 14851@ip-10-166-175-249
11/12/05 22:43:59 INFO zookeeper.Login: successfully logged in.
11/12/05 22:43:59 INFO client.ZooKeeperSaslClient: Client will use GSSAPI as SASL mechanism.
11/12/05 22:43:59 INFO zookeeper.Login: TGT refresh thread started.
11/12/05 22:43:59 INFO zookeeper.ClientCnxn: Socket connection established to ip-10-166-175-249.us-west-1.compute.internal/10.166.175.249:2181, initiating session
11/12/05 22:43:59 INFO zookeeper.Login: TGT valid starting at: Mon Dec 05 22:43:59 UTC 2011
11/12/05 22:43:59 INFO zookeeper.Login: TGT expires: Tue Dec 06 22:43:59 UTC 2011
11/12/05 22:43:59 INFO zookeeper.Login: TGT refresh sleeping until: Tue Dec 06 18:30:37 UTC 2011
11/12/05 22:43:59 INFO zookeeper.ClientCnxn: Session establishment complete on server ip-10-166-175-249.us-west-1.compute.internal/10.166.175.249:2181, sessionid = 0x134106594320000, negotiated timeout = 180000
这已经在当前的标准 Amazon Linux AMI 上进行了测试。首先如上所述设置 KDC 和主体。下一个结帐代码并运行完整性检查。
git clone https://gitbox.apache.org/repos/asf/hbase.git
cd hbase
mvn clean test -Dtest=TestZooKeeperACL
然后如上所述配置 HBase。手动编辑 target / cached_classpath.txt(见下文):
bin/hbase zookeeper &
bin/hbase master &
bin/hbase regionserver &
您必须使用包含 HADOOP-7070 修复程序的版本覆盖target/cached_classpath.txt
文件中的标准 hadoop-core jar 文件。您可以使用以下脚本执行此操作:
echo `find ~/.m2 -name "*hadoop-core*7070*SNAPSHOT.jar"` ':' `cat target/cached_classpath.txt` | sed 's/ //g' > target/tmp.txt
mv target/tmp.txt target/cached_classpath.txt
这将避免需要一个单独的 Hadoop jar 来修复 HADOOP-7070 。
kerberos.removeHostFromPrincipal
和kerberos.removeRealmFromPrincipal