1. 程式人生 > >hadoop開啟Service Level Authorization 服務級認證-SIMPLE認證-過程中遇到的坑

hadoop開啟Service Level Authorization 服務級認證-SIMPLE認證-過程中遇到的坑

背景描述:

  最近在進行安全掃描的時候,說hadoop存在漏洞,Hadoop 未授權訪問【原理掃描】,然後就參考官方文件及一些資料,在測試環境中進行了開啟,中間就遇到了很多的坑,或者說自己沒有想明白的問題,在此記錄下吧,這個問題搞了2天。

環境描述:

  hadoop版本:2.6.2

操作步驟:

1.想要開啟服務級認證,需要在core-site.xml檔案中開啟引數hadoop.security.authorization,將其設定為true

<property>
  <name>hadoop.security.authorization</name>
  <value>true</value>
  <description>Is service-level authorization enabled?</description>
</property>

備註:根據官方文件的解釋,設定為true就是simple型別的認證,基於OS使用者的認證.現在服務級的認證已經開啟了。

增加此引數之後,需要重啟namenode:

sbin/hadoop-daemon.sh stop namenode
sbin/hadoop-daemon.sh start namenode

如何知道是否真正的開啟了該配置,檢視hadoop安全日誌SecurityAuth-aiprd.audit,如果有新日誌增加,裡面帶有認證資訊,說明開啟成功。

2.針對具體的各個服務的認證,在配置檔案hadoop-policy.xml中

<configuration>
  <property>
    <name>security.client.protocol.acl</name>
    <value>*</value>
    <description>ACL for ClientProtocol, which is used by user code
    via the DistributedFileSystem.
    The ACL is a comma-separated list of user and group names. The user and
    group list is separated by a blank. For e.g. "alice,bob users,wheel".
    A special value of "*" means all users are allowed.</description>
  </property>

  <property>
    <name>security.client.datanode.protocol.acl</name>
    <value>*</value>
    <description>ACL for ClientDatanodeProtocol, the client-to-datanode protocol
    for block recovery.
    The ACL is a comma-separated list of user and group names. The user and
    group list is separated by a blank. For e.g. "alice,bob users,wheel".
    A special value of "*" means all users are allowed.</description>
  </property>

  <property>
    <name>security.datanode.protocol.acl</name>
    <value>*</value>
    <description>ACL for DatanodeProtocol, which is used by datanodes to
    communicate with the namenode.
    The ACL is a comma-separated list of user and group names. The user and
    group list is separated by a blank. For e.g. "alice,bob users,wheel".
    A special value of "*" means all users are allowed.</description>
  </property>

  <property>
    <name>security.inter.datanode.protocol.acl</name>
    <value>*</value>
    <description>ACL for InterDatanodeProtocol, the inter-datanode protocol
    for updating generation timestamp.
    The ACL is a comma-separated list of user and group names. The user and
    group list is separated by a blank. For e.g. "alice,bob users,wheel".
    A special value of "*" means all users are allowed.</description>
  </property>

  <property>
    <name>security.namenode.protocol.acl</name>
    <value>*</value>
    <description>ACL for NamenodeProtocol, the protocol used by the secondary
    namenode to communicate with the namenode.
    The ACL is a comma-separated list of user and group names. The user and
    group list is separated by a blank. For e.g. "alice,bob users,wheel".
    A special value of "*" means all users are allowed.</description>
  </property>

 <property>
    <name>security.admin.operations.protocol.acl</name>
    <value>*</value>
    <description>ACL for AdminOperationsProtocol. Used for admin commands.
    The ACL is a comma-separated list of user and group names. The user and
    group list is separated by a blank. For e.g. "alice,bob users,wheel".
    A special value of "*" means all users are allowed.</description>
  </property>

  <property>
    <name>security.refresh.user.mappings.protocol.acl</name>
    <value>*</value>
    <description>ACL for RefreshUserMappingsProtocol. Used to refresh
    users mappings. The ACL is a comma-separated list of user and
    group names. The user and group list is separated by a blank. For
    e.g. "alice,bob users,wheel".  A special value of "*" means all
    users are allowed.</description>
  </property>

  <property>
    <name>security.refresh.policy.protocol.acl</name>
    <value>*</value>
    <description>ACL for RefreshAuthorizationPolicyProtocol, used by the
    dfsadmin and mradmin commands to refresh the security policy in-effect.
    The ACL is a comma-separated list of user and group names. The user and
    group list is separated by a blank. For e.g. "alice,bob users,wheel".
    A special value of "*" means all users are allowed.</description>
  </property>

  <property>
    <name>security.ha.service.protocol.acl</name>
    <value>*</value>
    <description>ACL for HAService protocol used by HAAdmin to manage the
      active and stand-by states of namenode.</description>
  </property>

  <property>
    <name>security.zkfc.protocol.acl</name>
    <value>*</value>
    <description>ACL for access to the ZK Failover Controller
    </description>
  </property>

  <property>
    <name>security.qjournal.service.protocol.acl</name>
    <value>*</value>
    <description>ACL for QJournalProtocol, used by the NN to communicate with
    JNs when using the QuorumJournalManager for edit logs.</description>
  </property>

  <property>
    <name>security.mrhs.client.protocol.acl</name>
    <value>*</value>
    <description>ACL for HSClientProtocol, used by job clients to
    communciate with the MR History Server job status etc. 
    The ACL is a comma-separated list of user and group names. The user and
    group list is separated by a blank. For e.g. "alice,bob users,wheel".
    A special value of "*" means all users are allowed.</description>
  </property>

  <!-- YARN Protocols -->

  <property>
    <name>security.resourcetracker.protocol.acl</name>
    <value>*</value>
    <description>ACL for ResourceTrackerProtocol, used by the
    ResourceManager and NodeManager to communicate with each other.
    The ACL is a comma-separated list of user and group names. The user and
    group list is separated by a blank. For e.g. "alice,bob users,wheel".
    A special value of "*" means all users are allowed.</description>
  </property>

  <property>
    <name>security.resourcemanager-administration.protocol.acl</name>
    <value>*</value>
    <description>ACL for ResourceManagerAdministrationProtocol, for admin commands. 
    The ACL is a comma-separated list of user and group names. The user and
    group list is separated by a blank. For e.g. "alice,bob users,wheel".
    A special value of "*" means all users are allowed.</description>
  </property>

  <property>
    <name>security.applicationclient.protocol.acl</name>
    <value>*</value>
    <description>ACL for ApplicationClientProtocol, used by the ResourceManager 
    and applications submission clients to communicate with each other.
    The ACL is a comma-separated list of user and group names. The user and
    group list is separated by a blank. For e.g. "alice,bob users,wheel".
    A special value of "*" means all users are allowed.</description>
  </property>

  <property>
    <name>security.applicationmaster.protocol.acl</name>
    <value>*</value>
    <description>ACL for ApplicationMasterProtocol, used by the ResourceManager 
    and ApplicationMasters to communicate with each other.
    The ACL is a comma-separated list of user and group names. The user and
    group list is separated by a blank. For e.g. "alice,bob users,wheel".
    A special value of "*" means all users are allowed.</description>
  </property>

  <property>
    <name>security.containermanagement.protocol.acl</name>
    <value>*</value>
    <description>ACL for ContainerManagementProtocol protocol, used by the NodeManager 
    and ApplicationMasters to communicate with each other.
    The ACL is a comma-separated list of user and group names. The user and
    group list is separated by a blank. For e.g. "alice,bob users,wheel".
    A special value of "*" means all users are allowed.</description>
  </property>

  <property>
    <name>security.resourcelocalizer.protocol.acl</name>
    <value>*</value>
    <description>ACL for ResourceLocalizer protocol, used by the NodeManager 
    and ResourceLocalizer to communicate with each other.
    The ACL is a comma-separated list of user and group names. The user and
    group list is separated by a blank. For e.g. "alice,bob users,wheel".
    A special value of "*" means all users are allowed.</description>
  </property>

  <property>
    <name>security.job.task.protocol.acl</name>
    <value>*</value>
    <description>ACL for TaskUmbilicalProtocol, used by the map and reduce
    tasks to communicate with the parent tasktracker.
    The ACL is a comma-separated list of user and group names. The user and
    group list is separated by a blank. For e.g. "alice,bob users,wheel".
    A special value of "*" means all users are allowed.</description>
  </property>

  <property>
    <name>security.job.client.protocol.acl</name>
    <value>*</value>
    <description>ACL for MRClientProtocol, used by job clients to
    communciate with the MR ApplicationMaster to query job status etc. 
    The ACL is a comma-separated list of user and group names. The user and
    group list is separated by a blank. For e.g. "alice,bob users,wheel".
    A special value of "*" means all users are allowed.</description>
  </property>

  <property>
    <name>security.applicationhistory.protocol.acl</name>
    <value>*</value>
    <description>ACL for ApplicationHistoryProtocol, used by the timeline
    server and the generic history service client to communicate with each other.
    The ACL is a comma-separated list of user and group names. The user and
    group list is separated by a blank. For e.g. "alice,bob users,wheel".
    A special value of "*" means all users are allowed.</description>
  </property>
</configuration>

備註:預設有10個服務,每個服務的預設值都是*,表示的就是任何的使用者都可以對其進行訪問。

3.目前只需要針對客戶端哪些使用者能夠訪問namenode即可,即修改引數security.client.protocol.acl的值

  <property>
    <name>security.zkfc.protocol.acl</name>
    <value>aiprd</value>
    <description>ACL for access to the ZK Failover Controller
    </description>
  </property>

備註:表示客戶端進行對應的使用者是aiprd的就可以訪問namenode。

重新整理ACL配置:

bin/hdfs dfsadmin -refreshServiceAcl

修改格式如下:

<property>
     <name>security.job.submission.protocol.acl</name>
     <value>user1,user2 group1,group2</value>
</property>

備註:該值是,使用者之間逗號隔開,使用者組之間用逗號隔開,使用者和使用者組之間用空格分開,如果沒有使用者,要以空格開頭後面接使用者組。

4.遠端客戶端訪問hdfs中檔案進行驗證

[aiprd@localhost ~]$ hdfs dfs -ls hdfs://hadoop1:9000/
Found 10 items
drwxr-xr-x   - aiprd  supergroup          0 2019-08-14 04:31 hdfs://hadoop1:9000/hbase
drwxr-xr-x   - aiprd  hadoop              0 2019-08-14 06:40 hdfs://hadoop1:9000/test01
drwxr-xr-x   - aiprd  supergroup          0 2019-08-14 06:22 hdfs://hadoop1:9000/test02
drwxr-xr-x   - aiprd  supergroup          0 2019-08-14 23:39 hdfs://hadoop1:9000/test03
drwxr-xr-x   - aiprd  supergroup          0 2019-08-14 06:30 hdfs://hadoop1:9000/test07
drwxr-xr-x   - aiprd  supergroup          0 2019-08-14 06:31 hdfs://hadoop1:9000/test08
drwxr-xr-x   - aiprd  supergroup          0 2019-08-14 06:32 hdfs://hadoop1:9000/test09
drwxr-xr-x   - aiprd  supergroup          0 2019-08-14 06:41 hdfs://hadoop1:9000/test10
drwxrwx---   - aiprd  supergroup          0 2019-08-14 07:06 hdfs://hadoop1:9000/test11
drwxr-xr-x   - aiprd1 supergroup          0 2019-08-15 00:10 hdfs://hadoop1:9000/test12

備註:在客戶端上,將hadoop的程式部署在aiprd使用者下,執行命令能夠檢視其中的檔案、資料夾資訊。同時,aiprd使用者也是啟動namenode的使用者即hadoop中的超級使用者,所以,檢視到的檔案的使用者組都是aiprd.

5.測試,如果增加或者使用其他的使用者是否可以

  <property>
    <name>security.zkfc.protocol.acl</name>
    <value>aiprd1</value>
    <description>ACL for access to the ZK Failover Controller
    </description>
  </property>

重新整理ACL配置。

bin/hdfs dfsadmin -refreshServiceAcl

將使用者修改aiprd1。即只有客戶端的程式使用者是aiprd1才能訪問。

6.在客戶端中,繼續使用之前部署在aiprd使用者下的hadoop客戶端進行訪問

[aiprd@localhost ~]$ hdfs dfs -ls hdfs://hadoop1:9000/
ls: User aiprd (auth:SIMPLE) is not authorized for protocol interface org.apache.hadoop.hdfs.protocol.ClientProtocol, expected client Kerberos principal is null

備註:發現aiprd使用者是不能訪問的了

7.客戶端中,在aiprd1使用者下,在部署hadoop客戶端,然後進行訪問

[aiprd1@localhost ~]$ hdfs dfs -ls hdfs://hadoop1:9000/test12
Found 6 items
drwxr-xr-x   - aiprd  supergroup          0 2019-08-14 23:43 hdfs://hadoop1:9000/test12/01
drwxr-xr-x   - aiprd  supergroup          0 2019-08-14 23:43 hdfs://hadoop1:9000/test12/02
drwxr-xr-x   - aiprd  supergroup          0 2019-08-14 23:43 hdfs://hadoop1:9000/test12/03
drwxr-xr-x   - aiprd  supergroup          0 2019-08-14 23:44 hdfs://hadoop1:9000/test12/04
drwxr-xr-x   - aiprd  supergroup          0 2019-08-14 23:49 hdfs://hadoop1:9000/test12/05
drwxr-xr-x   - aiprd1 supergroup          0 2019-08-15 00:10 hdfs://hadoop1:9000/test12/10

備註:是能夠訪問的,所以,如果要使用使用者來進行認證,那麼客戶端程式對應的OS使用者,必須要和hadoop-policy.xml中配置的使用者一致否則不能訪問。

既然,服務級引數的值,可以是使用者,也可以是使用者組,使用者驗證完了,那麼來驗證使用者組吧,此時,就遇到了很多的坑。

1.還是之前的引數security.zkfc.protocol.acl,這次使用,使用者組

  <property>
    <name>security.zkfc.protocol.acl</name>
    <value>aiprd hadoop</value>
    <description>ACL for access to the ZK Failover Controller
    </description>
  </property>

重新整理ACL配置:

/bin/hdfs dfsadmin -refreshServiceAcl

那麼問題來了,之前的使用者是基於OS級別的判斷,這個應該也是,也就是判斷我這個使用者到底是不是這個使用者組裡面的。

2.在客戶端上aiprd使用者下的程式是可以訪問的,經過之前的驗證沒有問題

3.在客戶端上,在aiprd1下部署hadoop客戶端程式,正常是訪問不了hdfs的,那麼將aiprd1加入到這個hadoop組下,理論上是可以訪問的

[aiprd1@localhost ~]$ id aiprd1
uid=1001(aiprd1) gid=1001(aiprd1) groups=1001(aiprd1),1002(hadoop)
[aiprd1@localhost ~]$ hdfs dfs -ls hdfs://hadoop1:9000/test12
ls: User aiprd1 (auth:SIMPLE) is not authorized for protocol interface org.apache.hadoop.hdfs.protocol.ClientProtocol, expected client Kerberos principal is null

經過驗證,是不可以的,說明這個hadoop分組並沒有起作用。

試瞭如下的辦法:

  • --1.hadoop.security.group.mapping 改了這個引數的值,其實這個引數有預設的值,不需要進行設定的
  • --2.在hdfs所有的節點都建了hadoop使用者組,還是沒有解決問題
  • --3.預設的hdfs中檔案的使用者組是supergroup,也嘗試將aiprd1加入到supergroup中,還是沒有作用
  • --4.使用aiprd這個超級使用者,將hdfs中檔案的使用者組改為hadoop還是沒有效果
  • --5.嘗試在namenode上將aiprd加入到hadoop組還是沒有效果。

實在沒有辦法,開啟DEBUG吧,開啟之後,獲得資訊如下:

2019-08-15 15:12:27,188 WARN org.apache.hadoop.security.ShellBasedUnixGroupsMapping: got exception trying to get groups for user aiprd1: id: aiprd1: No such user

2019-08-15 15:12:27,188 WARN org.apache.hadoop.security.UserGroupInformation: No groups available for user aiprd1
adoop.hdfs.protocol.ClientProtocol, expected client Kerberos principal is null
:SIMPLE)
2019-08-15 15:12:27,188 DEBUG org.apache.hadoop.ipc.Server: Socket Reader #1 for port 9000: responding to null from 192.168.30.1:61985 Call#-3 Retry#-1
2019-08-15 15:12:27,188 DEBUG org.apache.hadoop.ipc.Server: Socket Reader #1 for port 9000: responding to null from 192.168.30.1:61985 Call#-3 Retry#-1 Wrote 243 bytes.
izationException: User aiprd1 (auth:SIMPLE) is not authorized for protocol interface 

意思是說,當試著為這個使用者查詢使用者組的時候,沒有這個使用者,就很奇怪,明明是有使用者的啊。然後就基於這個報錯各種查詢,然後在下面的文章中獲得了點啟示:

https://www.e-learn.cn/content/wangluowenzhang/1136832

 

To accomplish your goal you'd need to add your user account (clott) on the NameNode machine and add it to hadoop group there.

If you are going to run MapReduce with your user, you'd need your user account to be configured on NodeManager hosts as well.

4.按照這個意思,在Namenode節點上,建立aiprd1使用者,並加入到hadoop使用者組裡面。

[root@hadoop1 ~]# useradd -G hadoop aiprd1
[root@hadoop1 ~]# id aiprd1
uid=503(aiprd1) gid=503(aiprd1) groups=503(aiprd1),502(hadoop)
[root@hadoop1 ~]# su - aiprd
[aiprd@hadoop1 ~]$ jps
15289 NameNode
15644 Jps

備註:此節點運行了NameNode.

5.再次在hadoop客戶端上,aiprd1使用者下執行查詢操作

[aiprd1@localhost ~]$ hdfs dfs -ls hdfs://hadoop1:9000/test12
Found 6 items
drwxr-xr-x   - aiprd  supergroup          0 2019-08-14 23:43 hdfs://hadoop1:9000/test12/01
drwxr-xr-x   - aiprd  supergroup          0 2019-08-14 23:43 hdfs://hadoop1:9000/test12/02
drwxr-xr-x   - aiprd  supergroup          0 2019-08-14 23:43 hdfs://hadoop1:9000/test12/03
drwxr-xr-x   - aiprd  supergroup          0 2019-08-14 23:44 hdfs://hadoop1:9000/test12/04
drwxr-xr-x   - aiprd  supergroup          0 2019-08-14 23:49 hdfs://hadoop1:9000/test12/05
drwxr-xr-x   - aiprd1 supergroup          0 2019-08-15 00:10 hdfs://hadoop1:9000/test12/10

可以進行查詢了。

在客戶端上,將aiprd1對應的使用者組hadoop去掉。

[aiprd1@localhost ~]$ id
uid=1001(aiprd1) gid=1001(aiprd1) groups=1001(aiprd1)

再次執行查詢:

[aiprd1@localhost ~]$ hdfs dfs -ls hdfs://hadoop1:9000/test12
Found 6 items
drwxr-xr-x   - aiprd  supergroup          0 2019-08-14 23:43 hdfs://hadoop1:9000/test12/01
drwxr-xr-x   - aiprd  supergroup          0 2019-08-14 23:43 hdfs://hadoop1:9000/test12/02
drwxr-xr-x   - aiprd  supergroup          0 2019-08-14 23:43 hdfs://hadoop1:9000/test12/03
drwxr-xr-x   - aiprd  supergroup          0 2019-08-14 23:44 hdfs://hadoop1:9000/test12/04
drwxr-xr-x   - aiprd  supergroup          0 2019-08-14 23:49 hdfs://hadoop1:9000/test12/05
drwxr-xr-x   - aiprd1 supergroup          0 2019-08-15 00:10 hdfs://hadoop1:9000/test12/10

還是可以查詢的,可以看出來,使用者組和客戶端上使用者所在的組沒有關係,需要在Namenode節點設定。

檢視官方,有如下解釋:

Once a username has been determined as described above, the list of groups is determined by a group mapping service, configured by the hadoop.security.group.mapping property. The default implementation, org.apache.hadoop.security.JniBasedUnixGroupsMappingWithFallback, will determine if the Java Native Interface (JNI) is available. If JNI is available, the implementation will use the API within hadoop to resolve a list of groups for a user. If JNI is not available then the shell implementation, org.apache.hadoop.security.ShellBasedUnixGroupsMapping, is used. This implementation shells out with the bash -c groups command (for a Linux/Unix environment) or the net group command (for a Windows environment) to resolve a list of groups for a user.

An alternate implementation, which connects directly to an LDAP server to resolve the list of groups, is available via org.apache.hadoop.security.LdapGroupsMapping. However, this provider should only be used if the required groups reside exclusively in LDAP, and are not materialized on the Unix servers. More information on configuring the group mapping service is available in the Javadocs.

For HDFS, the mapping of users to groups is performed on the NameNode. Thus, the host system configuration of the NameNode determines the group mappings for the users.

Note that HDFS stores the user and group of a file or directory as strings; there is no conversion from user and group identity numbers as is conventional in Unix.

 

對於HDFS來說,使用者到組的對映關係是在NameNode上執行的,因此,NameNode的主機系統配置決定了使用者組的對映。

實驗之後才看明白,之前根本沒有理解,以為是從客戶端拿到使用者對應的使用者組資訊,然後到NameNode來進行判斷呢。

所以,到這裡,基於服務級的ACL,使用者、使用者組的都已經可以配置了,對於其他的服務,可以根據實際情況進行配置。這裡面只要求哪些使用者、使用者組可以連線上來就好了。

 

小結:

  1.hadoop.security.authorization設定為true,開啟simple認證,即基於os使用者的認證,配置之後,重啟namenode

  2.acl為使用者認證的,保證服務acl中配置的值與客戶端程序對應的使用者一致即可訪問。

  3.acl為使用者組的,客戶端如果使用A訪問,那麼要在NameNode上建立使用者A,將A加入到acl使用者組,驗證過程:獲取客戶端的使用者,比如為A,NameNode節點上,通過使用者A,到NameNode的主機上來查詢使用者A對應的使用者組資訊,如果NameNode上沒有使用者A,認證失敗,如果有使用者A,沒有在acl使用者組上,認證失敗,有使用者A,使用者A在acl配置的組裡面,認證成功。

  4.acl配置的使用者組與客戶端程式使用者,所在的使用者組沒有關係。

  5.每次修改hadoop-policy.xml中的值,記得要執行重新整理操作。

 

另外:要注意,不同版本的引數,配置可能不同,要看和自己hadoop版本一致的文件。

https://hadoop.apache.org/docs/r2.6.2/hadoop-project-dist/hadoop-common/ServiceLevelAuth.html

 https://hadoop.apache.org/docs/r2.6.2/hadoop-project-dist/hadoop-hdfs/HdfsPermissionsGuide.html#Group_Mapping

 

文件建立時間:2019年8月15日17:3