diff --git a/hadoop-hdds/common/src/main/java/org/apache/hadoop/ozone/OzoneConfigKeys.java b/hadoop-hdds/common/src/main/java/org/apache/hadoop/ozone/OzoneConfigKeys.java
index 199242632bf5..460803ef22b4 100644
--- a/hadoop-hdds/common/src/main/java/org/apache/hadoop/ozone/OzoneConfigKeys.java
+++ b/hadoop-hdds/common/src/main/java/org/apache/hadoop/ozone/OzoneConfigKeys.java
@@ -330,6 +330,8 @@ public final class OzoneConfigKeys {
public static final String OZONE_HTTP_SECURITY_ENABLED_KEY =
"ozone.security.http.kerberos.enabled";
public static final boolean OZONE_HTTP_SECURITY_ENABLED_DEFAULT = false;
+ public static final String OZONE_HTTP_FILTER_INITIALIZERS_KEY =
+ "ozone.http.filter.initializers";
public static final String OZONE_CONTAINER_COPY_WORKDIR =
"hdds.datanode.replication.work.dir";
diff --git a/hadoop-hdds/common/src/main/java/org/apache/hadoop/ozone/OzoneConsts.java b/hadoop-hdds/common/src/main/java/org/apache/hadoop/ozone/OzoneConsts.java
index 0196725e1402..936861fc6783 100644
--- a/hadoop-hdds/common/src/main/java/org/apache/hadoop/ozone/OzoneConsts.java
+++ b/hadoop-hdds/common/src/main/java/org/apache/hadoop/ozone/OzoneConsts.java
@@ -430,4 +430,12 @@ private OzoneConsts() {
public static final String SCM_SUB_CA_PREFIX = "scm-sub@";
public static final String SCM_ROOT_CA_PREFIX = "scm@";
+
+ // Kerberos constants
+ public static final String KERBEROS_CONFIG_VALUE = "kerberos";
+ public static final String HTTP_AUTH_TYPE_SUFFIX = "http.auth.type";
+ public static final String OZONE_SECURITY_ENABLED_SECURE = "true";
+ public static final String OZONE_HTTP_SECURITY_ENABLED_SECURE = "true";
+ public static final String OZONE_HTTP_FILTER_INITIALIZERS_SECURE =
+ "org.apache.hadoop.security.AuthenticationFilterInitializer";
}
diff --git a/hadoop-hdds/common/src/main/resources/ozone-default.xml b/hadoop-hdds/common/src/main/resources/ozone-default.xml
index ac8169e35c50..9d2dceab4db9 100644
--- a/hadoop-hdds/common/src/main/resources/ozone-default.xml
+++ b/hadoop-hdds/common/src/main/resources/ozone-default.xml
@@ -434,7 +434,7 @@
ozone.om.service.ids
-
+
OM, HA
Comma-separated list of OM service Ids. This property allows the client
@@ -443,7 +443,7 @@
ozone.om.internal.service.id
-
+
OM, HA
Service ID of the Ozone Manager. If this is not set fall back to
@@ -452,7 +452,7 @@
ozone.om.nodes.EXAMPLEOMSERVICEID
-
+
OM, HA
Comma-separated list of OM node Ids for a given OM service ID (eg.
@@ -470,7 +470,7 @@
ozone.om.node.id
-
+
OM, HA
The ID of this OM node. If the OM node ID is not configured it
@@ -1262,7 +1262,7 @@
hdds.datanode.plugins
-
+
Comma-separated list of HDDS datanode plug-ins to be activated when
HDDS service starts as part of datanode.
@@ -1454,6 +1454,37 @@
+
+ hdds.scm.kerberos.keytab.file
+ /etc/security/keytabs/SCM.keytab
+ SCM, SECURITY, KERBEROS
+ The keytab file used by SCM daemon to login as its service principal.
+
+
+
+ hdds.scm.kerberos.principal
+ SCM/_HOST@REALM
+ SCM, SECURITY, KERBEROS
+ The SCM service principal. e.g. scm/_HOST@REALM.COM
+
+
+ hdds.scm.http.auth.kerberos.principal
+ HTTP/_HOST@REALM
+ SCM, SECURITY, KERBEROS
+
+ SCM http server service principal if SPNEGO is enabled for SCM http server.
+
+
+
+ hdds.scm.http.auth.kerberos.keytab
+ /etc/security/keytabs/HTTP.keytab
+ SCM, SECURITY, KERBEROS
+
+ The keytab file used by SCM http server to login as its service
+ principal if SPNEGO is enabled for SCM http server.
+
+
+
ozone.s3g.volume.name
s3v
@@ -1519,8 +1550,8 @@
ozone.s3g.http.auth.kerberos.principal
-
- OZONE, S3GATEWAY
+ HTTP/_HOST@REALM
+ OZONE, S3GATEWAY, SECURITY, KERBEROS
The server principal used by Ozone S3Gateway server. This is
typically set to
HTTP/_HOST@REALM.TLD The SPNEGO server principal begins with the prefix
@@ -1529,8 +1560,8 @@
ozone.s3g.http.auth.kerberos.keytab
-
- OZONE, S3GATEWAY
+ /etc/security/keytabs/HTTP.keytab
+ OZONE, S3GATEWAY, SECURITY, KERBEROS
The keytab file used by the S3Gateway server to login as its
service principal.
@@ -1547,7 +1578,7 @@
ozone.security.enabled
false
- OZONE, SECURITY
+ OZONE, SECURITY, KERBEROS
True if security is enabled for ozone. When this property is
true, hadoop.security.authentication should be Kerberos.
@@ -1555,13 +1586,23 @@
ozone.security.http.kerberos.enabled
false
- OZONE, SECURITY
+ OZONE, SECURITY, KERBEROS
True if Kerberos authentication for Ozone HTTP web consoles
is enabled using the SPNEGO protocol. When this property is
true, hadoop.security.authentication should be Kerberos and
ozone.security.enabled should be set to true.
+
+ ozone.http.filter.initializers
+
+ OZONE, SECURITY, KERBEROS
+ Set to org.apache.hadoop.security.AuthenticationFilterInitializer
+ to enable Kerberos authentication for Ozone HTTP web consoles
+ is enabled using the SPNEGO protocol. When this property is
+ set, ozone.security.http.kerberos.enabled should be set to true.
+
+
@@ -1760,8 +1801,8 @@
ozone.om.kerberos.keytab.file
-
- OZONE, SECURITY
+ /etc/security/keytabs/OM.keytab
+ OZONE, SECURITY, KERBEROS
The keytab file used by OzoneManager daemon to login as its
service principal. The principal name is configured with
ozone.om.kerberos.principal.
@@ -1769,22 +1810,25 @@
ozone.om.kerberos.principal
-
- OZONE, SECURITY
+ OM/_HOST@REALM
+ OZONE, SECURITY, KERBEROS
The OzoneManager service principal. Ex om/_HOST@REALM.COM
ozone.om.http.auth.kerberos.principal
- HTTP/_HOST@EXAMPLE.COM
+ HTTP/_HOST@REALM
+ OZONE, SECURITY, KERBEROS
- OzoneManager http server kerberos principal.
+ Ozone Manager http server service principal if SPNEGO is enabled for om http server.
ozone.om.http.auth.kerberos.keytab
/etc/security/keytabs/HTTP.keytab
+ OZONE, SECURITY, KERBEROS
- OzoneManager http server kerberos keytab.
+ The keytab file used by OM http server to login as its service
+ principal if SPNEGO is enabled for om http server.
@@ -2233,7 +2277,7 @@
ozone.freon.http.auth.kerberos.principal
- HTTP/_HOST@EXAMPLE.COM
+ HTTP/_HOST@REALM
SECURITY
Security principal used by freon.
@@ -2295,8 +2339,8 @@
hdds.datanode.http.auth.kerberos.principal
- HTTP/_HOST@EXAMPLE.COM
- HDDS, SECURITY, MANAGEMENT
+ HTTP/_HOST@REALM
+ HDDS, SECURITY, MANAGEMENT, KERBEROS
The kerberos principal for the datanode http server.
@@ -2304,7 +2348,7 @@
hdds.datanode.http.auth.kerberos.keytab
/etc/security/keytabs/HTTP.keytab
- HDDS, SECURITY, MANAGEMENT
+ HDDS, SECURITY, MANAGEMENT, KERBEROS
The kerberos keytab file for datanode http server
@@ -2429,31 +2473,31 @@
ozone.recon.http.auth.kerberos.keytab
-
- RECON, SECURITY
+ /etc/security/keytabs/HTTP.keytab
+ RECON, SECURITY, KERBEROS
The keytab file for HTTP Kerberos authentication in Recon.
ozone.recon.http.auth.kerberos.principal
-
- RECON
+ HTTP/_HOST@REALM
+ RECON, SECURITY, KERBEROS
The server principal used by Ozone Recon server. This is
typically set to HTTP/_HOST@REALM.TLD The SPNEGO server principal
begins with the prefix HTTP/ by convention.
- hdds.datanode.http.auth.type
+ hdds.datanode.http.auth.type
simple
- DATANODE, SECURITY
+ DATANODE, SECURITY, KERBEROS
simple or kerberos. If kerberos is set, Kerberos SPNEOGO
will be used for http authentication.
- ozone.freon.http.auth.type
+ ozone.freon.http.auth.type
simple
FREON, SECURITY
simple or kerberos. If kerberos is set, Kerberos SPNEOGO
@@ -2461,25 +2505,33 @@
- ozone.om.http.auth.type
+ ozone.om.http.auth.type
simple
- OM, SECURITY
+ OM, SECURITY, KERBEROS
+ simple or kerberos. If kerberos is set, Kerberos SPNEOGO
+ will be used for http authentication.
+
+
+
+ hdds.scm.http.auth.type
+ simple
+ OM, SECURITY, KERBEROS
simple or kerberos. If kerberos is set, Kerberos SPNEOGO
will be used for http authentication.
- ozone.recon.http.auth.type
+ ozone.recon.http.auth.type
simple
- RECON, SECURITY
+ RECON, SECURITY, KERBEROS
simple or kerberos. If kerberos is set, Kerberos SPNEOGO
will be used for http authentication.
- ozone.s3g.http.auth.type
+ ozone.s3g.http.auth.type
simple
- S3G, SECURITY
+ S3G, SECURITY, KERBEROS
simple or kerberos. If kerberos is set, Kerberos SPNEOGO
will be used for http authentication.
@@ -2633,7 +2685,7 @@
ozone.http.basedir
-
+
OZONE, OM, SCM, MANAGEMENT
The base dir for HTTP Jetty server to extract contents. If this property
@@ -2694,14 +2746,14 @@
ssl.server.keystore.keypassword
OZONE, SECURITY, MANAGEMENT
-
+
Keystore key password for HTTPS SSL configuration
ssl.server.keystore.location
OZONE, SECURITY, MANAGEMENT
-
+
Keystore location for HTTPS SSL configuration
@@ -2709,7 +2761,7 @@
ssl.server.keystore.password
OZONE, SECURITY, MANAGEMENT
-
+
Keystore password for HTTPS SSL configuration
@@ -2717,7 +2769,7 @@
ssl.server.truststore.location
OZONE, SECURITY, MANAGEMENT
-
+
Truststore location for HTTPS SSL configuration
@@ -2725,7 +2777,7 @@
ssl.server.truststore.password
OZONE, SECURITY, MANAGEMENT
-
+
Truststore password for HTTPS SSL configuration
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 53b1a99c799a..508725dcd454 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
@@ -19,6 +19,7 @@
import org.apache.hadoop.conf.TestConfigurationFieldsBase;
import org.apache.hadoop.hdds.HddsConfigKeys;
+import org.apache.hadoop.hdds.scm.ScmConfig;
import org.apache.hadoop.hdds.scm.server.SCMHTTPServerConfig;
import org.apache.hadoop.ozone.om.OMConfigKeys;
import org.apache.hadoop.hdds.scm.ScmConfigKeys;
@@ -48,7 +49,9 @@ public void initializeMemberVariables() {
OMConfigKeys.class, HddsConfigKeys.class,
ReconServerConfigKeys.class,
S3GatewayConfigKeys.class,
- SCMHTTPServerConfig.class
+ SCMHTTPServerConfig.class,
+ SCMHTTPServerConfig.ConfigStrings.class,
+ ScmConfig.ConfigStrings.class
};
errorIfMissingConfigProps = true;
errorIfMissingXmlProps = true;
diff --git a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/genconf/GenerateOzoneRequiredConfigurations.java b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/genconf/GenerateOzoneRequiredConfigurations.java
index 94557cc1668b..c5d4d156c8bf 100644
--- a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/genconf/GenerateOzoneRequiredConfigurations.java
+++ b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/genconf/GenerateOzoneRequiredConfigurations.java
@@ -26,6 +26,7 @@
import org.apache.hadoop.ozone.OzoneConsts;
import org.apache.hadoop.ozone.om.OMConfigKeys;
import picocli.CommandLine.Command;
+import picocli.CommandLine.Option;
import picocli.CommandLine.Parameters;
import picocli.CommandLine.PicocliException;
@@ -61,6 +62,10 @@ public final class GenerateOzoneRequiredConfigurations extends GenericCli {
description = "Directory path where ozone-site file should be generated.")
private String path;
+ @Option(names = "--security", description = "Generates security config " +
+ "template, update Kerberos principal and keytab file before use.")
+ private boolean genSecurityConf;
+
/**
* Entry point for using genconf tool.
*
@@ -73,7 +78,7 @@ public static void main(String[] args) throws Exception {
@Override
public Void call() throws Exception {
- generateConfigurations(path);
+ generateConfigurations(path, genSecurityConf);
return null;
}
@@ -85,6 +90,19 @@ public Void call() throws Exception {
*/
public static void generateConfigurations(String path) throws
PicocliException, JAXBException, IOException {
+ generateConfigurations(path, false);
+ }
+
+ /**
+ * Generate ozone-site.xml at specified path.
+ * @param path
+ * @param genSecurityConf
+ * @throws PicocliException
+ * @throws JAXBException
+ */
+ public static void generateConfigurations(String path,
+ boolean genSecurityConf) throws
+ PicocliException, JAXBException, IOException {
if (!isValidPath(path)) {
throw new PicocliException("Invalid directory path.");
@@ -108,7 +126,9 @@ public static void generateConfigurations(String path) throws
List requiredProperties = new ArrayList<>();
for (OzoneConfiguration.Property p : allProperties) {
- if (p.getTag() != null && p.getTag().contains("REQUIRED")) {
+ if (p.getTag() != null && (p.getTag().contains("REQUIRED") ||
+ (genSecurityConf && p.getTag().contains("KERBEROS")))) {
+ // Set default value for common required configs
if (p.getName().equalsIgnoreCase(
OzoneConfigKeys.OZONE_METADATA_DIRS)) {
p.setValue(System.getProperty(OzoneConsts.JAVA_TMP_DIR));
@@ -120,13 +140,27 @@ public static void generateConfigurations(String path) throws
p.setValue(OzoneConsts.LOCALHOST);
}
+ // Set default value for KERBEROS configs
+ if (p.getName().equalsIgnoreCase(
+ OzoneConfigKeys.OZONE_SECURITY_ENABLED_KEY)) {
+ p.setValue(OzoneConsts.OZONE_SECURITY_ENABLED_SECURE);
+ } else if (p.getName().equalsIgnoreCase(
+ OzoneConfigKeys.OZONE_HTTP_SECURITY_ENABLED_KEY)) {
+ p.setValue(OzoneConsts.OZONE_HTTP_SECURITY_ENABLED_SECURE);
+ } else if (p.getName().equalsIgnoreCase(
+ OzoneConfigKeys.OZONE_HTTP_FILTER_INITIALIZERS_KEY)) {
+ p.setValue(OzoneConsts.OZONE_HTTP_FILTER_INITIALIZERS_SECURE);
+ } else if (p.getName().endsWith(OzoneConsts.HTTP_AUTH_TYPE_SUFFIX)) {
+ p.setValue(OzoneConsts.KERBEROS_CONFIG_VALUE);
+ }
+
requiredProperties.add(p);
}
}
- OzoneConfiguration.XMLConfiguration requiredConfig =
+ OzoneConfiguration.XMLConfiguration generatedConfig =
new OzoneConfiguration.XMLConfiguration();
- requiredConfig.setProperties(requiredProperties);
+ generatedConfig.setProperties(requiredProperties);
File output = new File(path, "ozone-site.xml");
if(output.createNewFile()){
@@ -134,7 +168,7 @@ public static void generateConfigurations(String path) throws
JAXBContext.newInstance(OzoneConfiguration.XMLConfiguration.class);
Marshaller m = context.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
- m.marshal(requiredConfig, output);
+ m.marshal(generatedConfig, output);
System.out.println("ozone-site.xml has been generated at " + path);
} else {
diff --git a/hadoop-ozone/tools/src/test/java/org/apache/hadoop/ozone/genconf/TestGenerateOzoneRequiredConfigurations.java b/hadoop-ozone/tools/src/test/java/org/apache/hadoop/ozone/genconf/TestGenerateOzoneRequiredConfigurations.java
index 8a66a1443209..2f4c4a8d743f 100644
--- a/hadoop-ozone/tools/src/test/java/org/apache/hadoop/ozone/genconf/TestGenerateOzoneRequiredConfigurations.java
+++ b/hadoop-ozone/tools/src/test/java/org/apache/hadoop/ozone/genconf/TestGenerateOzoneRequiredConfigurations.java
@@ -181,6 +181,56 @@ public void testGenerateConfigurations() throws Exception {
}
}
+ /**
+ * Tests a valid path and generates secure ozone-site.xml by calling
+ * {@code GenerateOzoneRequiredConfigurations#generateConfigurations}.
+ * Further verifies that all properties have a default value.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testGenerateSecurityConfigurations() throws Exception {
+ int ozoneConfigurationCount, ozoneSecurityConfigurationCount;
+
+ // Generate default Ozone Configuration
+ File tempPath = getRandomTempDir();
+ String[] args = new String[]{tempPath.getAbsolutePath()};
+ execute(args, "ozone-site.xml has been generated at " +
+ tempPath.getAbsolutePath());
+
+ URL url = new File(tempPath.getAbsolutePath() + "/ozone-site.xml")
+ .toURI().toURL();
+ OzoneConfiguration oc = new OzoneConfiguration();
+ List allProperties =
+ oc.readPropertyFromXml(url);
+
+ for (OzoneConfiguration.Property p : allProperties) {
+ Assert.assertTrue(
+ p.getValue() != null && p.getValue().length() > 0);
+ }
+ ozoneConfigurationCount = allProperties.size();
+
+ // Generate secure Ozone Configuration
+ tempPath = getRandomTempDir();
+ args = new String[]{"--security", tempPath.getAbsolutePath()};
+ execute(args, "ozone-site.xml has been generated at " +
+ tempPath.getAbsolutePath());
+
+ url = new File(tempPath.getAbsolutePath() + "/ozone-site.xml")
+ .toURI().toURL();
+ oc = new OzoneConfiguration();
+ allProperties = oc.readPropertyFromXml(url);
+
+ for (OzoneConfiguration.Property p : allProperties) {
+ Assert.assertTrue(
+ p.getValue() != null && p.getValue().length() > 0);
+ }
+ ozoneSecurityConfigurationCount = allProperties.size();
+
+ Assert.assertNotEquals(ozoneConfigurationCount,
+ ozoneSecurityConfigurationCount);
+ }
+
/**
* Generates ozone-site.xml at specified path.
* Verify that it does not overwrite if file already exists in path.
@@ -242,7 +292,7 @@ public void genconfPathNotSpecified() throws Exception {
public void genconfHelp() throws Exception {
File tempPath = getRandomTempDir();
String[] args = new String[]{"--help"};
- execute(args, "Usage: ozone genconf [-hV] [--verbose]");
+ execute(args, "Usage: ozone genconf [-hV] [--security] [--verbose]");
}
private File getRandomTempDir() throws IOException {