HDDS-5. Enable OzoneManager kerberos auth. Contributed by Ajay Kumar.
Project: http://git-wip-us.apache.org/repos/asf/hadoop/repo Commit: http://git-wip-us.apache.org/repos/asf/hadoop/commit/1e95b5de Tree: http://git-wip-us.apache.org/repos/asf/hadoop/tree/1e95b5de Diff: http://git-wip-us.apache.org/repos/asf/hadoop/diff/1e95b5de Branch: refs/heads/HDDS-4 Commit: 1e95b5def78d6b61ad2b1e7053a27bb99ee5822c Parents: 998df5a Author: Xiaoyu Yao <x...@apache.org> Authored: Mon May 14 09:36:57 2018 -0700 Committer: Xiaoyu Yao <x...@apache.org> Committed: Tue May 15 16:55:52 2018 -0700 ---------------------------------------------------------------------- .../org/apache/hadoop/hdds/HddsConfigKeys.java | 4 + .../common/src/main/resources/ozone-default.xml | 33 +++- .../apache/hadoop/ozone/ksm/KSMConfigKeys.java | 5 + .../ksm/protocol/KeySpaceManagerProtocol.java | 4 + .../protocolPB/KeySpaceManagerProtocolPB.java | 5 + .../hadoop/ozone/MiniOzoneClusterImpl.java | 3 +- .../ozone/TestOzoneConfigurationFields.java | 3 +- .../hadoop/ozone/TestSecureOzoneCluster.java | 169 +++++++++++++++---- .../hadoop/ozone/ksm/KeySpaceManager.java | 53 +++++- .../ozone/ksm/KeySpaceManagerHttpServer.java | 5 +- 10 files changed, 238 insertions(+), 46 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/hadoop/blob/1e95b5de/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/HddsConfigKeys.java ---------------------------------------------------------------------- diff --git a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/HddsConfigKeys.java b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/HddsConfigKeys.java index dec2c1c..a12d6ac 100644 --- a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/HddsConfigKeys.java +++ b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/HddsConfigKeys.java @@ -20,4 +20,8 @@ package org.apache.hadoop.hdds; public final class HddsConfigKeys { private HddsConfigKeys() { } + public static final String HDDS_KSM_KERBEROS_KEYTAB_FILE_KEY = "hdds.ksm." + + "kerberos.keytab.file"; + public static final String HDDS_KSM_KERBEROS_PRINCIPAL_KEY = "hdds.ksm" + + ".kerberos.principal"; } http://git-wip-us.apache.org/repos/asf/hadoop/blob/1e95b5de/hadoop-hdds/common/src/main/resources/ozone-default.xml ---------------------------------------------------------------------- diff --git a/hadoop-hdds/common/src/main/resources/ozone-default.xml b/hadoop-hdds/common/src/main/resources/ozone-default.xml index 46c67fd..deb286d 100644 --- a/hadoop-hdds/common/src/main/resources/ozone-default.xml +++ b/hadoop-hdds/common/src/main/resources/ozone-default.xml @@ -1071,7 +1071,23 @@ <name>ozone.scm.kerberos.principal</name> <value></value> <tag> OZONE, SECURITY</tag> - <description>The SCM service principal. Ex scm/_h...@realm.tld.</description> + <description>The SCM service principal. Ex scm/_h...@realm.com</description> + </property> + + <property> + <name>hdds.ksm.kerberos.keytab.file</name> + <value></value> + <tag> HDDS, SECURITY</tag> + <description> The keytab file used by KSM daemon to login as its + service principal. The principal name is configured with + hdds.ksm.kerberos.principal. + </description> + </property> + <property> + <name>hdds.ksm.kerberos.principal</name> + <value></value> + <tag> HDDS, SECURITY</tag> + <description>The KSM service principal. Ex ksm/_h...@realm.com</description> </property> <property> @@ -1083,4 +1099,19 @@ <value>/etc/security/keytabs/HTTP.keytab</value> </property> + <property> + <name>hdds.ksm.web.authentication.kerberos.principal</name> + <value>HTTP/_h...@example.com</value> + <description> + KSM http server kerberos principal. + </description> + </property> + <property> + <name>hdds.ksm.web.authentication.kerberos.keytab</name> + <value>/etc/security/keytabs/HTTP.keytab</value> + <description> + KSM http server kerberos keytab. + </description> + </property> + </configuration> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/hadoop/blob/1e95b5de/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/ksm/KSMConfigKeys.java ---------------------------------------------------------------------- diff --git a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/ksm/KSMConfigKeys.java b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/ksm/KSMConfigKeys.java index 75cf613..d911bcb 100644 --- a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/ksm/KSMConfigKeys.java +++ b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/ksm/KSMConfigKeys.java @@ -78,4 +78,9 @@ public final class KSMConfigKeys { public static final String OZONE_KEY_DELETING_LIMIT_PER_TASK = "ozone.key.deleting.limit.per.task"; public static final int OZONE_KEY_DELETING_LIMIT_PER_TASK_DEFAULT = 1000; + + public static final String KSM_WEB_AUTHENTICATION_KERBEROS_PRINCIPAL = + "hdds.ksm.web.authentication.kerberos.principal"; + public static final String KSM_WEB_AUTHENTICATION_KERBEROS_KEYTAB_FILE = + "hdds.ksm.web.authentication.kerberos.keytab"; } http://git-wip-us.apache.org/repos/asf/hadoop/blob/1e95b5de/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/ksm/protocol/KeySpaceManagerProtocol.java ---------------------------------------------------------------------- diff --git a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/ksm/protocol/KeySpaceManagerProtocol.java b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/ksm/protocol/KeySpaceManagerProtocol.java index 54862d3..de27108 100644 --- a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/ksm/protocol/KeySpaceManagerProtocol.java +++ b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/ksm/protocol/KeySpaceManagerProtocol.java @@ -17,6 +17,7 @@ */ package org.apache.hadoop.ozone.ksm.protocol; +import org.apache.hadoop.hdds.HddsConfigKeys; import org.apache.hadoop.ozone.ksm.helpers.KsmBucketArgs; import org.apache.hadoop.ozone.ksm.helpers.KsmBucketInfo; import org.apache.hadoop.ozone.ksm.helpers.KsmKeyArgs; @@ -29,10 +30,13 @@ import org.apache.hadoop.ozone.protocol.proto .KeySpaceManagerProtocolProtos.OzoneAclInfo; import java.io.IOException; import java.util.List; +import org.apache.hadoop.security.KerberosInfo; /** * Protocol to talk to KSM. */ +@KerberosInfo( + serverPrincipal = HddsConfigKeys.HDDS_KSM_KERBEROS_PRINCIPAL_KEY) public interface KeySpaceManagerProtocol { /** http://git-wip-us.apache.org/repos/asf/hadoop/blob/1e95b5de/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/ksm/protocolPB/KeySpaceManagerProtocolPB.java ---------------------------------------------------------------------- diff --git a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/ksm/protocolPB/KeySpaceManagerProtocolPB.java b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/ksm/protocolPB/KeySpaceManagerProtocolPB.java index 8acca8a..71b9da0 100644 --- a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/ksm/protocolPB/KeySpaceManagerProtocolPB.java +++ b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/ksm/protocolPB/KeySpaceManagerProtocolPB.java @@ -18,9 +18,12 @@ package org.apache.hadoop.ozone.ksm.protocolPB; import org.apache.hadoop.classification.InterfaceAudience; +import org.apache.hadoop.hdds.HddsConfigKeys; import org.apache.hadoop.ipc.ProtocolInfo; +import org.apache.hadoop.ozone.OzoneConfigKeys; import org.apache.hadoop.ozone.protocol.proto .KeySpaceManagerProtocolProtos.KeySpaceManagerService; +import org.apache.hadoop.security.KerberosInfo; /** * Protocol used to communicate with KSM. @@ -28,6 +31,8 @@ import org.apache.hadoop.ozone.protocol.proto @ProtocolInfo(protocolName = "org.apache.hadoop.ozone.protocol.KeySpaceManagerProtocol", protocolVersion = 1) +@KerberosInfo( + serverPrincipal = HddsConfigKeys.HDDS_KSM_KERBEROS_PRINCIPAL_KEY) @InterfaceAudience.Private public interface KeySpaceManagerProtocolPB extends KeySpaceManagerService.BlockingInterface { http://git-wip-us.apache.org/repos/asf/hadoop/blob/1e95b5de/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/MiniOzoneClusterImpl.java ---------------------------------------------------------------------- diff --git a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/MiniOzoneClusterImpl.java b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/MiniOzoneClusterImpl.java index e4f8e62..b837100 100644 --- a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/MiniOzoneClusterImpl.java +++ b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/MiniOzoneClusterImpl.java @@ -344,7 +344,8 @@ public final class MiniOzoneClusterImpl implements MiniOzoneCluster { * * @throws IOException */ - private KeySpaceManager createKSM() throws IOException { + private KeySpaceManager createKSM() + throws IOException, AuthenticationException { configureKSM(); KSMStorage ksmStore = new KSMStorage(conf); ksmStore.setClusterId(clusterId); http://git-wip-us.apache.org/repos/asf/hadoop/blob/1e95b5de/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/TestOzoneConfigurationFields.java ---------------------------------------------------------------------- diff --git a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/TestOzoneConfigurationFields.java b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/TestOzoneConfigurationFields.java index 533a3b4..a1d3fd0 100644 --- a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/TestOzoneConfigurationFields.java +++ b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/TestOzoneConfigurationFields.java @@ -18,6 +18,7 @@ package org.apache.hadoop.ozone; import org.apache.hadoop.conf.TestConfigurationFieldsBase; +import org.apache.hadoop.hdds.HddsConfigKeys; import org.apache.hadoop.ozone.ksm.KSMConfigKeys; import org.apache.hadoop.hdds.scm.ScmConfigKeys; @@ -31,7 +32,7 @@ public class TestOzoneConfigurationFields extends TestConfigurationFieldsBase { xmlFilename = new String("ozone-default.xml"); configurationClasses = new Class[] {OzoneConfigKeys.class, ScmConfigKeys.class, - KSMConfigKeys.class}; + KSMConfigKeys.class, HddsConfigKeys.class}; errorIfMissingConfigProps = true; errorIfMissingXmlProps = true; } http://git-wip-us.apache.org/repos/asf/hadoop/blob/1e95b5de/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/TestSecureOzoneCluster.java ---------------------------------------------------------------------- diff --git a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/TestSecureOzoneCluster.java b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/TestSecureOzoneCluster.java index 9c430ad..b917dfe 100644 --- a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/TestSecureOzoneCluster.java +++ b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/TestSecureOzoneCluster.java @@ -26,24 +26,34 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.util.Properties; import java.util.UUID; +import java.util.concurrent.Callable; import org.apache.hadoop.classification.InterfaceAudience; import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.fs.CommonConfigurationKeys; import org.apache.hadoop.fs.CommonConfigurationKeysPublic; +import org.apache.hadoop.hdds.HddsConfigKeys; import org.apache.hadoop.hdds.conf.OzoneConfiguration; import org.apache.hadoop.hdds.scm.ScmConfigKeys; import org.apache.hadoop.hdds.scm.ScmInfo; import org.apache.hadoop.hdds.scm.server.SCMStorage; import org.apache.hadoop.hdds.scm.server.StorageContainerManager; import org.apache.hadoop.minikdc.MiniKdc; +import org.apache.hadoop.ozone.ksm.KSMConfigKeys; +import org.apache.hadoop.ozone.ksm.KSMStorage; +import org.apache.hadoop.ozone.ksm.KeySpaceManager; import org.apache.hadoop.security.KerberosAuthException; import org.apache.hadoop.security.UserGroupInformation; import org.apache.hadoop.security.authentication.client.AuthenticationException; import org.apache.hadoop.security.authentication.util.KerberosUtil; import org.apache.hadoop.test.GenericTestUtils; +import org.apache.hadoop.test.GenericTestUtils.LogCapturer; import org.apache.hadoop.test.LambdaTestUtils; +import org.junit.After; import org.junit.Assert; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.Timeout; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -56,13 +66,23 @@ public final class TestSecureOzoneCluster { private Logger LOGGER = LoggerFactory .getLogger(TestSecureOzoneCluster.class); + @Rule + public Timeout timeout = new Timeout(80000); + private MiniKdc miniKdc; private OzoneConfiguration conf; private File workDir; private static Properties securityProperties; private File scmKeytab; private File spnegoKeytab; + private File ksmKeyTab; private String curUser; + private StorageContainerManager scm; + private KeySpaceManager ksm; + + private static String clusterId; + private static String scmId; + private static String ksmId; @Before public void init() { @@ -71,6 +91,10 @@ public final class TestSecureOzoneCluster { startMiniKdc(); setSecureConfig(conf); createCredentialsInKDC(conf, miniKdc); + + clusterId = UUID.randomUUID().toString(); + scmId = UUID.randomUUID().toString(); + ksmId = UUID.randomUUID().toString(); } catch (IOException e) { LOGGER.error("Failed to initialize TestSecureOzoneCluster", e); } catch (Exception e) { @@ -78,12 +102,30 @@ public final class TestSecureOzoneCluster { } } + @After + public void stop() { + try { + stopMiniKdc(); + if (scm != null) { + scm.stop(); + } + if (ksm != null) { + ksm.stop(); + } + } catch (Exception e) { + LOGGER.error("Failed to stop TestSecureOzoneCluster", e); + } + } + private void createCredentialsInKDC(Configuration conf, MiniKdc miniKdc) throws Exception { createPrincipal(scmKeytab, conf.get(ScmConfigKeys.OZONE_SCM_KERBEROS_PRINCIPAL_KEY)); createPrincipal(spnegoKeytab, - conf.get(ScmConfigKeys.SCM_WEB_AUTHENTICATION_KERBEROS_PRINCIPAL_KEY)); + conf.get(ScmConfigKeys.SCM_WEB_AUTHENTICATION_KERBEROS_PRINCIPAL_KEY), + conf.get(KSMConfigKeys.KSM_WEB_AUTHENTICATION_KERBEROS_PRINCIPAL)); + createPrincipal(ksmKeyTab, + conf.get(HddsConfigKeys.HDDS_KSM_KERBEROS_PRINCIPAL_KEY)); } private void createPrincipal(File keytab, String... principal) @@ -99,6 +141,10 @@ public final class TestSecureOzoneCluster { miniKdc.start(); } + private void stopMiniKdc() throws Exception { + miniKdc.stop(); + } + private void setSecureConfig(Configuration conf) throws IOException { conf.setBoolean(OZONE_SECURITY_ENABLED_KEY, true); String host = KerberosUtil.getLocalHostName(); @@ -114,59 +160,56 @@ public final class TestSecureOzoneCluster { conf.set(ScmConfigKeys.SCM_WEB_AUTHENTICATION_KERBEROS_PRINCIPAL_KEY, "HTTP_SCM/" + host + "@" + realm); + conf.set(HddsConfigKeys.HDDS_KSM_KERBEROS_PRINCIPAL_KEY, + "ksm/" + host + "@" + realm); + conf.set(KSMConfigKeys.KSM_WEB_AUTHENTICATION_KERBEROS_PRINCIPAL, + "HTTP_KSM/" + host + "@" + realm); + scmKeytab = new File(workDir, "scm.keytab"); spnegoKeytab = new File(workDir, "http.keytab"); + ksmKeyTab = new File(workDir, "ksm.keytab"); conf.set(ScmConfigKeys.OZONE_SCM_KERBEROS_KEYTAB_FILE_KEY, scmKeytab.getAbsolutePath()); conf.set(ScmConfigKeys.SCM_WEB_AUTHENTICATION_KERBEROS_KEYTAB_FILE_KEY, spnegoKeytab.getAbsolutePath()); + conf.set(HddsConfigKeys.HDDS_KSM_KERBEROS_KEYTAB_FILE_KEY, + ksmKeyTab.getAbsolutePath()); } @Test public void testSecureScmStartupSuccess() throws Exception { + + initSCM(); + scm = StorageContainerManager.createSCM(null, conf); + //Reads the SCM Info from SCM instance + ScmInfo scmInfo = scm.getClientProtocolServer().getScmInfo(); + Assert.assertEquals(clusterId, scmInfo.getClusterId()); + Assert.assertEquals(scmId, scmInfo.getScmId()); + } + + private void initSCM() + throws IOException, AuthenticationException { final String path = GenericTestUtils .getTempPath(UUID.randomUUID().toString()); Path scmPath = Paths.get(path, "scm-meta"); conf.set(OzoneConfigKeys.OZONE_METADATA_DIRS, scmPath.toString()); conf.setBoolean(OzoneConfigKeys.OZONE_ENABLED, true); SCMStorage scmStore = new SCMStorage(conf); - String clusterId = UUID.randomUUID().toString(); - String scmId = UUID.randomUUID().toString(); scmStore.setClusterId(clusterId); scmStore.setScmId(scmId); // writes the version file properties scmStore.initialize(); - StorageContainerManager scm = StorageContainerManager.createSCM(null, conf); - //Reads the SCM Info from SCM instance - ScmInfo scmInfo = scm.getClientProtocolServer().getScmInfo(); - Assert.assertEquals(clusterId, scmInfo.getClusterId()); - Assert.assertEquals(scmId, scmInfo.getScmId()); } @Test public void testSecureScmStartupFailure() throws Exception { - final String path = GenericTestUtils - .getTempPath(UUID.randomUUID().toString()); - Path scmPath = Paths.get(path, "scm-meta"); - - OzoneConfiguration conf = new OzoneConfiguration(); - conf.setBoolean(OZONE_SECURITY_ENABLED_KEY, true); - conf.set(OzoneConfigKeys.OZONE_METADATA_DIRS, scmPath.toString()); - conf.setBoolean(OzoneConfigKeys.OZONE_ENABLED, true); - conf.set(ScmConfigKeys.OZONE_SCM_KERBEROS_PRINCIPAL_KEY, - "scm@" + miniKdc.getRealm()); + initSCM(); + conf.set(ScmConfigKeys.OZONE_SCM_KERBEROS_KEYTAB_FILE_KEY, ""); conf.set(CommonConfigurationKeysPublic.HADOOP_SECURITY_AUTHENTICATION, "kerberos"); - SCMStorage scmStore = new SCMStorage(conf); - String clusterId = UUID.randomUUID().toString(); - String scmId = UUID.randomUUID().toString(); - scmStore.setClusterId(clusterId); - scmStore.setScmId(scmId); - // writes the version file properties - scmStore.initialize(); LambdaTestUtils.intercept(IOException.class, "Running in secure mode, but config doesn't have a keytab", () -> { @@ -178,28 +221,82 @@ public final class TestSecureOzoneCluster { conf.set(ScmConfigKeys.OZONE_SCM_KERBEROS_KEYTAB_FILE_KEY, "/etc/security/keytabs/scm.keytab"); + testCommonKerberosFailures( + () -> StorageContainerManager.createSCM(null, conf)); + + } + + private void testCommonKerberosFailures(Callable callable) throws Exception { LambdaTestUtils.intercept(KerberosAuthException.class, "failure " - + "to login: for principal:", - () -> { - StorageContainerManager.createSCM(null, conf); - }); + + "to login: for principal:", callable); conf.set(CommonConfigurationKeysPublic.HADOOP_SECURITY_AUTHENTICATION, "OAuth2"); LambdaTestUtils.intercept(IllegalArgumentException.class, "Invalid" + " attribute value for hadoop.security.authentication of OAuth2", - () -> { - StorageContainerManager.createSCM(null, conf); - }); + callable); conf.set(CommonConfigurationKeysPublic.HADOOP_SECURITY_AUTHENTICATION, "KERBEROS_SSL"); LambdaTestUtils.intercept(AuthenticationException.class, - "KERBEROS_SSL authentication method not support.", - () -> { - StorageContainerManager.createSCM(null, conf); - }); + "KERBEROS_SSL authentication method not", + callable); + } + /** + * Tests the secure KSM Initialization Failure. + * + * @throws IOException + */ + @Test + public void testSecureKsmInitializationFailure() throws Exception { + initSCM(); + // Create a secure SCM instance as ksm client will connect to it + scm = StorageContainerManager.createSCM(null, conf); + + final String path = GenericTestUtils + .getTempPath(UUID.randomUUID().toString()); + KSMStorage ksmStore = new KSMStorage(conf); + ksmStore.setClusterId("testClusterId"); + ksmStore.setScmId("testScmId"); + // writes the version file properties + ksmStore.initialize(); + conf.set(HddsConfigKeys.HDDS_KSM_KERBEROS_PRINCIPAL_KEY, + "non-existent-u...@example.com"); + testCommonKerberosFailures(() -> KeySpaceManager.createKSM(null, conf)); + } + + /** + * Tests the secure KSM Initialization success. + * + * @throws IOException + */ + @Test + public void testSecureKsmInitializationSuccess() throws Exception { + initSCM(); + // Create a secure SCM instance as ksm client will connect to it + scm = StorageContainerManager.createSCM(null, conf); + LogCapturer logs = LogCapturer.captureLogs(KeySpaceManager.LOG); + GenericTestUtils + .setLogLevel(LoggerFactory.getLogger(KeySpaceManager.class.getName()), + org.slf4j.event.Level.INFO); + + final String path = GenericTestUtils + .getTempPath(UUID.randomUUID().toString()); + Path metaDirPath = Paths.get(path, "ksm-meta"); + + KSMStorage ksmStore = new KSMStorage(conf); + ksmStore.setClusterId("testClusterId"); + ksmStore.setScmId("testScmId"); + // writes the version file properties + ksmStore.initialize(); + try { + ksm = KeySpaceManager.createKSM(null, conf); + } catch (Exception ex) { + // Expects timeout failure from scmClient in KSM but KSM user login via + // kerberos should succeed + Assert.assertTrue(logs.getOutput().contains("KSM login successful")); + } } } http://git-wip-us.apache.org/repos/asf/hadoop/blob/1e95b5de/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/ksm/KeySpaceManager.java ---------------------------------------------------------------------- diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/ksm/KeySpaceManager.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/ksm/KeySpaceManager.java index d0f0c9b..700260d 100644 --- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/ksm/KeySpaceManager.java +++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/ksm/KeySpaceManager.java @@ -26,6 +26,7 @@ import org.apache.hadoop.ipc.Client; import org.apache.hadoop.ipc.ProtobufRpcEngine; import org.apache.hadoop.ipc.RPC; import org.apache.hadoop.hdds.server.ServiceRuntimeInfoImpl; +import org.apache.hadoop.ozone.OzoneConfigKeys; import org.apache.hadoop.ozone.common.Storage.StorageState; import org.apache.hadoop.ozone.ksm.exceptions.KSMException; import org.apache.hadoop.ozone.ksm.helpers.KsmBucketArgs; @@ -59,7 +60,10 @@ import org.apache.hadoop.hdds.scm.protocolPB.ScmBlockLocationProtocolPB; import org.apache.hadoop.hdds.scm.protocolPB .StorageContainerLocationProtocolClientSideTranslatorPB; import org.apache.hadoop.hdds.scm.protocolPB.StorageContainerLocationProtocolPB; +import org.apache.hadoop.security.SecurityUtil; import org.apache.hadoop.security.UserGroupInformation; +import org.apache.hadoop.security.UserGroupInformation.AuthenticationMethod; +import org.apache.hadoop.security.authentication.client.AuthenticationException; import org.apache.hadoop.util.GenericOptionsParser; import org.apache.hadoop.util.StringUtils; @@ -83,6 +87,8 @@ import java.util.List; import java.util.Map; import static org.apache.hadoop.ozone.OzoneConfigKeys.OZONE_ENABLED; +import static org.apache.hadoop.hdds.HddsConfigKeys.HDDS_KSM_KERBEROS_PRINCIPAL_KEY; +import static org.apache.hadoop.hdds.HddsConfigKeys.HDDS_KSM_KERBEROS_KEYTAB_FILE_KEY; import static org.apache.hadoop.ozone.ksm.KSMConfigKeys .OZONE_KSM_ADDRESS_KEY; import static org.apache.hadoop.ozone.ksm.KSMConfigKeys @@ -102,7 +108,7 @@ import static org.apache.hadoop.util.ExitUtil.terminate; @InterfaceAudience.LimitedPrivate({"HDFS", "CBLOCK", "OZONE", "HBASE"}) public final class KeySpaceManager extends ServiceRuntimeInfoImpl implements KeySpaceManagerProtocol, KSMMXBean { - private static final Logger LOG = + public static final Logger LOG = LoggerFactory.getLogger(KeySpaceManager.class); private static final String USAGE = @@ -153,8 +159,8 @@ public final class KeySpaceManager extends ServiceRuntimeInfoImpl private KeySpaceManager(OzoneConfiguration conf) throws IOException { Preconditions.checkNotNull(conf); configuration = conf; + ksmStorage = new KSMStorage(conf); - scmBlockClient = getScmBlockClient(configuration); scmContainerClient = getScmContainerClient(configuration); if (ksmStorage.getState() != StorageState.INITIALIZED) { throw new KSMException("KSM not initialized.", @@ -162,6 +168,7 @@ public final class KeySpaceManager extends ServiceRuntimeInfoImpl } // verifies that the SCM info in the KSM Version file is correct. + scmBlockClient = getScmBlockClient(configuration); ScmInfo scmInfo = scmBlockClient.getScmInfo(); if (!(scmInfo.getClusterId().equals(ksmStorage.getClusterID()) && scmInfo .getScmId().equals(ksmStorage.getScmId()))) { @@ -194,6 +201,34 @@ public final class KeySpaceManager extends ServiceRuntimeInfoImpl } /** + * Login KSM service user if security and Kerberos are enabled. + * + * @param conf + * @throws IOException, AuthenticationException + */ + private static void loginKSMUser(OzoneConfiguration conf) + throws IOException, AuthenticationException { + + if (SecurityUtil.getAuthenticationMethod(conf).equals + (AuthenticationMethod.KERBEROS)) { + LOG.debug("Ozone security is enabled. Attempting login for KSM user. " + + "Principal: {},keytab: {}", conf.get(HDDS_KSM_KERBEROS_PRINCIPAL_KEY), + conf.get(HDDS_KSM_KERBEROS_KEYTAB_FILE_KEY)); + + UserGroupInformation.setConfiguration(conf); + + InetSocketAddress socAddr = getKsmAddress(conf); + SecurityUtil.login(conf, HDDS_KSM_KERBEROS_KEYTAB_FILE_KEY, + HDDS_KSM_KERBEROS_PRINCIPAL_KEY, socAddr.getHostName()); + } else { + throw new AuthenticationException(SecurityUtil.getAuthenticationMethod + (conf) + " authentication method not supported. KSM user login " + + "failed."); + } + LOG.info("KSM login successful."); + } + + /** * Create a scm block client, used by putKey() and getKey(). * * @return {@link ScmBlockLocationProtocol} @@ -337,7 +372,7 @@ public final class KeySpaceManager extends ServiceRuntimeInfoImpl */ public static KeySpaceManager createKSM(String[] argv, - OzoneConfiguration conf) throws IOException { + OzoneConfiguration conf) throws IOException, AuthenticationException { if (!isHddsEnabled(conf)) { System.err.println("KSM cannot be started in secure mode or when " + OZONE_ENABLED + " is set to false"); @@ -349,6 +384,10 @@ public final class KeySpaceManager extends ServiceRuntimeInfoImpl terminate(1); return null; } + // Authenticate KSM if security is enabled + if (conf.getBoolean(OzoneConfigKeys.OZONE_SECURITY_ENABLED_KEY, true)) { + loginKSMUser(conf); + } switch (startOpt) { case CREATEOBJECTSTORE: terminate(ksmInit(conf) ? 0 : 1); @@ -443,7 +482,13 @@ public final class KeySpaceManager extends ServiceRuntimeInfoImpl metadataManager.start(); keyManager.start(); ksmRpcServer.start(); - httpServer.start(); + try { + httpServer.start(); + } catch (Exception ex) { + // Allow KSM to start as Http Server failure is not fatal. + LOG.error("KSM HttpServer failed to start.", ex); + } + registerMXBean(); setStartTime(); } http://git-wip-us.apache.org/repos/asf/hadoop/blob/1e95b5de/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/ksm/KeySpaceManagerHttpServer.java ---------------------------------------------------------------------- diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/ksm/KeySpaceManagerHttpServer.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/ksm/KeySpaceManagerHttpServer.java index 478804b..a0d15b3 100644 --- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/ksm/KeySpaceManagerHttpServer.java +++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/ksm/KeySpaceManagerHttpServer.java @@ -18,7 +18,6 @@ package org.apache.hadoop.ozone.ksm; import org.apache.hadoop.conf.Configuration; -import org.apache.hadoop.ozone.OzoneConfigKeys; import org.apache.hadoop.ozone.OzoneConsts; import org.apache.hadoop.hdds.server.BaseHttpServer; @@ -65,11 +64,11 @@ public class KeySpaceManagerHttpServer extends BaseHttpServer { } @Override protected String getKeytabFile() { - return KSMConfigKeys.OZONE_KSM_KEYTAB_FILE; + return KSMConfigKeys.KSM_WEB_AUTHENTICATION_KERBEROS_KEYTAB_FILE; } @Override protected String getSpnegoPrincipal() { - return OzoneConfigKeys.OZONE_SCM_WEB_AUTHENTICATION_KERBEROS_PRINCIPAL; + return KSMConfigKeys.KSM_WEB_AUTHENTICATION_KERBEROS_PRINCIPAL; } @Override protected String getEnabledKey() { --------------------------------------------------------------------- To unsubscribe, e-mail: common-commits-unsubscr...@hadoop.apache.org For additional commands, e-mail: common-commits-h...@hadoop.apache.org