YARN-961. Changed ContainerManager to enforce Token auth irrespective of security. Contributed by Omkar Vinit Joshi.

git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/trunk@1508216 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Vinod Kumar Vavilapalli 2013-07-29 22:23:29 +00:00
parent 9eb06b31d6
commit c23cf3cddf
5 changed files with 67 additions and 32 deletions

View File

@ -765,6 +765,12 @@ Release 2.1.0-beta - 2013-07-02
YARN-245. Fixed NodeManager to handle duplicate responses from YARN-245. Fixed NodeManager to handle duplicate responses from
ResourceManager. (Mayank Bansal via vinodkv) ResourceManager. (Mayank Bansal via vinodkv)
YARN-932. TestResourceLocalizationService.testLocalizationInit can fail on
JDK7. (Karthik Kambatla via Sandy Ryza)
YARN-961. Changed ContainerManager to enforce Token auth irrespective of
security. (Omkar Vinit Joshi via vinodkv)
BREAKDOWN OF HADOOP-8562/YARN-191 SUBTASKS AND RELATED JIRAS BREAKDOWN OF HADOOP-8562/YARN-191 SUBTASKS AND RELATED JIRAS
YARN-158. Yarn creating package-info.java must not depend on sh. YARN-158. Yarn creating package-info.java must not depend on sh.
@ -830,9 +836,6 @@ Release 2.1.0-beta - 2013-07-02
YARN-909. Disable TestLinuxContainerExecutorWithMocks on Windows. (Chuan Liu YARN-909. Disable TestLinuxContainerExecutorWithMocks on Windows. (Chuan Liu
via cnauroth) via cnauroth)
YARN-932. TestResourceLocalizationService.testLocalizationInit can fail on
JDK7. (Karthik Kambatla via Sandy Ryza)
Release 2.0.5-alpha - 06/06/2013 Release 2.0.5-alpha - 06/06/2013
INCOMPATIBLE CHANGES INCOMPATIBLE CHANGES

View File

@ -40,6 +40,7 @@ import org.apache.hadoop.io.DataInputByteBuffer;
import org.apache.hadoop.ipc.Server; import org.apache.hadoop.ipc.Server;
import org.apache.hadoop.net.NetUtils; import org.apache.hadoop.net.NetUtils;
import org.apache.hadoop.security.Credentials; import org.apache.hadoop.security.Credentials;
import org.apache.hadoop.security.SaslRpcServer;
import org.apache.hadoop.security.UserGroupInformation; import org.apache.hadoop.security.UserGroupInformation;
import org.apache.hadoop.security.authorize.PolicyProvider; import org.apache.hadoop.security.authorize.PolicyProvider;
import org.apache.hadoop.security.token.SecretManager.InvalidToken; import org.apache.hadoop.security.token.SecretManager.InvalidToken;
@ -230,6 +231,13 @@ public class ContainerManagerImpl extends CompositeService implements
// Enqueue user dirs in deletion context // Enqueue user dirs in deletion context
Configuration conf = getConfig(); Configuration conf = getConfig();
Configuration serverConf = new Configuration(conf);
// always enforce it to be token-based.
serverConf.set(
CommonConfigurationKeysPublic.HADOOP_SECURITY_AUTHENTICATION,
SaslRpcServer.AuthMethod.TOKEN.toString());
YarnRPC rpc = YarnRPC.create(conf); YarnRPC rpc = YarnRPC.create(conf);
InetSocketAddress initialAddress = conf.getSocketAddr( InetSocketAddress initialAddress = conf.getSocketAddr(
@ -238,8 +246,8 @@ public class ContainerManagerImpl extends CompositeService implements
YarnConfiguration.DEFAULT_NM_PORT); YarnConfiguration.DEFAULT_NM_PORT);
server = server =
rpc.getServer(ContainerManagementProtocol.class, this, initialAddress, conf, rpc.getServer(ContainerManagementProtocol.class, this, initialAddress,
this.context.getNMTokenSecretManager(), serverConf, this.context.getNMTokenSecretManager(),
conf.getInt(YarnConfiguration.NM_CONTAINER_MGR_THREAD_COUNT, conf.getInt(YarnConfiguration.NM_CONTAINER_MGR_THREAD_COUNT,
YarnConfiguration.DEFAULT_NM_CONTAINER_MGR_THREAD_COUNT)); YarnConfiguration.DEFAULT_NM_CONTAINER_MGR_THREAD_COUNT));

View File

@ -33,6 +33,7 @@ import org.apache.hadoop.classification.InterfaceAudience.Private;
import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.CommonConfigurationKeysPublic; import org.apache.hadoop.fs.CommonConfigurationKeysPublic;
import org.apache.hadoop.ipc.Server; import org.apache.hadoop.ipc.Server;
import org.apache.hadoop.security.SaslRpcServer;
import org.apache.hadoop.security.UserGroupInformation; import org.apache.hadoop.security.UserGroupInformation;
import org.apache.hadoop.security.authorize.PolicyProvider; import org.apache.hadoop.security.authorize.PolicyProvider;
import org.apache.hadoop.security.token.TokenIdentifier; import org.apache.hadoop.security.token.TokenIdentifier;
@ -119,12 +120,11 @@ public class ApplicationMasterService extends AbstractService implements
YarnConfiguration.DEFAULT_RM_SCHEDULER_PORT); YarnConfiguration.DEFAULT_RM_SCHEDULER_PORT);
Configuration serverConf = conf; Configuration serverConf = conf;
if (!UserGroupInformation.isSecurityEnabled()) { // If the auth is not-simple, enforce it to be token-based.
// If the auth is not-simple, enforce it to be token-based. serverConf = new Configuration(conf);
serverConf = new Configuration(conf); serverConf.set(
serverConf.set(CommonConfigurationKeysPublic.HADOOP_SECURITY_AUTHENTICATION, CommonConfigurationKeysPublic.HADOOP_SECURITY_AUTHENTICATION,
UserGroupInformation.AuthenticationMethod.TOKEN.toString()); SaslRpcServer.AuthMethod.TOKEN.toString());
}
this.server = this.server =
rpc.getServer(ApplicationMasterProtocol.class, this, masterServiceAddress, rpc.getServer(ApplicationMasterProtocol.class, this, masterServiceAddress,
serverConf, this.rmContext.getAMRMTokenSecretManager(), serverConf, this.rmContext.getAMRMTokenSecretManager(),

View File

@ -253,15 +253,14 @@ public class TestAMAuthorization {
} catch (Exception e) { } catch (Exception e) {
// Because there are no tokens, the request should be rejected as the // Because there are no tokens, the request should be rejected as the
// server side will assume we are trying simple auth. // server side will assume we are trying simple auth.
String availableAuthMethods; String expectedMessage = "";
if (UserGroupInformation.isSecurityEnabled()) { if (UserGroupInformation.isSecurityEnabled()) {
availableAuthMethods = "[TOKEN, KERBEROS]"; expectedMessage = "Client cannot authenticate via:[TOKEN]";
} else { } else {
availableAuthMethods = "[TOKEN]"; expectedMessage =
"SIMPLE authentication is not enabled. Available:[TOKEN]";
} }
Assert.assertTrue(e.getCause().getMessage().contains( Assert.assertTrue(e.getCause().getMessage().contains(expectedMessage));
"SIMPLE authentication is not enabled. "
+ "Available:" + availableAuthMethods));
} }
// TODO: Add validation of invalid authorization when there's more data in // TODO: Add validation of invalid authorization when there's more data in

View File

@ -24,6 +24,8 @@ import java.io.IOException;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.security.PrivilegedAction; import java.security.PrivilegedAction;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List; import java.util.List;
import junit.framework.Assert; import junit.framework.Assert;
@ -63,7 +65,11 @@ import org.apache.hadoop.yarn.server.resourcemanager.security.RMContainerTokenSe
import org.apache.hadoop.yarn.util.ConverterUtils; import org.apache.hadoop.yarn.util.ConverterUtils;
import org.apache.hadoop.yarn.util.Records; import org.apache.hadoop.yarn.util.Records;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
@RunWith(Parameterized.class)
public class TestContainerManagerSecurity { public class TestContainerManagerSecurity {
static Log LOG = LogFactory.getLog(TestContainerManagerSecurity.class); static Log LOG = LogFactory.getLog(TestContainerManagerSecurity.class);
@ -71,28 +77,33 @@ public class TestContainerManagerSecurity {
.getRecordFactory(null); .getRecordFactory(null);
private static MiniYARNCluster yarnCluster; private static MiniYARNCluster yarnCluster;
static final Configuration conf = new Configuration(); private Configuration conf;
@Parameters
public static Collection<Object[]> configs() {
Configuration configurationWithoutSecurity = new Configuration();
configurationWithoutSecurity.set(
CommonConfigurationKeysPublic.HADOOP_SECURITY_AUTHENTICATION, "simple");
Configuration configurationWithSecurity = new Configuration();
configurationWithSecurity.set(
CommonConfigurationKeysPublic.HADOOP_SECURITY_AUTHENTICATION,
"kerberos");
return Arrays.asList(new Object[][] { { configurationWithoutSecurity },
{ configurationWithSecurity } });
}
public TestContainerManagerSecurity(Configuration conf) {
conf.setLong(YarnConfiguration.RM_AM_EXPIRY_INTERVAL_MS, 100000L);
UserGroupInformation.setConfiguration(conf);
this.conf = conf;
}
@Test (timeout = 1000000) @Test (timeout = 1000000)
public void testContainerManagerWithSecurityEnabled() throws Exception { public void testContainerManager() throws Exception {
conf.set(CommonConfigurationKeysPublic.HADOOP_SECURITY_AUTHENTICATION,
"kerberos");
testContainerManager();
}
@Test (timeout=1000000)
public void testContainerManagerWithSecurityDisabled() throws Exception {
conf.set(CommonConfigurationKeysPublic.HADOOP_SECURITY_AUTHENTICATION,
"simple");
testContainerManager();
}
private void testContainerManager() throws Exception {
try { try {
yarnCluster = new MiniYARNCluster(TestContainerManagerSecurity.class yarnCluster = new MiniYARNCluster(TestContainerManagerSecurity.class
.getName(), 1, 1, 1); .getName(), 1, 1, 1);
conf.setLong(YarnConfiguration.RM_AM_EXPIRY_INTERVAL_MS, 100000L);
UserGroupInformation.setConfiguration(conf);
yarnCluster.init(conf); yarnCluster.init(conf);
yarnCluster.start(); yarnCluster.start();
@ -184,6 +195,18 @@ public class TestContainerManagerSecurity {
} while (tempManager.getCurrentKey().getKeyId() == nmTokenSecretManagerRM } while (tempManager.getCurrentKey().getKeyId() == nmTokenSecretManagerRM
.getCurrentKey().getKeyId()); .getCurrentKey().getKeyId());
// Testing that NM rejects the requests when we don't send any token.
if (UserGroupInformation.isSecurityEnabled()) {
sb = new StringBuilder("Client cannot authenticate via:[TOKEN]");
} else {
sb =
new StringBuilder(
"SIMPLE authentication is not enabled. Available:[TOKEN]");
}
String errorMsg = testStartContainer(rpc, validAppAttemptId, validNode,
validContainerToken, null, true);
Assert.assertTrue(errorMsg.contains(sb.toString()));
org.apache.hadoop.yarn.api.records.Token invalidNMToken = org.apache.hadoop.yarn.api.records.Token invalidNMToken =
tempManager.createNMToken(validAppAttemptId, validNode, user); tempManager.createNMToken(validAppAttemptId, validNode, user);
sb = new StringBuilder("Given NMToken for application : "); sb = new StringBuilder("Given NMToken for application : ");
@ -402,7 +425,9 @@ public class TestContainerManagerSecurity {
UserGroupInformation ugi = UserGroupInformation.createRemoteUser(user); UserGroupInformation ugi = UserGroupInformation.createRemoteUser(user);
final InetSocketAddress addr = final InetSocketAddress addr =
NetUtils.createSocketAddr(nodeId.getHost(), nodeId.getPort()); NetUtils.createSocketAddr(nodeId.getHost(), nodeId.getPort());
ugi.addToken(ConverterUtils.convertFromYarn(nmToken, addr)); if (nmToken != null) {
ugi.addToken(ConverterUtils.convertFromYarn(nmToken, addr));
}
proxy = ugi proxy = ugi
.doAs(new PrivilegedAction<ContainerManagementProtocol>() { .doAs(new PrivilegedAction<ContainerManagementProtocol>() {