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:
parent
9eb06b31d6
commit
c23cf3cddf
|
@ -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
|
||||||
|
|
|
@ -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));
|
||||||
|
|
||||||
|
|
|
@ -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(),
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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>() {
|
||||||
|
|
Loading…
Reference in New Issue