SLIDER-1027 kdiag adds validation that user has kerberos credentials; doesn't fail on an insecure cluster, and adds a kdiagIT test to verify the kerberos bindings for the IT Test run
Project: http://git-wip-us.apache.org/repos/asf/incubator-slider/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-slider/commit/819b127e Tree: http://git-wip-us.apache.org/repos/asf/incubator-slider/tree/819b127e Diff: http://git-wip-us.apache.org/repos/asf/incubator-slider/diff/819b127e Branch: refs/heads/develop Commit: 819b127e49fdadd832f6289b05b31fd98e1cee58 Parents: a36b25d Author: Steve Loughran <ste...@apache.org> Authored: Wed Dec 16 16:27:31 2015 +0000 Committer: Steve Loughran <ste...@apache.org> Committed: Wed Dec 16 16:30:17 2015 +0000 ---------------------------------------------------------------------- .../apache/hadoop/security/KerberosDiags.java | 46 ++++++++++++++----- .../org/apache/slider/common/Constants.java | 11 +++++ .../funtest/framework/CommandTestBase.groovy | 10 +++++ .../funtest/framework/FuntestProperties.groovy | 2 +- .../slider/funtest/framework/SliderShell.groovy | 9 ++++ .../funtest/commands/KDiagCommandIT.groovy | 47 ++++++++++++++++++++ 6 files changed, 113 insertions(+), 12 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/819b127e/slider-core/src/main/java/org/apache/hadoop/security/KerberosDiags.java ---------------------------------------------------------------------- diff --git a/slider-core/src/main/java/org/apache/hadoop/security/KerberosDiags.java b/slider-core/src/main/java/org/apache/hadoop/security/KerberosDiags.java index 3d12857..93b09a7 100644 --- a/slider-core/src/main/java/org/apache/hadoop/security/KerberosDiags.java +++ b/slider-core/src/main/java/org/apache/hadoop/security/KerberosDiags.java @@ -54,7 +54,7 @@ import static org.apache.hadoop.fs.CommonConfigurationKeysPublic.*; */ public class KerberosDiags implements Closeable { - private static final Logger LOG= LoggerFactory.getLogger(KerberosDiags.class); + private static final Logger LOG = LoggerFactory.getLogger(KerberosDiags.class); public static final String KRB5_CCNAME = "KRB5CCNAME"; public static final String JAVA_SECURITY_KRB5_CONF = "java.security.krb5.conf"; @@ -102,6 +102,7 @@ public class KerberosDiags implements Closeable { private void title(String format, Object... args) { println(""); + println(""); println(format, args); println(""); } @@ -136,14 +137,20 @@ public class KerberosDiags implements Closeable { * <li>A way to enable JAAS debug programatically</li> * <li>Acess to the TGT</li> * </ol> - * @throws Exception + * @return true if security was enabled and all probes were successful + * @throws KerberosDiagsFailure explicitly raised failure + * @throws Exception other security problems */ - public void execute() throws Exception { + @SuppressWarnings("deprecation") + public boolean execute() throws Exception { title("Kerberos Diagnostics scan at %s", new Date(System.currentTimeMillis())); boolean securityDisabled = SecurityUtil.getAuthenticationMethod(conf) .equals(UserGroupInformation.AuthenticationMethod.SIMPLE); - failif(securityDisabled, "security disabled"); + if(securityDisabled) { + println("security disabled"); + return false; + } title("System Properties"); for (String prop : new String[]{ JAVA_SECURITY_KRB5_CONF, @@ -179,11 +186,15 @@ public class KerberosDiags implements Closeable { printConfOpt(prop); } - System.setProperty("sun.security.krb5.debug", "true"); - System.setProperty("sun.security.spnego.debug", "true"); + System.setProperty(SUN_SECURITY_KRB5_DEBUG, "true"); + System.setProperty(SUN_SECURITY_SPNEGO_DEBUG, "true"); title("Logging in"); - dumpUser("Log in user", getLoginUser()); + UserGroupInformation loginUser = getLoginUser(); + dumpUser("Log in user", loginUser); + println("Ticket based login: %b", isLoginTicketBased()); + println("Keytab based login: %b", isLoginKeytabBased()); + validateUser("Login user", loginUser); // locate KDC and dump it if (!Shell.WINDOWS) { @@ -225,6 +236,8 @@ public class KerberosDiags implements Closeable { failif(StringUtils.isEmpty(principal), "No principal defined"); ugi = loginUserFromKeytabAndReturnUGI(principal, kt.getPath()); dumpUser(identity, ugi); + validateUser(principal, ugi); + title("Attempting to log in from keytab again"); // package scoped -hence the reason why this class must be in the // hadoop.security package @@ -234,14 +247,18 @@ public class KerberosDiags implements Closeable { // dumpUser("Updated User", ugi); } else { println("No keytab: logging is as current user"); - ugi = getLoginUser(); - identity = "Login User"; } + return true; } - private void dumpUser(String message, UserGroupInformation ugi) { + private void dumpUser(String message, UserGroupInformation ugi) + throws IOException { title(message); println("UGI=%s", ugi); + println("Has kerberos credentials: %b", ugi.hasKerberosCredentials()); + println("Authentication method: %s", ugi.getAuthenticationMethod()); + println("Real Authentication method: %s", + ugi.getRealAuthenticationMethod()); title("Group names"); for (String name : ugi.getGroupNames()) { println(name); @@ -270,6 +287,13 @@ public class KerberosDiags implements Closeable { } } + private void validateUser(String message, UserGroupInformation user) { + failif(!user.hasKerberosCredentials(), + "%s: No kerberos credentials for %s", message, user); + failif(user.getAuthenticationMethod() == null, + "%s: Null AuthenticationMethod for %s", message, user); + } + private void fail(String message, Object... args) throws KerberosDiagsFailure { throw new KerberosDiagsFailure(message, args); @@ -278,7 +302,7 @@ public class KerberosDiags implements Closeable { private void failif(boolean condition, String message, Object... args) throws KerberosDiagsFailure { if (condition) { - throw new KerberosDiagsFailure(message, args); + fail(message, args); } } http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/819b127e/slider-core/src/main/java/org/apache/slider/common/Constants.java ---------------------------------------------------------------------- diff --git a/slider-core/src/main/java/org/apache/slider/common/Constants.java b/slider-core/src/main/java/org/apache/slider/common/Constants.java index 868ea57..fdb3452 100644 --- a/slider-core/src/main/java/org/apache/slider/common/Constants.java +++ b/slider-core/src/main/java/org/apache/slider/common/Constants.java @@ -21,4 +21,15 @@ package org.apache.slider.common; public class Constants { public static final int CONNECT_TIMEOUT = 10000; public static final int RPC_TIMEOUT = 15000; + + public static final String ENV_JAAS_DEBUG = "HADOOP_JAAS_DEBUG"; + public static final String KRB5_CCNAME = "KRB5CCNAME"; + public static final String JAVA_SECURITY_KRB5_CONF + = "java.security.krb5.conf"; + public static final String JAVA_SECURITY_KRB5_REALM + = "java.security.krb5.realm"; + public static final String SUN_SECURITY_KRB5_DEBUG + = "sun.security.krb5.debug"; + public static final String SUN_SECURITY_SPNEGO_DEBUG + = "sun.security.spnego.debug"; } http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/819b127e/slider-funtest/src/main/groovy/org/apache/slider/funtest/framework/CommandTestBase.groovy ---------------------------------------------------------------------- diff --git a/slider-funtest/src/main/groovy/org/apache/slider/funtest/framework/CommandTestBase.groovy b/slider-funtest/src/main/groovy/org/apache/slider/funtest/framework/CommandTestBase.groovy index 5fa4c2a..46fefff 100644 --- a/slider-funtest/src/main/groovy/org/apache/slider/funtest/framework/CommandTestBase.groovy +++ b/slider-funtest/src/main/groovy/org/apache/slider/funtest/framework/CommandTestBase.groovy @@ -238,6 +238,16 @@ abstract class CommandTestBase extends SliderTestUtils { } /** + * used enough in setting properties it's worth pulling out + * @param key sysprop/conf definition + * @param val value + * @return the concatenated string + */ + static String define(String key, String val) { + key + "=" + val + } + + /** * Print to system out * @param string */ http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/819b127e/slider-funtest/src/main/groovy/org/apache/slider/funtest/framework/FuntestProperties.groovy ---------------------------------------------------------------------- diff --git a/slider-funtest/src/main/groovy/org/apache/slider/funtest/framework/FuntestProperties.groovy b/slider-funtest/src/main/groovy/org/apache/slider/funtest/framework/FuntestProperties.groovy index 3bc9263..200da80 100644 --- a/slider-funtest/src/main/groovy/org/apache/slider/funtest/framework/FuntestProperties.groovy +++ b/slider-funtest/src/main/groovy/org/apache/slider/funtest/framework/FuntestProperties.groovy @@ -53,7 +53,7 @@ public interface FuntestProperties extends SliderXMLConfKeysForTesting { String ENV_SLIDER_CONF_DIR = "SLIDER_CONF_DIR" String ENV_HADOOP_CONF_DIR = "HADOOP_CONF_DIR" String ENV_SLIDER_CLASSPATH_EXTRA = "SLIDER_CLASSPATH_EXTRA" - + String SCRIPT_NAME = "slider" String KEY_TEST_CONF_XML = "slider.test.conf.xml" String KEY_TEST_CONF_DIR = "slider.test.conf.dir" http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/819b127e/slider-funtest/src/main/groovy/org/apache/slider/funtest/framework/SliderShell.groovy ---------------------------------------------------------------------- diff --git a/slider-funtest/src/main/groovy/org/apache/slider/funtest/framework/SliderShell.groovy b/slider-funtest/src/main/groovy/org/apache/slider/funtest/framework/SliderShell.groovy index 9270e8c..b25264a 100644 --- a/slider-funtest/src/main/groovy/org/apache/slider/funtest/framework/SliderShell.groovy +++ b/slider-funtest/src/main/groovy/org/apache/slider/funtest/framework/SliderShell.groovy @@ -55,6 +55,15 @@ class SliderShell extends ShellBase { } /** + * Build the command + * @param commands + * @param map of environment variables to set + */ + SliderShell(Collection<String> commands, Map<String, String> env) { + this(commands) + env.entrySet().each { setEnv(it.key, it.value)} + } + /** * Exec any slider command * @param conf * @param commands http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/819b127e/slider-funtest/src/test/groovy/org/apache/slider/funtest/commands/KDiagCommandIT.groovy ---------------------------------------------------------------------- diff --git a/slider-funtest/src/test/groovy/org/apache/slider/funtest/commands/KDiagCommandIT.groovy b/slider-funtest/src/test/groovy/org/apache/slider/funtest/commands/KDiagCommandIT.groovy new file mode 100644 index 0000000..8d05df6 --- /dev/null +++ b/slider-funtest/src/test/groovy/org/apache/slider/funtest/commands/KDiagCommandIT.groovy @@ -0,0 +1,47 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.slider.funtest.commands + +import groovy.transform.CompileStatic +import groovy.util.logging.Slf4j +import org.apache.slider.common.params.Arguments +import org.apache.slider.common.params.SliderActions +import org.apache.slider.funtest.framework.CommandTestBase +import org.apache.slider.funtest.framework.SliderShell +import org.junit.Test +import static org.apache.slider.common.Constants.* + +@CompileStatic +@Slf4j +public class KDiagCommandIT extends CommandTestBase implements Arguments { + + @Test + public void testKdiag() throws Throwable { + SliderShell shell = new SliderShell([ + SliderActions.ACTION_KDIAG, + ARG_FAIL, + ARG_SYSPROP, define(SUN_SECURITY_KRB5_DEBUG, "true") + ], + [(ENV_JAAS_DEBUG): "true"] + ) + shell.execute() + assertSuccess(shell) + } + +}