因为DataNode数据传输协议不使用Hadoop RPC框架,DataNode必须使用由dfs.datanode.address和dfs.datanode.http.address指定的特权端口进行身份验证。此身份验证基于以下假设:攻击者将无法在DataNode主机上获得root权限。
以root用户身份执行hdfs datanode命令时,服务器进程首先绑定特权端口,然后删除特权并以HADOOP_SECURE_DN_USER指定的用户帐户运行。此启动过程使用安装到JSVC_HOME的jsvc程序。您必须在启动时(在hadoop-env.sh中)指定HADOOP_SECURE_DN_USER和JSVC_HOME作为环境变量。
从版本2.6.0起,SASL可用于验证数据传输协议。在此配置中,安全集群不再需要使用jsvc以root身份启动DataNode并绑定到特权端口。要启用SASL数据传输协议,请在hdfs-site.xml中设置dfs.data.transfer.protection,为dfs.datanode.address设置非特权端口,将dfs.http.policy设置为HTTPS_ONLY,并确保HADOOP_SECURE_DN_USER环境变量未定义。 请注意,如果dfs.datanode.address设置为特权端口,则不能在数据传输协议上使用SASL。 出于向后兼容性的原因,这是必需的。
配置HDFS
Hadoop的配置分为2步:
创建Principal和*unix用户的映射关系。
例如我们上面datanode服务的Principal是dn/cdh1@HADOOP.COM,默认的hadoop.security.auth_to_local规则是将instance和realm去掉,只保留dn,但实际上hdfs的用户maybe不是dn(我这里操作hdfs的用户是hadoop,如果你用包安装的话可能是叫hdfs,具体可以看hdfs上默认文件的用户是谁),dn这个用户在linux机器里也不存在,那么dn连接nn的时候,会提示错误找不到这个用户的组:
2016-06-07 19:06:58,329 INFO SecurityLogger.org.apache.hadoop.ipc.Server: Auth successful for dn/cdh2@HADOOP.COM (auth:KERBEROS)
2016-06-07 19:06:58,393 WARN org.apache.hadoop.security.UserGroupInformation: No groups available for user dn
2016-06-07 19:06:58,393 INFO org.apache.hadoop.ipc.Server: IPC Server handler 2 on 8020, call org.apache.hadoop.hdfs.server.protocol.DatanodeProtocol.versionRequest from 192.168.103.224:55035 Call#0 Retry#0: org.apache.hadoop.security.AccessControlException: Access denied for user dn. Superuser privilege is required
map配置方法:修改core-site.xml,增加:
<property>
<name>hadoop.security.auth_to_local</name>
<value>RULE:[2:$1@$0]([nd]n@ZELDA.COM)s/.*/dtdream/DEFAULT</value>
</property>
RULE的写法可以参考这儿,跟Kerberos的规则一样。具体到hadoop,这篇文章更直接一点。
上面的RULE表示会将nn和dn都替换为dtdream。
2、配置HDFS
2.1 总的配置
详细各参数的说明请见hortonworks官网,下面直接贴出来我的配置,略长。
<property>
<name>dfs.block.access.token.enable</name>
<value>true</value>
</property>
<!-- NameNode security config -->
<property>
<name>dfs.namenode.kerberos.principal</name>
<value>nn/_HOST@HADOOP.COM</value>
</property>
<property>
<name>dfs.namenode.keytab.file</name>
<value>/etc/security/nn.service.keytab</value> <!-- path to the HDFS keytab -->
</property>
<property>
<name>dfs.https.port</name>
<value>50470</value>
</property>
<property>
<