目前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後面都實現了這種方式,並且推薦使用這種方式。