1. 程式人生 > >Impala和Hive整合Sentry、Kerberos認證

Impala和Hive整合Sentry、Kerberos認證

關於 Kerberos 的安裝和 HDFS 配置 kerberos 認證,請參考 HDFS配置kerberos認證

關於 Kerberos 的安裝和 YARN 配置 kerberos 認證,請參考 YARN配置kerberos認證

關於 Kerberos 的安裝和 Hive 配置 kerberos 認證,請參考 Hive配置kerberos認證

請先完成 HDFS 、YARN、Hive 配置 Kerberos 認證,再來配置 Impala 整合 Kerberos 認證 !

參考 使用yum安裝CDH Hadoop叢集 安裝 hadoop 叢集,叢集包括三個節點,每個節點的ip、主機名和部署的元件分配如下:

192.168.56.121        cdh1     NameNode、Hive、ResourceManager、HBase、impala-state-store、impala-catalog、Kerberos Server
192.168.56.122        cdh2     DataNode、SSNameNode、NodeManager、HBase、impala-server
192.168.56.123        cdh3     DataNode、HBase、NodeManager、impala-server

注意:hostname 請使用小寫,要不然在整合 kerberos 時會出現一些錯誤。

1. 安裝必須的依賴

在每個節點上執行下面的命令:

 
  1. $ yum install python-devel openssl-devel python-pip cyrus-sasl cyrus-sasl-gssapi cyrus-sasl-devel -y

  2. $ pip-python install ssl

2. 生成 keytab

在 cdh1 節點,即 KDC server 節點上執行下面命令:

 
  1. $ cd /var/kerberos/krb5kdc/

  2.  
  3. kadmin.local -q "addprinc -randkey impala/[email protected] "

  4. kadmin.local -q "addprinc -randkey impala/[email protected] "

  5. kadmin.local -q "addprinc -randkey impala/[email protected] "

  6.  
  7. kadmin.local -q "xst -k impala-unmerge.keytab impala/[email protected] "

  8. kadmin.local -q "xst -k impala-unmerge.keytab impala/[email protected] "

  9. kadmin.local -q "xst -k impala-unmerge.keytab impala/[email protected] "

另外,如果你使用了haproxy來做負載均衡,參考官方文件Using Impala through a Proxy for High Availability,還需生成 proxy.keytab:

 
  1. $ cd /var/kerberos/krb5kdc/

  2.  
  3. # proxy 為安裝了 haproxy 的機器

  4. kadmin.local -q "addprinc -randkey impala/[email protected] "

  5.  
  6. kadmin.local -q "xst -k proxy.keytab impala/[email protected] "

合併 proxy.keytab 和 impala-unmerge.keytab 生成 impala.keytab:

 
  1. $ ktutil

  2. ktutil: rkt proxy.keytab

  3. ktutil: rkt impala-unmerge.keytab

  4. ktutil: wkt impala.keytab

  5. ktutil: quit

拷貝 impala.keytab 和 proxy_impala.keytab 檔案到其他節點的 /etc/impala/conf 目錄

 
  1. $ scp impala.keytab cdh1:/etc/impala/conf

  2. $ scp impala.keytab cdh2:/etc/impala/conf

  3. $ scp impala.keytab cdh3:/etc/impala/conf

並設定許可權,分別在 cdh1、cdh2、cdh3 上執行:

 
  1. $ ssh cdh1 "cd /etc/impala/conf/;chown impala:hadoop *.keytab ;chmod 400 *.keytab"

  2. $ ssh cdh2 "cd /etc/impala/conf/;chown impala:hadoop *.keytab ;chmod 400 *.keytab"

  3. $ ssh cdh3 "cd /etc/impala/conf/;chown impala:hadoop *.keytab ;chmod 400 *.keytab"

由於 keytab 相當於有了永久憑證,不需要提供密碼(如果修改 kdc 中的 principal 的密碼,則該 keytab 就會失效),所以其他使用者如果對該檔案有讀許可權,就可以冒充 keytab 中指定的使用者身份訪問 hadoop,所以 keytab 檔案需要確保只對 owner 有讀許可權(0400)

3. 修改 impala 配置檔案

修改 cdh1 節點上的 /etc/default/impala,在 IMPALA_CATALOG_ARGS 、IMPALA_SERVER_ARGS 和 IMPALA_STATE_STORE_ARGS 中新增下面引數:

 
  1. -kerberos_reinit_interval=60

  2. -principal=impala/[email protected]

  3. -keytab_file=/etc/impala/conf/impala.keytab

如果使用了 HAProxy(關於 HAProxy 的配置請參考 Hive使用HAProxy配置HA),則 IMPALA_SERVER_ARGS 引數需要修改為(proxy為 HAProxy 機器的名稱,這裡我是將 HAProxy 安裝在 cdh1 節點上):

 
  1. -kerberos_reinit_interval=60

  2. -be_principal=impala/[email protected]

  3. -principal=impala/[email protected]

  4. -keytab_file=/etc/impala/conf/impala.keytab

在 IMPALA_CATALOG_ARGS 中新增:

-state_store_host=${IMPALA_STATE_STORE_HOST} \

將修改的上面檔案同步到其他節點。最後,/etc/default/impala 檔案如下,這裡,為了避免 hostname 存在大寫的情況,使用 hostname 變數替換 _HOST

 
  1. IMPALA_CATALOG_SERVICE_HOST=cdh1

  2. IMPALA_STATE_STORE_HOST=cdh1

  3. IMPALA_STATE_STORE_PORT=24000

  4. IMPALA_BACKEND_PORT=22000

  5. IMPALA_LOG_DIR=/var/log/impala

  6.  
  7. IMPALA_MEM_DEF=$(free -m |awk 'NR==2{print $2-5120}')

  8. hostname=`hostname -f |tr "[:upper:]" "[:lower:]"`

  9.  
  10. IMPALA_CATALOG_ARGS=" -log_dir=${IMPALA_LOG_DIR} -state_store_host=${IMPALA_STATE_STORE_HOST} \

  11. -kerberos_reinit_interval=60\

  12. -principal=impala/${hostname}@JAVACHEN.COM \

  13. -keytab_file=/etc/impala/conf/impala.keytab

  14. "

  15.  
  16. IMPALA_STATE_STORE_ARGS=" -log_dir=${IMPALA_LOG_DIR} -state_store_port=${IMPALA_STATE_STORE_PORT}\

  17. -statestore_subscriber_timeout_seconds=15 \

  18. -kerberos_reinit_interval=60 \

  19. -principal=impala/${hostname}@JAVACHEN.COM \

  20. -keytab_file=/etc/impala/conf/impala.keytab

  21. "

  22. IMPALA_SERVER_ARGS=" \

  23. -log_dir=${IMPALA_LOG_DIR} \

  24. -catalog_service_host=${IMPALA_CATALOG_SERVICE_HOST} \

  25. -state_store_port=${IMPALA_STATE_STORE_PORT} \

  26. -use_statestore \

  27. -state_store_host=${IMPALA_STATE_STORE_HOST} \

  28. -be_port=${IMPALA_BACKEND_PORT} \

  29. -kerberos_reinit_interval=60 \

  30. -be_principal=impala/${hostname}@JAVACHEN.COM \

  31. -principal=impala/[email protected] \

  32. -keytab_file=/etc/impala/conf/impala.keytab \

  33. -mem_limit=${IMPALA_MEM_DEF}m

  34. "

  35.  
  36. ENABLE_CORE_DUMPS=false

將修改的上面檔案同步到其他節點:cdh2、cdh3:

 
  1. $ scp /etc/default/impala cdh2:/etc/default/impala

  2. $ scp /etc/default/impala cdh3:/etc/default/impala

更新 impala 配置檔案下的檔案並同步到其他節點:

 
  1. cp /etc/hadoop/conf/core-site.xml /etc/impala/conf/

  2. cp /etc/hadoop/conf/hdfs-site.xml /etc/impala/conf/

  3. cp /etc/hive/conf/hive-site.xml /etc/impala/conf/

  4.  
  5. scp -r /etc/impala/conf cdh2:/etc/impala

  6. scp -r /etc/impala/conf cdh3:/etc/impala

4. 啟動服務

啟動 impala-state-store

impala-state-store 是通過 impala 使用者啟動的,故在 cdh1 上先獲取 impala 使用者的 ticket 再啟動服務:

 
  1. $ kinit -k -t /etc/impala/conf/impala.keytab impala/[email protected]

  2. $ service impala-state-store start

然後檢視日誌,確認是否啟動成功。

$ tailf /var/log/impala/statestored.INFO

啟動 impala-catalog

impala-catalog 是通過 impala 使用者啟動的,故在 cdh1 上先獲取 impala 使用者的 ticket 再啟動服務:

 
  1. $ kinit -k -t /etc/impala/conf/impala.keytab impala/[email protected]

  2. $ service impala-catalog start

然後檢視日誌,確認是否啟動成功。

$ tailf /var/log/impala/catalogd.INFO

啟動 impala-server

impala-server 是通過 impala 使用者啟動的,故在 cdh1 上先獲取 impala 使用者的 ticket 再啟動服務:

 
  1. $ kinit -k -t /etc/impala/conf/impala.keytab impala/[email protected]

  2. $ service impala-server start

然後檢視日誌,確認是否啟動成功。

$ tailf /var/log/impala/impalad.INFO

5. 測試

測試 impala-shell

在啟用了 kerberos 之後,執行 impala-shell 時,需要新增 -k 引數:

 
  1. $ impala-shell -k

  2. Starting Impala Shell using Kerberos authentication

  3. Using service name 'impala'

  4. Connected to cdh1:21000

  5. Server version: impalad version 1.3.1-cdh4 RELEASE (build 907481bf45b248a7bb3bb077d54831a71f484e5f)

  6. Welcome to the Impala shell. Press TAB twice to see a list of available commands.

  7.  
  8. Copyright (c) 2012 Cloudera, Inc. All rights reserved.

  9.  
  10. (Shell build version: Impala Shell v1.3.1-cdh4 (907481b) built on Wed Apr 30 14:23:48 PDT 2014)

  11. [cdh1:21000] >

  12. [cdh1:21000] > show tables;

  13. Query: show tables

  14. +------+

  15. | name |

  16. +------+

  17. | a |

  18. | b |

  19. | c |

  20. | d |

  21. +------+

  22. Returned 4 row(s) in 0.08s

6. 排除

如果出現下面異常:

[cdh1:21000] > select * from test limit 10;
Query: select * from test limit 10
ERROR: AnalysisException: Failed to load metadata for table: default.test
CAUSED BY: TableLoadingException: Failed to load metadata for table: test
CAUSED BY: TTransportException: java.net.SocketTimeoutException: Read timed out
CAUSED BY: SocketTimeoutException: Read timed out

則需要在 hive-site.xml 中新增下面引數:

 
  1. <property>

  2. <name>hive.metastore.client.socket.timeout</name>

  3. <value>3600</value>

  4. </property>

本文主要記錄 CDH 5.2 Hadoop 叢集中配置 Impala 和 Hive 整合 Sentry 的過程,包括 Sentry 的安裝、配置以及和 Impala、Hive 整合後的測試。

使用 Sentry 來管理叢集的許可權,需要先在叢集上配置好 Kerberos。

關於 Hadoop 叢集上配置 kerberos 以及 ldap 的過程請參考本部落格以下文章:

Sentry 會安裝在三個節點的 hadoop 叢集上,每個節點的ip、主機名和部署的元件分配如下:

192.168.56.121        cdh1     NameNode、Hive、ResourceManager、HBase、impala-state-store、impala-catalog、Kerberos Server、sentry-store
192.168.56.122        cdh2     DataNode、SSNameNode、NodeManager、HBase、impala-server
192.168.56.123        cdh3     DataNode、HBase、NodeManager、impala-server

Sentry 的使用有兩種方式,一是基於檔案的儲存方式(SimpleFileProviderBackend),一是基於資料庫的儲存方式(SimpleDbProviderBackend),如果使用基於檔案的儲存則只需要安裝sentry,否則還需要安裝 sentry-store

1. 基於資料庫的儲存方式

1.1 安裝服務

在 cdh1 節點上安裝 sentry-store 服務:

yum install sentry sentry-store -y

修改 Sentry 的配置檔案 /etc/sentry/conf/sentry-store-site.xml,下面的配置參考了 Sentry原始碼中的配置例子

 
  1. <?xml version="1.0" encoding="UTF-8"?>

  2. <configuration>

  3. <property>

  4. <name>sentry.service.admin.group</name>

  5. <value>impala,hive,hue</value>

  6. </property>

  7. <property>

  8. <name>sentry.service.allow.connect</name>

  9. <value>impala,hive,hue</value>

  10. </property>

  11. <property>

  12. <name>sentry.verify.schema.version</name>

  13. <value>true</value>

  14. </property>

  15. <property>

  16. <name>sentry.service.server.rpc-address</name>

  17. <value>cdh1</value>

  18. </property>

  19. <property>

  20. <name>sentry.service.server.rpc-port</name>

  21. <value>8038</value>

  22. </property>

  23. <property>

  24. <name>sentry.store.jdbc.url</name>

  25. <value>jdbc:postgresql://cdh1/sentry</value>

  26. </property>

  27. <property>

  28. <name>sentry.store.jdbc.driver</name>

  29. <value>org.postgresql.Driver</value>

  30. </property>

  31. <property>

  32. <name>sentry.store.jdbc.user</name>

  33. <value>sentry</value>

  34. </property>

  35. <property>

  36. <name>sentry.store.jdbc.password</name>

  37. <value>redhat</value>

  38. </property>

  39. <property>

  40. <name>sentry.hive.server</name>

  41. <value>server1</value>

  42. </property>

  43. <property>

  44. <name>sentry.store.group.mapping</name>

  45. <value>org.apache.sentry.provider.common.HadoopGroupMappingService</value>

  46. </property>

  47. </configuration>

建立資料庫,請參考 Hadoop自動化安裝shell指令碼

 
  1. yum install postgresql-server postgresql-jdbc -y

  2.  
  3. ln -s /usr/share/java/postgresql-jdbc.jar /usr/lib/hive/lib/postgresql-jdbc.jar

  4. ln -s /usr/share/java/postgresql-jdbc.jar /usr/lib/sentry/lib/postgresql-jdbc.jar

  5.  
  6. su -c "cd ; /usr/bin/pg_ctl start -w -m fast -D /var/lib/pgsql/data" postgres

  7. su -c "cd ; /usr/bin/psql --command \"create user sentry with password 'redhat'; \" " postgres

  8. su -c "cd ; /usr/bin/psql --command \"CREATE DATABASE sentry owner=sentry;\" " postgres

  9. su -c "cd ; /usr/bin/psql --command \"GRANT ALL privileges ON DATABASE sentry TO sentry;\" " postgres

  10. su -c "cd ; /usr/bin/psql -U sentry -d sentry -f /usr/lib/sentry/scripts/sentrystore/upgrade/sentry-postgres-1.4.0-cdh5.sql" postgres

  11. su -c "cd ; /usr/bin/pg_ctl restart -w -m fast -D /var/lib/pgsql/data" postgres

/var/lib/pgsql/data/pg_hba.conf 內容如下:

# TYPE  DATABASE    USER        CIDR-ADDRESS          METHOD

# "local" is for Unix domain socket connections only
local   all         all                               md5
# IPv4 local connections:
#host    all         all         0.0.0.0/0             trust
host    all         all         127.0.0.1/32          md5

# IPv6 local connections:
#host    all         all         ::1/128               nd5

如果叢集開啟了 Kerberos 驗證,則需要在該節點上生成 Sentry 服務的 principal 並匯出為 ticket:

 
  1. $ cd /etc/sentry/conf

  2.  
  3. kadmin.local -q "addprinc -randkey sentry/[email protected] "

  4. kadmin.local -q "xst -k sentry.keytab sentry/[email protected] "

  5.  
  6. chown sentry:hadoop sentry.keytab ; chmod 400 *.keytab

然後,在/etc/sentry/conf/sentry-store-site.xml 中新增如下內容:

 
  1. <property>

  2. <name>sentry.service.security.mode</name>

  3. <value>kerberos</value>

  4. </property>

  5. <property>

  6. <name>sentry.service.server.principal</name>

  7. <value>sentry/[email protected]</value>

  8. </property>

  9. <property>

  10. <name>sentry.service.server.keytab</name>

  11. <value>/etc/sentry/conf/sentry.keytab</value>

  12. </property>

1.2. 準備測試資料

參考 Securing Impala for analysts,準備測試資料:

 
  1. $ cat /tmp/events.csv

  2. 10.1.2.3,US,android,createNote

  3. 10.200.88.99,FR,windows,updateNote

  4. 10.1.2.3,US,android,updateNote

  5. 10.200.88.77,FR,ios,createNote

  6. 10.1.4.5,US,windows,updateTag

  7.  
  8. $ hive -S

  9. hive> create database sensitive;

  10. hive> create table sensitive.events (

  11. ip STRING, country STRING, client STRING, action STRING

  12. ) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';

  13.  
  14. hive> load data local inpath '/tmp/events.csv' overwrite into table sensitive.events;

  15. hive> create database filtered;

  16. hive> create view filtered.events as select country, client, action from sensitive.events;

  17. hive> create view filtered.events_usonly as

  18. select * from filtered.events where country = 'US';

1.3 Hive-server2 整合 sentry

要求

在使用 Sentry 時,有如下要求:

1、需要修改 /user/hive/warehouse 許可權:

 
  1. hdfs dfs -chmod -R 770 /user/hive/warehouse

  2. hdfs dfs -chown -R hive:hive /user/hive/warehouse

2、修改 hive-site.xml 檔案,關掉 HiveServer2 impersonation

3、taskcontroller.cfg 檔案中確保 min.user.id=0

修改配置檔案

修改 hive-site.xml,新增如下:

 
  1. <property>

  2. <name>hive.security.authorization.task.factory</name>

  3. <value>org.apache.sentry.binding.hive.SentryHiveAuthorizationTaskFactoryImpl</value>

  4. </property>

  5. <property>

  6. <name>hive.server2.session.hook</name>

  7. <value>org.apache.sentry.binding.hive.HiveAuthzBindingSessionHook</value>

  8. </property>

  9. <property>

  10. <name>hive.sentry.conf.url</name>

  11. <value>file:///etc/hive/conf/sentry-site.xml</value>

  12. </property>

在 /etc/hive/conf/ 目錄建立 sentry-site.xml:

 
  1. <?xml version="1.0" encoding="UTF-8"?>

  2. <configuration>

  3. <property>

  4. <name>sentry.service.client.server.rpc-port</name>

  5. <value>8038</value>

  6. </property>

  7. <property>

  8. <name>sentry.service.client.server.rpc-address</name>

  9. <value>cdh1</value>

  10. </property>

  11. <property>

  12. <name>sentry.service.client.server.rpc-connection-timeout</name>

  13. <value>200000</value>

  14. </property>

  15. <property>

  16. <name>sentry.service.security.mode</name>

  17. <value>kerberos</value>

  18. </property>

  19. <property>

  20. <name>sentry.service.server.principal</name>

  21. <value>sentry/[email protected]</value>

  22. </property>

  23. <property>

  24. <name>sentry.service.server.keytab</name>

  25. <value>/etc/sentry/conf/sentry.keytab</value>

  26. </property>

  27. <property>

  28. <name>sentry.hive.provider</name>

  29. <value>org.apache.sentry.provider.file.HadoopGroupResourceAuthorizationProvider</value>

  30. </property>

  31. <property>

  32. <name>sentry.hive.provider.backend</name>

  33. <value>org.apache.sentry.provider.db.SimpleDBProviderBackend</value>

  34. </property>

  35. <property>

  36. <name>sentry.hive.server</name>

  37. <value>server1</value>

  38. </property>

  39. <property>

  40. <name>sentry.metastore.service.users</name>

  41. <value>hive</value>

  42. </property>

  43. <property>

  44. <name>sentry.hive.testing.mode</name>

  45. <value>false</value>

  46. </property>

  47. </configuration>

sentry-store 中建立角色和組

在 beeline 中通過 hive(注意,在 sentry 中 hive 為管理員使用者)的 ticket 連線 hive-server2,建立 role、group 等等,執行下面語句:

 
  1. create role admin_role;

  2. GRANT ALL ON SERVER server1 TO ROLE admin_role;

  3. GRANT ROLE admin_role TO GROUP admin;

  4. GRANT ROLE admin_role TO GROUP hive;

  5.  
  6. create role test_role;

  7. GRANT ALL ON DATABASE filtered TO ROLE test_role;

  8. GRANT ALL ON DATABASE sensitive TO ROLE test_role;

  9. GRANT ROLE test_role TO GROUP test;

上面建立了兩個角色,一個是 admin_role,具有管理員許可權,可以讀寫所有資料庫,並授權給 admin 和 hive 組(對應作業系統上的組);一個是 test_role,只能讀寫 filtered 和 sensitive 資料庫,並授權給 test 組

在 ldap 建立測試使用者

在 ldap 伺服器上建立系統使用者 yy_test,並使用 migrationtools 工具將該使用者匯入 ldap,最後設定 ldap 中該使用者密碼。

 
  1. # 建立 yy_test使用者

  2. useradd yy_test

  3.  
  4. grep -E "yy_test" /etc/passwd >/opt/passwd.txt

  5. /usr/share/migrationtools/migrate_passwd.pl /opt/passwd.txt /opt/passwd.ldif

  6. ldapadd -x -D "uid=ldapadmin,ou=people,dc=lashou,dc=com" -w secret -f /opt/passwd.ldif

  7.  
  8. #使用下面語句修改密碼,填入上面生成的密碼,輸入兩次:

  9.  
  10. ldappasswd -x -D 'uid=ldapadmin,ou=people,dc=lashou,dc=com' -w secret "uid=yy_test,ou=people,dc=lashou,dc=com" -S

在每臺 datanode 機器上建立 test 分組,並將 yy_test 使用者加入到 test 分組:

groupadd test ; useradd yy_test; usermod -G test,yy_test yy_test

測試

通過 beeline 連線 hive-server2,進行測試:

 
  1. # 切換到 test 使用者進行測試

  2. $ su test

  3.  
  4. $ kinit -k -t test.keytab test/[email protected]

  5.  
  6. $ beeline -u "jdbc:hive2://cdh1:10000/default;principal=test/[email protected]"

1.4 Impala 整合 Sentry

修改配置

修改 /etc/default/impala 檔案中的 IMPALA_SERVER_ARGS 引數,新增:

 
  1. -server_name=server1

  2. -sentry_config=/etc/impala/conf/sentry-site.xml

在 IMPALA_CATALOG_ARGS 中新增:

-sentry_config=/etc/impala/conf/sentry-site.xml

注意:server1 必須和 sentry-provider.ini 檔案中的保持一致。

IMPALA_SERVER_ARGS 引數最後如下:

 
  1. hostname=`hostname -f |tr "[:upper:]" "[:lower:]"`

  2.  
  3. IMPALA_SERVER_ARGS=" \

  4. -log_dir=${IMPALA_LOG_DIR} \

  5. -catalog_service_host=${IMPALA_CATALOG_SERVICE_HOST} \

  6. -state_store_port=${IMPALA_STATE_STORE_PORT} \

  7. -use_statestore \

  8. -state_store_host=${IMPALA_STATE_STORE_HOST} \

  9. -kerberos_reinit_interval=60 \

  10. -principal=impala/${hostname}@JAVACHEN.COM \

  11. -keytab_file=/etc/impala/conf/impala.keytab \

  12. -enable_ldap_auth=true -ldap_uri=ldaps://cdh1 -ldap_baseDN=ou=people,dc=javachen,dc=com \

  13. -server_name=server1 \

  14. -sentry_config=/etc/impala/conf/sentry-site.xml \

  15. -be_port=${IMPALA_BACKEND_PORT} -default_pool_max_requests=-1 -mem_limit=60%"

建立 /etc/impala/conf/sentry-site.xml 內容如下:

 
  1. <?xml version="1.0" encoding="UTF-8"?>

  2. <configuration>

  3. <property>

  4. <name>sentry.service.client.server.rpc-port</name>

  5. <value>8038</value>

  6. </property>

  7. <property>

  8. <name>sentry.service.client.server.rpc-address</name>

  9. <value>cdh1</value>

  10. </property>

  11. <property>

  12. <name>sentry.service.client.server.rpc-connection-timeout</name>

  13. <value>200000</value>

  14. </property>

  15. <property>

  16. <name>sentry.service.security.mode</name>

  17. <value>kerberos</value>

  18. </property>

  19. <property>

  20. <name>sentry.service.server.principal</name>

  21. <value>sentry/[email protected]</value>

  22. </property>

  23. <property>

  24. <name>sentry.service.server.keytab</name>

  25. <value>/etc/sentry/conf/sentry.keytab</value>

  26. </property>

  27. </configuration>

測試

請參考下午基於檔案儲存方式中 impala 的測試。

2. 基於檔案儲存方式

2.1 hive 整合 sentry

修改配置檔案

在 hive 的 /etc/hive/conf 目錄下建立 sentry-site.xml 檔案,內容如下:

 
  1. <?xml version="1.0" encoding="UTF-8"?>

  2. <configuration>

  3. <property>

  4. <name>hive.sentry.server</name>

  5. <value>server1</value>

  6. </property>

  7. <property>

  8. <name>sentry.hive.provider.backend</name>

  9. <value>org.apache.sentry.provider.file.SimpleFileProviderBackend</value>

  10. </property>

  11. <property>

  12. <name>hive.sentry.provider</name>

  13. <value>org.apache.sentry.provider.file.HadoopGroupResourceAuthorizationProvider</value>

  14. </property>

  15. <property>

  16. <name>hive.sentry.provider.resource</name>

  17. <value>/user/hive/sentry/sentry-provider.ini</value>

  18. </property>

  19. </configuration>

建立 sentry-provider.ini 檔案並將其上傳到 hdfs 的 /user/hive/sentry/ 目錄:

 
  1. $ cat /tmp/sentry-provider.ini

  2. [databases]

  3. # Defines the location of the per DB policy file for the customers DB/schema

  4. #db1 = hdfs://cdh1:8020/user/hive/sentry/db1.ini

  5.  
  6. [groups]

  7. admin = any_operation

  8. hive = any_operation

  9. test = select_filtered

  10.  
  11. [roles]

  12. any_operation = server=server1->db=*->table=*->action=*

  13. select_filtered = server=server1->db=filtered->table=*->action=SELECT

  14. select_us = server=server1->db=filtered->table=events_usonly->action=SELECT

  15.  
  16. [users]

  17. test = test

  18. hive= hive

  19.  
  20. $ hdfs dfs -rm -r /user/hive/sentry/sentry-provider.ini

  21. $ hdfs dfs -put /tmp/sentry-provider.ini /user/hive/sentry/

  22. $ hdfs dfs -chown hive:hive /user/hive/sentry/sentry-provider.ini

  23. $ hdfs dfs -chmod 640 /user/hive/sentry/sentry-provider.ini

關於 sentry-provider.ini 檔案的語法說明,請參考官方文件。這裡我指定了 Hive 組有全部許可權,並指定 Hive 使用者屬於 Hive 分組,而其他兩個分組只有部分許可權。

然後在 hive-site.xml 中新增如下配置:

 
  1. <property>

  2. <name>hive.security.authorization.task.factory</name>

  3. <value>org.apache.sentry.binding.hive.SentryHiveAuthorizationTaskFactoryImpl</value>

  4. </property>

  5. <property>

  6. <name>hive.server2.session.hook</name>

  7. <value>org.apache.sentry.binding.hive.HiveAuthzBindingSessionHook</value>

  8. </property>

  9. <property>

  10. <name>hive.sentry.conf.url</name>

  11. <value>file:///etc/hive/conf/sentry-site.xml</value>

  12. </property>

將配置檔案同步到其他節點,並重啟 hive-server2 服務。

測試

這裡,我叢集中 hive-server2 開啟了 kerberos 認證,故通過 hive 使用者來連線 hive-server2。

 
  1. $ kinit -k -t /etc/hive/conf/hive.keytab hive/[email protected]

  2.  
  3. $ beeline -u "jdbc:hive2://cdh1:10000/default;principal=hive/[email protected]"

  4. scan complete in 10ms

  5. Connecting to jdbc:hive2://cdh1:10000/default;principal=hive/[email protected]

  6. Connected to: Apache Hive (version 0.13.1-cdh5.2.0)

  7. Driver: Hive JDBC (version 0.13.1-cdh5.2.0)

  8. Transaction isolation: TRANSACTION_REPEATABLE_READ

  9. Beeline version 0.13.1-cdh5.2.0 by Apache Hive

  10. 5 rows selected (0.339 seconds)

  11.  
  12. 0: jdbc:hive2://cdh1:10000/default> show databases;

  13. +----------------+--+

  14. | database_name |

  15. +----------------+--+

  16. | default |

  17. | filtered |

  18. | sensitive |

  19. +----------------+--+

  20. 10 rows selected (0.145 seconds)

  21.  
  22. 0: jdbc:hive2://cdh1:10000/default> use filtered

  23. No rows affected (0.132 seconds)

  24.  
  25. 0: jdbc:hive2://cdh1:10000/default> show tables;

  26. +----------------+--+

  27. | tab_name |

  28. +----------------+--+

  29. | events |

  30. | events_usonly |

  31. +----------------+--+

  32. 2 rows selected (0.158 seconds)

  33. 0: jdbc:hive2://cdh1:10000/default> use sensitive;

  34. No rows affected (0.115 seconds)

  35.  
  36. 0: jdbc:hive2://cdh1:10000/default> show tables;

  37. +-----------+--+

  38. | tab_name |

  39. +-----------+--+

  40. | events |

  41. +-----------+--+

  42. 1 row selected (0.148 seconds)

2.3 impala 整合 sentry

修改配置檔案

修改 /etc/default/impala 檔案中的 IMPALA_SERVER_ARGS 引數,新增:

 
  1. -server_name=server1

  2. -authorization_policy_file=/user/hive/sentry/sentry-provider.ini

  3. -authorization_policy_provider_class=org.apache.sentry.provider.file.LocalGroupResourceAuthorizationProvider

注意:server1 必須和 sentry-provider.ini 檔案中的保持一致。

IMPALA_SERVER_ARGS 引數最後如下:

 
  1. hostname=`hostname -f |tr "[:upper:]" "[:lower:]"`

  2.  
  3. IMPALA_SERVER_ARGS=" \

  4. -log_dir=${IMPALA_LOG_DIR} \

  5. -catalog_service_host=${IMPALA_CATALOG_SERVICE_HOST} \

  6. -state_store_port=${IMPALA_STATE_STORE_PORT} \

  7. -use_statestore \

  8. -state_store_host=${IMPALA_STATE_STORE_HOST} \

  9. -be_port=${IMPALA_BACKEND_PORT} \

  10. -server_name=server1 \

  11. -authorization_policy_file=/user/hive/sentry/sentry-provider.ini \

  12. -authorization_policy_provider_class=org.apache.sentry.provider.file.LocalGroupResourceAuthorizationProvider \

  13. -enable_ldap_auth=true -ldap_uri=ldaps://cdh1 -ldap_baseDN=ou=people,dc=javachen,dc=com \

  14. -kerberos_reinit_interval=60 \

  15. -principal=impala/${hostname}@JAVACHEN.COM \

  16. -keytab_file=/etc/impala/conf/impala.keytab \

  17. "

測試

重啟 impala-server 服務,然後進行測試。因為我這裡 impala-server 集成了 kerberos 和 ldap,現在通過 ldap 來進行測試。

先通過 ldap 的 test 使用者來測試:

 
  1. impala-shell -l -u test

  2. Starting Impala Shell using LDAP-based authentication

  3. LDAP password for test:

  4. Connected to cdh1:21000

  5. Server version: impalad version 2.0.0-cdh5 RELEASE (build ecf30af0b4d6e56ea80297df2189367ada6b7da7)

  6. Welcome to the Impala shell. Press TAB twice to see a list of available commands.

  7.  
  8. Copyright (c) 2012 Cloudera, Inc. All rights reserved.

  9.  
  10. (Shell build version: Impala Shell v2.0.0-cdh5 (ecf30af) built on Sat Oct 11 13:56:06 PDT 2014)

  11.  
  12. [cdh1:21000] > show databases;

  13. Query: show databases

  14. +---------+

  15. | name |

  16. +---------+

  17. | default |

  18. +---------+

  19. Fetched 1 row(s) in 0.11s

  20.  
  21. [cdh1:21000] > show tables;

  22.  
  23. Query: show tables

  24. ERROR: AuthorizationException: User 'test' does not have privileges to access: default.*

  25.  
  26. [cdh1:21000] >

可以看到 test 使用者沒有許可權檢視和資料庫,這是因為 sentry-provider.ini 檔案中並沒有給 test 使用者分配任何許可權。

下面使用 hive 使用者來測試。使用下面命令在 ldap 中建立 hive 使用者和組並給 hive 使用者設定密碼。

 
  1. $ grep hive /etc/passwd >/opt/passwd.txt

  2. $ /usr/share/migrationtools/migrate_passwd.pl /opt/passwd.txt /opt/passwd.ldif

  3.  
  4. $ ldapadd -x -D "uid=ldapadmin,ou=people,dc=javachen,dc=com" -w secret -f /opt/passwd.ldif

  5.  
  6. $ grep hive /etc/group >/opt/group.txt

  7. $ /usr/share/migrationtools/migrate_group.pl /opt/group.txt /opt/group.ldif

  8.  
  9. $ ldapadd -x -D "uid=ldapadmin,ou=people,dc=javachen,dc=com" -w secret -f /opt/group.ldif

  10.  
  11. # 修改 ldap 中 hive 使用者密碼

  12. $ ldappasswd -x -D 'uid=ldapadmin,ou=people,dc=javachen,dc=com' -w secret "uid=hive,ou=people,dc=javachen,dc=com" -S

然後,使用 hive 使用者測試:

$ impala-shell -l -u hive
    Starting Impala Shell using LDAP-based authentication
    LDAP password for hive:
    Connected to cdh1:21000
    Server version: impalad version 2.0.0-cdh5 RELEASE (build ecf30af0b4d6e56ea80297df2189367ada6b7da7)
    Welcome to the Impala shell. Press TAB twice to see a list of available commands.

    Copyright (c) 2012 Cloudera, Inc. All rights reserved.

    (Shell build version: Impala Shell v2.0.0-cdh5 (ecf30af) built on Sat Oct 11 13:56:06 PDT 2014)

[cdh1:21000] > show databases;
    Query: show databases
    +------------------+
    | name             |
    +------------------+
    | _impala_builtins |
    | default          |
    | filtered         |
    | sensitive        |
    +------------------+
    Fetched 11 row(s) in 0.11s

[cdh1:21000] > use sensitive;
    Query: use sensitive

[cdh1:21000] > show tables;
    Query: show tables
    +--------+
    | name   |
    +--------+
    | events |
    +--------+
    Fetched 1 row(s) in 0.11s

[cdh1:21000] > select * from events;
    Query: select * from events
    +--------------+---------+---------+------------+
    | ip           | country | client  | action     |
    +--------------+---------+---------+------------+
    | 10.1.2.3     | US      | android | createNote |
    | 10.200.88.99 | FR      | windows | updateNote |
    | 10.1.2.3     | US      | android | updateNote |
    | 10.200.88.77 | FR      | ios     | createNote |
    | 10.1.4.5     | US      | windows | updateTag  |
    +--------------+---------+---------+------------+
    Fetched 5 row(s) in 0.76s

同樣,你還可以使用其他使用者來測試。

也可以使用 beeline 來連線 impala-server 來進行測試:

 
  1. $ beeline -u "jdbc:hive2://cdh1:21050/default;" -n test -p test

  2. scan complete in 2ms

  3. Connecting to jdbc:hive2://cdh1:21050/default;

  4. Connected to: Impala (version 2.0.0-cdh5)

  5. Driver: Hive JDBC (version 0.13.1-cdh5.2.0)

  6. Transaction isolation: TRANSACTION_REPEATABLE_READ

  7. Beeline version 0.13.1-cdh5.2.0 by Apache Hive

  8. 0: jdbc:hive2://cdh1:21050/default>

3. 參考文章

  • Securing Impala for analysts
  • Setting Up Hive Authorization with Sentry
  • Sentry原始碼中的配置例子

    impala授權

    SHOW CREATE table hue.auth_permission;
    ALTER TABLE hue.auth_permission DROP FOREIGN KEY content_type_id_refs_id_id value;
    DELETE FROM hue.django_content_type;
    ALTER TABLE hue.auth_permission ADD FOREIGN KEY (content_type_id) REFERENCES django_content_type (id);

    為HDFS定義URI時,還必須指定NameNode。例如:
    GRANT ALL ON URI檔案:/// path / to / dir TO <role>
    GRANT ALL ON URI hdfs:// namenode:port / path / to / dir TO <role>
    GRANT ALL ON URI hdfs:// ha -nn-uri / path / to / dir TO <role>
    管理使用者的許可權示例
    在此示例中,SQL語句授予 entire_server 角色伺服器中的資料庫和URI的所有特權。

    CREATE ROLE whole_server;
    GRANT ROLE whole_server TO GROUP admin_group;
    GRANT ALL ON SERVER server1 TO ROLE whole_server;


    具有特定資料庫和表的許可權的使用者
    如果使用者具有特定資料庫中特定表的許可權,則使用者可以訪問這些內容,但不能訪問其他內容。他們可以在輸出中看到表及其父資料庫 顯示錶格 和 顯示資料庫, 使用 適當的資料庫,並執行相關的行動(選擇 和/或 插)基於表許可權。要實際建立表需要所有 資料庫級別的許可權,因此您可以為使用者設定單獨的角色,以設定架構以及對錶執行日常操作的其他使用者或應用程式。
    CREATE ROLE one_database;
    GRANT ROLE one_database TO GROUP admin_group;
    GRANT ALL ON DATABASE db1 TO ROLE one_database;

    CREATE ROLE instructor;
    GRANT ROLE instructor TO GROUP trainers;
    GRANT ALL ON TABLE db1.lesson TO ROLE instructor;

    # This particular course is all about queries, so the students can SELECT but not INSERT or CREATE/DROP.
    CREATE ROLE student;
    GRANT ROLE student TO GROUP visitors;
    GRANT SELECT ON TABLE db1.training TO ROLE student;

    使用外部資料檔案的許可權
    通過資料插入資料時 負載資料 語句,或從普通Impala資料庫目錄之外的HDFS位置引用,使用者還需要對與這些HDFS位置對應的URI的適當許可權。

    在這個例子中:

    該 external_table 角色可以插入並查詢Impala表, external_table.sample。
    該 STAGING_DIR角色可以指定HDFS路徑/使用者/ Cloudera的/ external_data與負載資料宣告。當Impala查詢或載入資料檔案時,它會對該目錄中的所有檔案進行操作,而不僅僅是單個檔案,因此任何Impala都可以位置 引數指的是目錄而不是單個檔案。
    CREATE ROLE external_table; 
    GRANT ROLE external_table TO GROUP cloudera; 
    GRANT ALL ON TABLE external_table.sample TO ROLE external_table; 

    CREATE ROLE staging_dir; 
    GRANT ROLE staging TO GROUP cloudera; 
    GRANT ALL ON URI'hdfs://127.0.0.1:8020 / user / cloudera / external_data'TO ROLE staging_dir;

    將管理員職責與讀寫許可權分開
    要建立資料庫,您需要該資料庫的完全許可權,而對該資料庫中的表的日常操作可以在特定表上使用較低級別的許可權執行。因此,您可以為每個資料庫或應用程式設定單獨的角色:可以建立或刪除資料庫的管理角色,以及只能訪問相關表的使用者級角色。

    在此示例中,職責分為3個不同組中的使用者:
    CREATE ROLE training_sysadmin;
    GRANT ROLE training_sysadmin TO GROUP supergroup;
    GRANT ALL ON DATABASE training1 TO ROLE training_sysadmin;

    CREATE ROLE instructor;
    GRANT ROLE instructor TO GROUP cloudera;
    GRANT ALL ON TABLE training1.course1 TO ROLE instructor;

    CREATE ROLE visitor;
    GRANT ROLE student TO GROUP visitor;
    GRANT SELECT ON TABLE training1.course1 TO ROLE student;

    server=server_name->db=database_name->table=table_name->action=SELECT
    server=server_name->db=database_name->table=table_name->action=ALL

    server=impala-host.example.com->db=default->table=t1->action=SELECT
    server=impala-host.example.com->db=*->table=audit_log->action=SELECT
    server=impala-host.example.com->db=default->table=t1->action=*