1 概述
默认情况下hadoop中hdfs和mapreduce运行在一种不安全的环境中,引用《hadoop权威指南》中的一段话:“从安全角度分析,Hadoop缺乏一个安全打的认证机制,以确保试图在集群上执行操作的用户恰是所声称的安全用户。但是,Hadoop的文件许可模块只提供一种简单的认证机制,以决定各个文件对特定文件的访问权限。”
上面一段话描述的安全问题,我也遇到了,对于启用权限的伪分布式hadoop环境,写文件的时候不提供用户信息,则访问出错,但是在写文件的api中加上启动hadoop的用户信息,则顺利写入。这应该是为什么hadoop要使用kerbeos的最直接的原因吧。
2.4.1的hadoop可以为hdfs和mapreduce配置kerberos,这里以hdfs为例记录配置过程。
2 配置说明
2.1 部署kerberos服务
主要做两件事情:
1、安装部署过程请参考我的博客:。
2、在kerberos中为namenode和datanode分别新建principal:
host/admin@psy.com
http/admin@psy.com
2.2 配置hdfs
Hdfs的配置主要参考“hadoop-2.4.1/share/doc/hadoop/hadoop-project-dist/hadoop-common/SecureMode.html”,下面是我的实施步骤。
1、关于hdfs启动用户的说明
操作系统用户这块我没有做特别的操作,用的是之前创建的hadoop帐号,apache Hadoop的文档上说新建hdfs用户启动hdfs服务,新建yarn用户启动yarn服务,我直接偷懒了。
2、创建密钥文件,用于无密码登录
在任何一台机上运行命令:
ktutil: add_entry -password -p nn/admin@psy.com -k 3 -e aes256-cts-hmac-sha1-96 ktutil: add_entry -password -p host/admin@psy.com -k 3 -e aes256-cts-hmac-sha1-96 ktutil: write_kt /hadoop-data/etc/hadoop/nn.service.keytab ktutil: add_entry -password -p dn/admin@psy.com -k 3 -e aes256-cts-hmac-sha1-96 ktutil: add_entry -password -p host/admin@psy.com -k 3 -e aes256-cts-hmac-sha1-96 ktutil: write_kt /hadoop-data/etc/hadoop/dn.service.keytab ktutil: add_entry -password -p http/admin@psy.com -k 3 -e aes256-cts-hmac-sha1-96 ktutil: write_kt /hadoop-data/etc/hadoop/http.service.keytab |
3、修改配置文件
core-site.xml
<property> <name>hadoop.security.authentication</name> <value>kerberos</value> </property> <property> <name>hadoop.security.authorization</name> <value>true</value> </property> <property> <name>hadoop.security.auth_to_local</name> <value>RULE:[2:$1@$0](.*@psy.com)s/.*/hadoop/ DEFAULT </value> </property> |
Hdfs-site.xml
<property> <name>dfs.block.access.token.enable</name> <value>true</value> </property> <property> <name>dfs.namenode.https-address</name> <value>namenode:50470</value> </property> <property> <name>dfs.https.port</name> <value>50470</value> </property> <property> <name>dfs.namenode.keytab.file</name> <value>/hadoop-data/etc/hadoop/nn.service.keytab</value> </property> <property> <name>dfs.namenode.kerberos.principal</name> <value>nn/admin@psy.com</value> </property> <property> <name>dfs.namenode.kerberos.https.principal</name> <value>host/admin@psy.com</value> </property> <property> <name>dfs.namenode.secondary.http-address</name> <value>namenode:50090</value> </property> <property> <name>dfs.namenode.secondary.https-port</name> <value>50470</value> </property> <property> <name>dfs.namenode.secondary.keytab.file</name> <value>/hadoop-data/etc/hadoop/sn.service.keytab</value> </property> <property> <name>dfs.namenode.secondary.kerberos.principal</name> <value>sn/admin@psy.com</value> </property> <property> <name>dfs.namenode.kerberos.https.principal</name> <value>host/admin@psy.com</value> </property> <property> <name>dfs.datanode.data.dir.perm</name> <value>700</value> </property> <property> <name>dfs.datanode.keytab.file</name> <value>/hadoop-data/etc/hadoop/dn.service.keytab</value> </property> <property> <name>dfs.datanode.kerberos.principal</name> <value>dn/admin@psy.com</value> </property> <property> <name>dfs.datanode.kerberos.https.principal</name> <value>host/admin@psy.com</value> </property> <property> <name>dfs.encrypt.data.transfer</name> <value>true</value> </property> <property> <name>dfs.webhdfs.enabled</name> <value>true</value> </property> <property> <name>dfs.web.authentication.kerberos.principal</name> <value>http/admin@psy.com</value> </property> <property> <name>dfs.web.authentication.kerberos.keytab</name> <value>/hadoop-data/etc/hadoop/http.service.keytab</value> </property> <property> <name>ignore.secure.ports.for.testing</name> <value>true</value> </property> |
特别说明如下:
Ø 在apache hadoop的安全配置文档中并没用提到“ignore.secure.ports.for.testing”这个属性,参看本文的读者可以视自己的环境添加。由于作者在配置过程中遇到一个异常,跟踪源码后,发现了这个属性,做了设置后,异常不再;
Ø 在apache hadoop的安全配置文档中是有ssl的配置的,作者去掉了这块,因为这块的配置,作者不太了解,并且重点在kerberos,所以就忽略他了;
Ø 在启动namenode的时候,作者遇到了一个很奇怪的问题,之所以奇怪,大部分原因是作者的学识不够。显然本文的目的是为hadoop的hdfs服务配置kerberos,作者同时打开了webhdfs的权限开关,这就出现一个问题了。namenode启动失败,登录失败,却能够成功登录。namenode的日志信息中有如下的出错信息:
2014-10-24 01:44:54,376 INFO org.apache.hadoop.security.authentication.server.KerberosAuthenticationHandler: Login using keytab /hadoop-data/etc/hadoop/http.service.keytab, for principal http/admin@psy.com 2014-10-24 01:44:54,382 WARN org.mortbay.log: failed SpnegoFilter: javax.servlet.ServletException: javax.security.auth.login.LoginException: No key to store 2014-10-24 01:44:54,383 WARN org.mortbay.log: Failed startup of context org.mortbay.jetty.webapp.WebAppContext@4f98b5c{/,file:/opt/hadoop-2.4.1/share/hadoop/hdfs/webapps/hdfs} javax.servlet.ServletException: javax.security.auth.login.LoginException: No key to store at org.apache.hadoop.security.authentication.server.KerberosAuthenticationHandler.init(KerberosAuthenticationHandler.java:203) at org.apache.hadoop.security.authentication.server.AuthenticationFilter.init(AuthenticationFilter.java:150) at org.mortbay.jetty.servlet.FilterHolder.doStart(FilterHolder.java:97) at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50) at org.mortbay.jetty.servlet.ServletHandler.initialize(ServletHandler.java:713) at org.mortbay.jetty.servlet.Context.startContext(Context.java:140) at org.mortbay.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1282) at org.mortbay.jetty.handler.ContextHandler.doStart(ContextHandler.java:518) at org.mortbay.jetty.webapp.WebAppContext.doStart(WebAppContext.java:499) at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50) at org.mortbay.jetty.handler.HandlerCollection.doStart(HandlerCollection.java:152) at org.mortbay.jetty.handler.ContextHandlerCollection.doStart(ContextHandlerCollection.java:156) at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50) at org.mortbay.jetty.handler.HandlerWrapper.doStart(HandlerWrapper.java:130) at org.mortbay.jetty.Server.doStart(Server.java:224) at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50) at org.apache.hadoop.http.HttpServer2.start(HttpServer2.java:796) at org.apache.hadoop.hdfs.server.namenode.NameNodeHttpServer.start(NameNodeHttpServer.java:132) at org.apache.hadoop.hdfs.server.namenode.NameNode.startHttpServer(NameNode.java:666) at org.apache.hadoop.hdfs.server.namenode.NameNode.initialize(NameNode.java:557) at org.apache.hadoop.hdfs.server.namenode.NameNode.<init>(NameNode.java:724) at org.apache.hadoop.hdfs.server.namenode.NameNode.<init>(NameNode.java:708) at org.apache.hadoop.hdfs.server.namenode.NameNode.createNameNode(NameNode.java:1358) at org.apache.hadoop.hdfs.server.namenode.NameNode.main(NameNode.java:1424) Caused by: javax.security.auth.login.LoginException: No key to store at com.sun.security.auth.module.Krb5LoginModule.commit(Krb5LoginModule.java:1072) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:606) at javax.security.auth.login.LoginContext.invoke(LoginContext.java:762) at javax.security.auth.login.LoginContext.access$000(LoginContext.java:203) at javax.security.auth.login.LoginContext$4.run(LoginContext.java:690) at javax.security.auth.login.LoginContext$4.run(LoginContext.java:688) at java.security.AccessController.doPrivileged(Native Method) at javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:687) at javax.security.auth.login.LoginContext.login(LoginContext.java:596) at org.apache.hadoop.security.authentication.server.KerberosAuthenticationHandler.init(KerberosAuthenticationHandler.java:187) ... 23 more |
说实话,到我写这篇文章的时候,我还是不明白其中的缘由,所以我没直接解决这个问题,但是我注意到一个现象,能够成功登录,却不能,对比了这两部分登录代码,登录,loginContext使用的配置类是HadoopConfiguration,类KerberosConfiguration,打印调试日志后,又让我发现其中的不同:
Debug is true storeKey true useTicketCache false useKeyTab true doNotPrompt true ticketCache is null isInitiator true KeyTab is /hadoop-data/etc/hadoop/nn.service.keytab refreshKrb5Config is true principal is nn/admin@psy.com tryFirstPass is false useFirstPass is false storePass is false clearPass is false Refreshing Kerberos configuration principal is nn/admin@psy.com Will use keytab Commit Succeeded Debug is true storeKey true useTicketCache true useKeyTab true doNotPrompt true ticketCache is null isInitiator false KeyTab is /hadoop-data/etc/hadoop/http.service.keytab refreshKrb5Config is true principal is http/admin@psy.com tryFirstPass is false useFirstPass is false storePass is false clearPass is false Refreshing Kerberos configuration Acquire TGT from Cache Principal is http/admin@psy.com [Krb5LoginModule]: Entering logout [Krb5LoginModule]: logged out Subject |
两端调试日志中不一样的部分已经标出来了,在没有其他解决办法的情况下,我改了KerberosConfiguration的源码。
Ø 在core-site.xml中hadoop.security.auth_to_local的写法需要特别注意,参考链接:。
2.3 验证hdfs
2.3.1 授权不过的现象
![](http://static.oschina.net/uploads/space/2014/1026/225859_SiVs_781254.png)
2.3.2 授权通过的现象
![](http://static.oschina.net/uploads/space/2014/1026/225921_pXMX_781254.png)