pinpoint 添加 hbase kerberos认证

October 18, 2018

pinpoint 原生是不支持的hbasekerberos认证的,经过修改源码,现已在1.8版本之后支持了这一功能,并入到项目主分支中,以后可以直接使用。

开源地址: https://github.com/naver/pinpoint

kerberos 认证简介

Kerberos 是一种基于对称密钥的身份认证协议,它作为一个独立的第三方的身份认证服务,可以为其服务提供身份认证功能,且支持SSO(即客户端身份认证后,可以访问多个服务如HBase/HDFS等). Kerberos 协议过程主要有两个阶段,第一个阶段是KDCclient的身份认证,第二个阶段是serviceclient的身份认证.

原理图

  • KDC: Kerberos的服务端程序
  • Client: 需要访问服务的用户(principal),KDC和Service会对用户的身份进行认证
  • Service: 集成了Kerberos的服务,如HDFS/YARN/HBase等

1、KDC对Client身份认证

当客户端用户访问一个集成了Kerberos的服务之前,需要先通过KDC的身份认证.若身份认证通过则客户端会拿到一个TGT,后续就可以拿该TGT去访问集成了Kerberos的服务。

2、Service对Client身份认证

当该客户端拿到TGT之后,就可以继续访问Service服务。它回使用TGT以及需要访问的服务名称去KDC获取SGT,然后使用SGT去访问服务ServiceService会利用相关信息对Client进行身份认证,认证通过后就可以正常访问Service服务。

Hbase kerberos 认证

1、修改源码

pinpoint中的hbase相关代码都是在commons-hbase这个项目中,连接都是通过PooledHTableFactory.java 这个类创建的,因此修改代码的地方就是这个类,并且只需要添加上hbase认证代码即可.

     public PooledHTableFactory(Configuration config, ExecutorService executor) {
         Objects.requireNonNull(config, "config must not be null");
         this.executor = Objects.requireNonNull(executor, "executor must not be null");
         try {
             String authEnable = config.get("hbase.kerberos.auth");
             if (!StringUtils.isEmpty(authEnable) && Boolean.parseBoolean(authEnable)){
                 if (StringUtils.isEmpty(config.get("hbase.kerberos.keytab.path"))){
                     throw new KerberosException(ErrorType.KDC_ERR_NONE);
                 }
                 System.out.println("hbase.zookeeper.quorum:"+config.get("hbase.zookeeper.quorum"));
                 System.out.println("hbase.kerberos.keytab.path:"+config.get("hbase.kerberos.keytab.path"));
                 System.out.println("hbase.kerberos.user:"+config.get("hbase.kerberos.user"));
 
                 config.set("hbase.security.authentication", "kerberos");
                 config.set("hadoop.security.authentication", "kerberos");
                 config.set("hbase.master.kerberos.principal",config.get("hbase.master.kerberos.principal"));
                 config.set("hbase.regionserver.kerberos.principal",config.get("hbase.regionserver.kerberos.principal"));
                 UserGroupInformation.setConfiguration(config);
                 String kerberosUser = config.get("hbase.kerberos.user");
                 String kerberosPath = config.get("hbase.kerberos.keytab.path");
                 UserGroupInformation.loginUserFromKeytab(kerberosUser, kerberosPath);
             }
             this.connection = ConnectionFactory.createConnection(config, executor);
         } catch (Exception e) {
             throw new HbaseSystemException(e);
         }
     }

只添加了if里面的所以代码,值都通过配置文件传入,设置了开关,可以启用或者禁用认证功能。

2、添加配置

添加hbase.properties的配置

# kerberos
# 是否启用或者禁用
hbase.kerberos.auth=true
# kerberos 用户
hbase.kerberos.user=test_add@HADOOP.COM
# keytab 认证文件路径
hbase.kerberos.keytab.path=./test_add.keytab
# 默认配置
hbase.master.kerberos.principal=hbase/_HOST@HADOOP.COM
hbase.regionserver.kerberos.principal=hbase/_HOST@HADOOP.COM

添加 applicationContext-hbase.xml的配置.

<bean id="hbaseConfiguration" class="com.navercorp.pinpoint.common.hbase.HbaseConfigurationFactoryBean">
        <property name="properties">
            <props>
                <prop key="hbase.zookeeper.quorum">${hbase.client.host}</prop>
                <prop key="hbase.zookeeper.property.clientPort">${hbase.client.port}</prop>

               <!--Root ZNode for HBase in ZooKeeper.-->
                <prop key="zookeeper.znode.parent">${hbase.zookeeper.znode.parent:/hbase}</prop>
                 <!-- hbase default:true -->
                <prop key="hbase.ipc.client.tcpnodelay">${hbase.ipc.client.tcpnodelay}</prop>
                <!-- hbase default:60000 -->
                <prop key="hbase.rpc.timeout">${hbase.rpc.timeout}</prop>
                <!-- hbase default:Integer.MAX_VALUE -->
                <prop key="hbase.client.operation.timeout">${hbase.client.operation.timeout}</prop>

                <!-- hbase socket read timeout. default: 200000-->
                <prop key="hbase.ipc.client.socket.timeout.read">${hbase.ipc.client.socket.timeout.read}</prop>
                <!-- socket write timeout. hbase default: 600000-->
                 <prop key="hbase.ipc.client.socket.timeout.write">${hbase.ipc.client.socket.timeout.write}</prop>
 
                 <!-- hbase async put operation. -->
                 <prop key="hbase.client.async.enable">${hbase.client.async.enable:false}</prop>
                 <prop key="hbase.client.async.in.queuesize">${hbase.client.async.in.queuesize:10000}</prop>
                 <prop key="hbase.tablemultiplexer.flush.period.ms">${hbase.client.async.flush.period.ms:100}</prop>
                 <prop key="hbase.client.max.retries.in.queue">${hbase.client.async.max.retries.in.queue:10}</prop>
                <!--hbase kerberos-->
                <prop key="hbase.kerberos.auth">${hbase.kerberos.auth:false}</prop>
                <prop key="hbase.kerberos.user">${hbase.kerberos.user:test}</prop>
                <prop key="hbase.kerberos.keytab.path">${hbase.kerberos.keytab.path:/tmp}</prop>
                <prop key="hbase.master.kerberos.principal">${hbase.master.kerberos.principal:test}</prop>
                <prop key="hbase.regionserver.kerberos.principal">${hbase.regionserver.kerberos.principal:test}</prop>
            </props>
        </property>
    </bean>

3、添加启动参数配置到tomcat

$ vim bin/catalina.sh
# 添加krb配置文件
CATALINA_OPTS="$CATALINA_OPTS -Djava.security.krb5.conf=./krb5.conf"
# 开启krb认证的bug日志
CATALINA_OPTS="$CATALINA_OPTS -Dsun.security.krb5.debug=true"
CATALINA_OPTS="$CATALINA_OPTS -Djavax.security.auth.useSubjectCredsOnly=true"

** 上面步骤都完成之后即可进行重启使用。**


LRF 记录学习、生活的点滴