目前Hadoop的稳定版本为1.2.1,咱们的实验就在hadoop-1.2.1上进行java
Hadoop 版本:1.2.1node
OS 版本: Centos6.4linux
环境配置sql
机器名apache |
Ip地址安全 |
功能网络 |
用户app |
Hadoop1负载均衡 |
192.168.124.135框架 |
namenode, datanode, secondNameNode jobtracker, tasktracer |
hadoop |
Hadoop2 |
192.168.124.136 |
Datanode, tasktracker |
hadoop |
Hadoop3 |
192.168.124.137 |
Datanode, tasktracker |
hadoop |
client |
192.168.124.141 |
client |
test |
简单介绍一下hadoop安全须要哪些受权
先来看一下hdfs,当一个用户须要读写hadoop集群上的一个文件时,他一般先跟namenode联系,这就须要namenode的认证(org.apache.hadoop.hdfs.protocol.ClientProtocol定义了须要受权的接口),当namenode成功的认证client用户时,会返回给用户存储文件的datanode,client须要读写datanode上的数据时,一样也须要datanode的认证(org.apache.hadoop.hdfs.protocol.ClientDatanodeProtocol定义了须要受权的接口)。datanode和namenode之间也须要联系,datanode须要定时向namenode发送heartbeat和数据块的信息(org.apache.hadoop.hdfs.server.protocol.DatanodeProtocol定义了须要受权的接口)。Datanode之间也要发生数据交换,好比负载均衡,数据失效(org.apache.hadoop.hdfs.server.protocol.InterDatanodeProtocol定义了须要受权的接口)。Hadoop一般还须要一个secondnamenode来备份数据,由于secondnamenode按期向namenode发送数据请求,这中间也须要namenode的认证(org.apache.hadoop.hdfs.server.protocol.NamenodeProtocol定义了须要受权的接口)。还有两个不经常使用的受权org.apache.hadoop.security.authorize.RefreshAuthorizationPolicyProtocol和org.apache.hadoop.security.RefreshUserMappingsProtocol,这两个受权时检查是否有刷新受权和用户的权限。
咱们再来看一下mapred框架须要哪些受权
当一个client写好map和reduce以及其余相关的程序后,他首先向jobtracker提交job,这就须要获得jobtracker的受权(org.apache.hadoop.mapred.JobSubmissionProtocol定义了须要受权的接口)。提交的job通过jobtracker调度后,会合理的分配到tasktracker节点上,hadoop采用的是tasktracker向jobtracker发送heartbeat或其余信息的返回值来获得task的信息,而不是jobttracker将task推送给tasktracker,也就是说tasktracker须要jobtracker的认证(org.apache.hadoop.mapred.InterTrackerProtocol定义了须要受权的接口)。还有一个必要重要的受权,tasktracker在获得task后,不是直接在本身的进程里执行,而是启动一个叫作Child的子进程,tasktracker和这些Child子进程(一般最多只有两个map和两个reduce)须要交换数据。尽管linux存在不少种进程共享数据的方式,Child和tasktracker仍是经过网络的方式来的,这个交换过程主要都是由Child发起的。因此这些Child也须要获得tasktracer的认证(org.apache.hadoop.mapred.TaskUmbilicalProtocol定义了须要受权的接口)。跟hdfs同样,mapredu中也有两个不经常使用的受权org.apache.hadoop.security.authorize.RefreshAuthorizationPolicyProtocol和org.apache.hadoop.security.RefreshUserMappingsProtocol,这两个受权时检查是否有刷新受权和用户的权限。
这些受权都在org.apache.hadoop.hdfs.HDFSPolicyProvider和org.apache.hadoop.mapred.MapReducePolicyProvider中定义,有兴趣的可能看看。
简单方式配置
conf/core-site.xml加上
<property>
<name>hadoop.security.authorization</name>
<value>true</value>
</property>
<property>
<name>hadoop.security.authentication</name>
<value>simple</value>
</property>
下面作一些简单测试,来验证一下配置
测试代码1
Configuration conf = new Configuration();
conf.set("fs.default.name", "hdfs://hadoop1:9000");
FileSystem hdfs = FileSystem.get(conf);
Path path = new Path("/user/hadoop/input");
FileStatus[] files = hdfs.listStatus(path);
for(int i=0; i< files.length; i++ ){
System.out.println(files[i].getPath());
}
控制台打出的结果
Exception in thread "main" org.apache.hadoop.ipc.RemoteException: User test is not authorized for protocol interface org.apache.hadoop.hdfs.protocol.ClientProtocol, expected client Kerberos principal is null
at org.apache.hadoop.ipc.Client.call(Client.java:1113)
at org.apache.hadoop.ipc.RPC$Invoker.invoke(RPC.java:229)
at com.sun.proxy.$Proxy1.getProtocolVersion(Unknown Source)
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:601)
at org.apache.hadoop.io.retry.RetryInvocationHandler.invokeMethod(RetryInvocationHandler.java:85)
at org.apache.hadoop.io.retry.RetryInvocationHandler.invoke(RetryInvocationHandler.java:62)
at com.sun.proxy.$Proxy1.getProtocolVersion(Unknown Source)
at org.apache.hadoop.ipc.RPC.checkVersion(RPC.java:422)
at org.apache.hadoop.hdfs.DFSClient.createNamenode(DFSClient.java:183)
at org.apache.hadoop.hdfs.DFSClient.<init>(DFSClient.java:281)
at org.apache.hadoop.hdfs.DFSClient.<init>(DFSClient.java:245)
at org.apache.hadoop.hdfs.DistributedFileSystem.initialize(DistributedFileSystem.java:100)
at org.apache.hadoop.fs.FileSystem.createFileSystem(FileSystem.java:1446)
at org.apache.hadoop.fs.FileSystem.access$200(FileSystem.java:67)
at org.apache.hadoop.fs.FileSystem$Cache.get(FileSystem.java:1464)
at org.apache.hadoop.fs.FileSystem.get(FileSystem.java:263)
at org.apache.hadoop.fs.FileSystem.get(FileSystem.java:124)
at test.TestHdfs.main(TestHdfs.java:18)
从上面的结果能够看出,client机器上的test用户没有权限访问hdfs系统。当咱们将代码稍做改变,见测试代码2:
测试代码2
Configuration conf = new Configuration();
conf.set("fs.default.name", "hdfs://hadoop1:9000");
//FileSystem hdfs = FileSystem.get(conf);
FileSystem hdfs = FileSystem.get(new URI("hdfs://hadoop1:9000"), conf, "hadoop");
Path path = new Path("/user/hadoop/input");
FileStatus[] files = hdfs.listStatus(path);
for(int i=0; i< files.length; i++ ){
System.out.println(files[i].getPath());
控制台打出的结果
hdfs://hadoop1:9000/user/hadoop/input/Balancer.java
hdfs://hadoop1:9000/user/hadoop/input/BalancerBandwidthCommand.java
hdfs://hadoop1:9000/user/hadoop/input/BlockAlreadyExistsException.java
hdfs://hadoop1:9000/user/hadoop/input/BlockCommand.java
很显然,使用hadoop用户来访问hdfs就没有任何问题。换一句话说,一旦客户端知道hadoop集群的用户,就能够执行hdfs的操做。这将会存在很大的安全隐患。至少应该有一个登陆系统来提供一个认证功能。
目前经常使用的认证的方式有以下几种:
Kerboros方式,hadoop1后面都实现了这种方式,并且推荐使用这种方式。