Author: arp
Date: Fri Jun 27 08:34:15 2014
New Revision: 1605989
URL: http://svn.apache.org/r1605989
Log:
HADOOP-10565: Merging r1605987 from trunk to branch-2.
Added:
hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/MachineList.java
- copied unchanged from r1605987,
hadoop/common/trunk/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/MachineList.java
hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/util/TestMachineList.java
- copied unchanged from r1605987,
hadoop/common/trunk/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/util/TestMachineList.java
Modified:
hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/CHANGES.txt
hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/authorize/DefaultImpersonationProvider.java
hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/src/site/apt/SecureMode.apt.vm
hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/authorize/TestProxyUsers.java
Modified:
hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/CHANGES.txt
URL:
http://svn.apache.org/viewvc/hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/CHANGES.txt?rev=1605989&r1=1605988&r2=1605989&view=diff
==============================================================================
---
hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/CHANGES.txt
(original)
+++
hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/CHANGES.txt
Fri Jun 27 08:34:15 2014
@@ -114,6 +114,9 @@ Release 2.5.0 - UNRELEASED
HADOOP-10754. Reenable several HA ZooKeeper-related tests on Windows.
(cnauroth)
+ HADOOP-10565. Support IP ranges (CIDR) in proxyuser.hosts. (Benoy Antony
+ via Arpit Agarwal)
+
OPTIMIZATIONS
BUG FIXES
Modified:
hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/authorize/DefaultImpersonationProvider.java
URL:
http://svn.apache.org/viewvc/hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/authorize/DefaultImpersonationProvider.java?rev=1605989&r1=1605988&r2=1605989&view=diff
==============================================================================
---
hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/authorize/DefaultImpersonationProvider.java
(original)
+++
hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/authorize/DefaultImpersonationProvider.java
Fri Jun 27 08:34:15 2014
@@ -18,8 +18,6 @@
package org.apache.hadoop.security.authorize;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
@@ -28,7 +26,7 @@ import java.util.regex.Pattern;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.security.UserGroupInformation;
-import org.apache.hadoop.util.StringUtils;
+import org.apache.hadoop.util.MachineList;
import com.google.common.annotations.VisibleForTesting;
@@ -46,8 +44,8 @@ public class DefaultImpersonationProvide
// acl and list of hosts per proxyuser
private Map<String, AccessControlList> proxyUserAcl =
new HashMap<String, AccessControlList>();
- private Map<String, Collection<String>> proxyHosts =
- new HashMap<String, Collection<String>>();
+ private static Map<String, MachineList> proxyHosts =
+ new HashMap<String, MachineList>();
private Configuration conf;
@Override
@@ -70,7 +68,7 @@ public class DefaultImpersonationProvide
allMatchKeys = conf.getValByRegex(CONF_HADOOP_PROXYUSER_RE_HOSTS);
for(Entry<String, String> entry : allMatchKeys.entrySet()) {
proxyHosts.put(entry.getKey(),
- StringUtils.getTrimmedStringCollection(entry.getValue()));
+ new MachineList(entry.getValue()));
}
}
@@ -95,27 +93,10 @@ public class DefaultImpersonationProvide
+ " is not allowed to impersonate " + user.getUserName());
}
- boolean ipAuthorized = false;
- Collection<String> ipList = proxyHosts.get(
+ MachineList MachineList = proxyHosts.get(
getProxySuperuserIpConfKey(realUser.getShortUserName()));
- if (isWildcardList(ipList)) {
- ipAuthorized = true;
- } else if (ipList != null && !ipList.isEmpty()) {
- for (String allowedHost : ipList) {
- InetAddress hostAddr;
- try {
- hostAddr = InetAddress.getByName(allowedHost);
- } catch (UnknownHostException e) {
- continue;
- }
- if (hostAddr.getHostAddress().equals(remoteAddress)) {
- // Authorization is successful
- ipAuthorized = true;
- }
- }
- }
- if(!ipAuthorized) {
+ if(!MachineList.includes(remoteAddress)) {
throw new AuthorizationException("Unauthorized connection for
super-user: "
+ realUser.getUserName() + " from IP " + remoteAddress);
}
@@ -128,16 +109,6 @@ public class DefaultImpersonationProvide
}
return key;
}
-
- /**
- * Return true if the configuration specifies the special configuration value
- * "*", indicating that any group or host list is allowed to use this
configuration.
- */
- private boolean isWildcardList(Collection<String> list) {
- return (list != null) &&
- (list.size() == 1) &&
- (list.contains("*"));
- }
/**
* Returns configuration key for effective usergroups allowed for a superuser
@@ -180,6 +151,12 @@ public class DefaultImpersonationProvide
@VisibleForTesting
public Map<String, Collection<String>> getProxyHosts() {
- return proxyHosts;
+ Map<String, Collection<String>> tmpProxyHosts =
+ new HashMap<String, Collection<String>>();
+ for (Map.Entry<String, MachineList> proxyHostEntry :proxyHosts.entrySet())
{
+ tmpProxyHosts.put(proxyHostEntry.getKey(),
+ proxyHostEntry.getValue().getCollection());
+ }
+ return tmpProxyHosts;
}
}
Modified:
hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/src/site/apt/SecureMode.apt.vm
URL:
http://svn.apache.org/viewvc/hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/src/site/apt/SecureMode.apt.vm?rev=1605989&r1=1605988&r2=1605989&view=diff
==============================================================================
---
hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/src/site/apt/SecureMode.apt.vm
(original)
+++
hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/src/site/apt/SecureMode.apt.vm
Fri Jun 27 08:34:15 2014
@@ -236,6 +236,25 @@ KVNO Timestamp Principal
</property>
----
+ The <<<hadoop.proxyuser.${superuser}.hosts>>> accepts list of ip addresses,
+ ip address ranges in CIDR format and/or host names.
+
+ For example, by specifying as below in core-site.xml,
+ user named <<<oozie>>> accessing from hosts in the range
+ 10.222.0.0-15 and 10.113.221.221
+ can impersonate any user belonging to any group.
+
+ ----
+ <property>
+ <name>hadoop.proxyuser.oozie.hosts</name>
+ <value>10.222.0.0/16,10.113.221.221</value>
+ </property>
+ <property>
+ <name>hadoop.proxyuser.oozie.groups</name>
+ <value>*</value>
+ </property>
+----
+
** Secure DataNode
Because the data transfer protocol of DataNode
Modified:
hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/authorize/TestProxyUsers.java
URL:
http://svn.apache.org/viewvc/hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/authorize/TestProxyUsers.java?rev=1605989&r1=1605988&r2=1605989&view=diff
==============================================================================
---
hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/authorize/TestProxyUsers.java
(original)
+++
hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/authorize/TestProxyUsers.java
Fri Jun 27 08:34:15 2014
@@ -21,6 +21,7 @@ import static org.junit.Assert.assertEqu
import static org.junit.Assert.fail;
import java.io.IOException;
+import java.security.SecureRandom;
import java.util.Arrays;
import java.util.Collection;
@@ -50,6 +51,7 @@ public class TestProxyUsers {
private static final String[] SUDO_GROUP_NAMES =
new String[] { "sudo_proxied_user" };
private static final String PROXY_IP = "1.2.3.4";
+ private static final String PROXY_IP_RANGE = "10.222.0.0/16,10.113.221.221";
/**
* Test the netgroups (groups in ACL rules that start with @)
@@ -294,6 +296,29 @@ public class TestProxyUsers {
assertNotAuthorized(proxyUserUgi, "1.2.3.4");
assertNotAuthorized(proxyUserUgi, "1.2.3.5");
}
+
+ @Test
+ public void testIPRange() {
+ Configuration conf = new Configuration();
+ conf.set(
+
DefaultImpersonationProvider.getProxySuperuserGroupConfKey(REAL_USER_NAME),
+ "*");
+ conf.set(
+
DefaultImpersonationProvider.getProxySuperuserIpConfKey(REAL_USER_NAME),
+ PROXY_IP_RANGE);
+ ProxyUsers.refreshSuperUserGroupsConfiguration(conf);
+
+ // First try proxying a group that's allowed
+ UserGroupInformation realUserUgi = UserGroupInformation
+ .createRemoteUser(REAL_USER_NAME);
+ UserGroupInformation proxyUserUgi =
UserGroupInformation.createProxyUserForTesting(
+ PROXY_USER_NAME, realUserUgi, GROUP_NAMES);
+
+ // From good IP
+ assertAuthorized(proxyUserUgi, "10.222.0.0");
+ // From bad IP
+ assertNotAuthorized(proxyUserUgi, "10.221.0.0");
+ }
@Test
public void testWithDuplicateProxyGroups() throws Exception {
@@ -431,4 +456,71 @@ public class TestProxyUsers {
return null;
}
}
+
+ public static void loadTest(String ipString, int testRange) {
+ Configuration conf = new Configuration();
+ conf.set(
+
DefaultImpersonationProvider.getProxySuperuserGroupConfKey(REAL_USER_NAME),
+ StringUtils.join(",", Arrays.asList(GROUP_NAMES)));
+
+ conf.set(
+
DefaultImpersonationProvider.getProxySuperuserIpConfKey(REAL_USER_NAME),
+ ipString
+ );
+ ProxyUsers.refreshSuperUserGroupsConfiguration(conf);
+
+
+ // First try proxying a group that's allowed
+ UserGroupInformation realUserUgi = UserGroupInformation
+ .createRemoteUser(REAL_USER_NAME);
+ UserGroupInformation proxyUserUgi =
UserGroupInformation.createProxyUserForTesting(
+ PROXY_USER_NAME, realUserUgi, GROUP_NAMES);
+
+ long startTime = System.nanoTime();
+ SecureRandom sr = new SecureRandom();
+ for (int i=1; i < 1000000; i++){
+ try {
+ ProxyUsers.authorize(proxyUserUgi, "1.2.3."+ sr.nextInt(testRange));
+ } catch (AuthorizationException e) {
+ }
+ }
+ long stopTime = System.nanoTime();
+ long elapsedTime = stopTime - startTime;
+ System.out.println(elapsedTime/1000000 + " ms");
+ }
+
+ /**
+ * invokes the load Test
+ * A few sample invocations are as below
+ * TestProxyUsers ip 128 256
+ * TestProxyUsers range 1.2.3.0/25 256
+ * TestProxyUsers ip 4 8
+ * TestProxyUsers range 1.2.3.0/30 8
+ * @param args
+ */
+ public static void main (String[] args){
+ String ipValues = null;
+
+ if (args.length != 3 || (!args[0].equals("ip") &&
!args[0].equals("range"))) {
+ System.out.println("Invalid invocation. The right syntax is ip/range
<numberofIps/cidr> <testRange>");
+ }
+ else {
+ if (args[0].equals("ip")){
+ int numberOfIps = Integer.parseInt(args[1]);
+ StringBuilder sb = new StringBuilder();
+ for (int i=0; i < numberOfIps; i++){
+ sb.append("1.2.3."+ i + ",");
+ }
+ ipValues = sb.toString();
+ }
+ else if (args[0].equals("range")){
+ ipValues = args[1];
+ }
+
+ int testRange = Integer.parseInt(args[2]);
+
+ loadTest(ipValues, testRange);
+ }
+ }
+
}