HUE/beeline/python + kerberos+Hadoop實現User Impersonation

最近接到了一個需求

要在使用了kerberos做驗證的Hadoop上,使用HUE等服務

以往我這邊的用法都是直接每個user申請自己的keytab然後用kinit去通過認證

但是如果使用了HUE服務就要得使用共享的keytab才行,但是又必須達成個人帳號的區分

單純的Hadoop的話直接新增一個hue user然後將其設定成proxy user就行了
http://gethue.com/how-to-configure-hue-in-your-hadoop-cluster/

但現在加上了kerberos,這要怎麼達成讓我煩惱了一陣子

我有兩個目標

  • 讓不同user使用他們自己的LDAP account使用一個共享的keytab去存取kerberos認證的hadoop
  • 儘管使用共享的keytab仍可以區分各個user

後來研究了一下,把做法紀錄在這邊

首先必須做成一個3-parts的keytab

當個人用戶申請自己的kerberos keytab的時候申請的是2-parts的keytab
其principal格式如下

USERNAME@REALM_DOMAIN

而像hue這種proxy user則需要申請3-parts的keytab來綁定某個host
其principal格式如下

USERNAME/HOST@REALM_DOMAIN

kerberos keytab怎麼製作,這邊就跳過了

首先就是想辦法把hue的3-parts keytab hue.keytab弄到手

這邊直接展示hue.ini (HUE 4.1)的設定

...
  [[kerberos]]

    # Path to Hue's Kerberos keytab file
    ## hue_keytab=
    hue_keytab=/etc/hue.keytab
    # Kerberos principal name for Hue
    ## hue_principal=hue/hostname.foo.com
    hue_principal=hue/my_hue_server.com@my_realm_server.com
    # Frequency in seconds with which Hue will renew its keytab
    ## keytab_reinit_frequency=3600
    # Path to keep Kerberos credentials cached
    ## ccache_path=/var/run/hue/hue_krb5_ccache
    # Path to kinit
    ## kinit_path=/path/to/kinit
    kinit_path=/bin/kinit

    # Mutual authentication from the server, attaches HTTP GSSAPI/Kerberos Authentication to the given Request object
    ## mutual_authentication="OPTIONAL" or "REQUIRED" or "DISABLED"
    mutual_authentication=DISABLED
...

只要keytab有了,HUE的kerberos設定對了,其他hadoop設定上去就能讓HUE使用kerberos認證的hadoop
同時每個user仍能keep他們的帳戶在hadoop上

接下來是我想藉著beeline/python存取Hive
如何有同樣的效果
關鍵是hive.server2.proxy.user這個設定,他代表了被proxy的user,也就是在hadoop看到的名字
https://www.cloudera.com/documentation/enterprise/5-8-x/topics/cdh_sg_hiveserver2_security.html

不管是用beeline還是python
首先先用hue user的keytab初始化

$ kinit -kt /etc/hue.keytab hue/my_hue_server.com@my_realm_server.com

在沒有設定hive.server2.proxy.user的時候,因為是用了hue user的keytab初始化

在hadoop上的身份就會是hue

再來就是想辦法把hive.server2.proxy.user設定上去

  • beeline
$ $HIVE_HOME/bin/beeline -u "jdbc:hive2://$HIVESERVER2_HOST:HIVESERVER2_PORT/;principal=hive/$HIVESERVER2_HOST@my_realm_server.com;hive.server2.proxy.user=terrence" -n "" -p ""

這邊要注意的是使用beeline連接hiveserver2的時候,principal要設定成hive user的

  • python

python則可以用impyla這個套件,pyhs2有點舊了這次先不測
先安裝impyla所需套件

$ pip install impyla 
$ pip install thrift_sasl==0.2.1 #https://github.com/cloudera/impyla/issues/268
$ yum install cyrus-sasl-*

然後用如下方法初始化測試

from impala.dbapi import connect
with connect(host='HIVESERVER2_HOST',port=HIVESERVER2_PORT, auth_mechanism='GSSAPI', kerberos_service_name='hive', database='default') as conn:
    #從cursor的configuration設定hive.server2.proxy.user

    with conn.cursor(configuration={'hive.server2.proxy.user':'terrence'}) as cursor:
        cursor.execute(" select count(1) from my_test_table where dt='2018-01-01'")
        print(cursor.fetchall())

上面的方法,儘管我使用的hue的keytab,但是在hadoop上執行的user仍是我的名字terrence

這樣一來就這次的目標就算達到了

comments powered by Disqus