diff --git a/hbase-common/src/main/resources/hbase-default.xml b/hbase-common/src/main/resources/hbase-default.xml
index 1bf63b136e04..b16bb9e7dbf0 100644
--- a/hbase-common/src/main/resources/hbase-default.xml
+++ b/hbase-common/src/main/resources/hbase-default.xml
@@ -1631,6 +1631,26 @@ possible configurations would overwhelm and obscure the important.
Possible values are 'simple' (no authentication), and 'kerberos'.
+
+ hbase.security.authentication.ui.metrics.protected
+ true
+
+ Controls whether or not metrics endpoints are allowed only for admin.
+ If true, only users listed on "hbase.security.authentication.spnego.admin.users"
+ or users in group listed on "hbase.security.authentication.spnego.admin.groups"
+ are allowed to access metrics endpoints. (e.g. /jmx, /metrics, /prometheus)
+
+
+
+ hbase.security.authentication.spnego.kerberos.endpoint.whitelist
+
+
+ Controls whether or not secure authentication is enabled for conf, metrics endpoints.
+ (e.g. /conf, /jmx, /metrics, /prometheus)
+ It is valid only when "hbase.security.authentication.ui.config.protected" (for /conf),
+ "hbase.security.authentication.ui.metrics.protected" (for /jmx, /metrics, /prometheus) is false.
+
+
hbase.rest.filter.classes
org.apache.hadoop.hbase.rest.filter.GzipFilter
diff --git a/hbase-http/src/main/java/org/apache/hadoop/hbase/http/HttpServer.java b/hbase-http/src/main/java/org/apache/hadoop/hbase/http/HttpServer.java
index 6bbbc5608a0d..769a20031a80 100644
--- a/hbase-http/src/main/java/org/apache/hadoop/hbase/http/HttpServer.java
+++ b/hbase-http/src/main/java/org/apache/hadoop/hbase/http/HttpServer.java
@@ -144,6 +144,10 @@ public class HttpServer implements FilterContainer {
static final String HTTP_AUTHENTICATION_SIGNATURE_SECRET_FILE_SUFFIX = "signature.secret.file";
public static final String HTTP_AUTHENTICATION_SIGNATURE_SECRET_FILE_KEY =
HTTP_AUTHENTICATION_PREFIX + HTTP_AUTHENTICATION_SIGNATURE_SECRET_FILE_SUFFIX;
+ static final String HTTP_SPNEGO_AUTHENTICATION_ENDPOINT_WHITELIST_SUFFIX =
+ "kerberos.endpoint.whitelist";
+ public static final String HTTP_SPNEGO_AUTHENTICATION_ENDPOINT_WHITELIST_KEY =
+ HTTP_SPNEGO_AUTHENTICATION_PREFIX + HTTP_SPNEGO_AUTHENTICATION_ENDPOINT_WHITELIST_SUFFIX;
public static final String HTTP_SPNEGO_AUTHENTICATION_ADMIN_USERS_KEY =
HTTP_SPNEGO_AUTHENTICATION_PREFIX + "admin.users";
public static final String HTTP_SPNEGO_AUTHENTICATION_ADMIN_GROUPS_KEY =
@@ -152,6 +156,9 @@ public class HttpServer implements FilterContainer {
"hbase.security.authentication.ui.config.protected";
public static final String HTTP_UI_NO_CACHE_ENABLE_KEY = "hbase.http.filter.no-store.enable";
public static final boolean HTTP_PRIVILEGED_CONF_DEFAULT = false;
+ public static final String HTTP_PRIVILEGED_METRICS_KEY =
+ "hbase.security.authentication.ui.metrics.protected";
+ public static final boolean HTTP_PRIVILEGED_METRICS_DEFAULT = true;
// The ServletContext attribute where the daemon Configuration
// gets stored.
@@ -850,8 +857,13 @@ protected void addDefaultServlets(ContextHandlerCollection contexts, Configurati
ServletConfig servletConfig = METRIC_SERVLETS.get(enabledServlet);
if (servletConfig != null) {
Class> clz = Class.forName(servletConfig.getClazz());
- addPrivilegedServlet(servletConfig.getName(), servletConfig.getPathSpec(),
- clz.asSubclass(HttpServlet.class));
+ if (conf.getBoolean(HTTP_PRIVILEGED_METRICS_KEY, HTTP_PRIVILEGED_METRICS_DEFAULT)) {
+ addPrivilegedServlet(servletConfig.getName(), servletConfig.getPathSpec(),
+ clz.asSubclass(HttpServlet.class));
+ } else {
+ addUnprivilegedServlet(servletConfig.getName(), servletConfig.getPathSpec(),
+ clz.asSubclass(HttpServlet.class));
+ }
}
} catch (Exception e) {
/* shouldn't be fatal, so warn the user about it */
@@ -1129,7 +1141,7 @@ public void setThreads(int min, int max) {
private void initSpnego(Configuration conf, String hostName, String usernameConfKey,
String keytabConfKey, String kerberosNameRuleKey, String signatureSecretKeyFileKey)
throws IOException {
- Map params = new HashMap<>();
+ Map params = conf.getPropsWithPrefix(HTTP_SPNEGO_AUTHENTICATION_PREFIX);
String principalInConf = getOrEmptyString(conf, usernameConfKey);
if (!principalInConf.isEmpty()) {
params.put(HTTP_SPNEGO_AUTHENTICATION_PRINCIPAL_SUFFIX,
@@ -1147,6 +1159,11 @@ private void initSpnego(Configuration conf, String hostName, String usernameConf
if (!signatureSecretKeyFile.isEmpty()) {
params.put(HTTP_AUTHENTICATION_SIGNATURE_SECRET_FILE_SUFFIX, signatureSecretKeyFile);
}
+ String endpointWhitelist =
+ getOrEmptyString(conf, HTTP_SPNEGO_AUTHENTICATION_ENDPOINT_WHITELIST_KEY);
+ if (!endpointWhitelist.isEmpty()) {
+ params.put(HTTP_SPNEGO_AUTHENTICATION_ENDPOINT_WHITELIST_SUFFIX, endpointWhitelist);
+ }
params.put(AuthenticationFilter.AUTH_TYPE, "kerberos");
// Verify that the required options were provided
diff --git a/hbase-http/src/test/java/org/apache/hadoop/hbase/http/TestSpnegoHttpServer.java b/hbase-http/src/test/java/org/apache/hadoop/hbase/http/TestSpnegoHttpServer.java
index 25620d1bc6dc..2fcb2e4a6eef 100644
--- a/hbase-http/src/test/java/org/apache/hadoop/hbase/http/TestSpnegoHttpServer.java
+++ b/hbase-http/src/test/java/org/apache/hadoop/hbase/http/TestSpnegoHttpServer.java
@@ -157,6 +157,11 @@ private static Configuration buildSpnegoConfiguration(Configuration conf, String
conf.set(HttpServer.HTTP_SPNEGO_AUTHENTICATION_PRINCIPAL_KEY, serverPrincipal);
conf.set(HttpServer.HTTP_SPNEGO_AUTHENTICATION_KEYTAB_KEY, serverKeytab.getAbsolutePath());
+ // To test disabled kerberos authentication for specific metric endpoint
+ conf.set(HttpServer.HTTP_PRIVILEGED_METRICS_KEY, "false");
+ conf.set(HttpServer.METRIC_SERVLETS_CONF_KEY, "jmx,prometheus");
+ conf.set(HttpServer.HTTP_SPNEGO_AUTHENTICATION_ENDPOINT_WHITELIST_KEY, "/prometheus");
+
return conf;
}
@@ -234,4 +239,15 @@ public void testMissingConfigurationThrowsException() throws Exception {
customServer.addJerseyResourcePackage(JerseyResource.class.getPackage().getName(), "/jersey/*");
customServer.start();
}
+
+ @Test
+ public void testEndpointWhitelist() throws IOException {
+ URL url = new URL(getServerURL(server), "/jmx");
+ HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+ assertEquals(HttpURLConnection.HTTP_UNAUTHORIZED, conn.getResponseCode());
+ // FIXME: hadoop >= 3.4.0 (or hadoop with HADOOP-18666) is needed to test with below lines.
+ // url = new URL(getServerURL(server), "/prometheus");
+ // conn = (HttpURLConnection) url.openConnection();
+ // assertEquals(HttpURLConnection.HTTP_OK, conn.getResponseCode());
+ }
}
diff --git a/src/main/asciidoc/_chapters/hbase-default.adoc b/src/main/asciidoc/_chapters/hbase-default.adoc
index 03391cc38b1a..5f9603eaffea 100644
--- a/src/main/asciidoc/_chapters/hbase-default.adoc
+++ b/src/main/asciidoc/_chapters/hbase-default.adoc
@@ -1949,6 +1949,36 @@ If the DFSClient configuration
`simple`
+[[hbase.security.authentication.ui.metrics.protected]]
+*`hbase.security.authentication.ui.metrics.protected`*::
++
+.Description
+
+ Controls whether or not metrics endpoints are allowed only for admin.
+ If true, only users listed on "hbase.security.authentication.spnego.admin.users"
+ or users in group listed on "hbase.security.authentication.spnego.admin.groups"
+ are allowed to access metrics endpoints. (e.g. /jmx, /metrics, /prometheus)
+
++
+.Default
+`true`
+
+
+[[hbase.security.authentication.spnego.kerberos.endpoint.whitelist]]
+*`hbase.security.authentication.spnego.kerberos.endpoint.whitelist`*::
++
+.Description
+
+ Controls whether or not secure authentication is enabled for conf, metrics endpoints.
+ (e.g. /conf, /jmx, /metrics, /prometheus)
+ It is valid only when "hbase.security.authentication.ui.config.protected" (for /conf),
+ "hbase.security.authentication.ui.metrics.protected" (for /jmx, /metrics, /prometheus) is false.
+
++
+.Default
+``
+
+
[[hbase.rest.filter.classes]]
*`hbase.rest.filter.classes`*::
+
diff --git a/src/main/asciidoc/_chapters/security.adoc b/src/main/asciidoc/_chapters/security.adoc
index b2110a6fbcda..6e7df1e4c3ea 100644
--- a/src/main/asciidoc/_chapters/security.adoc
+++ b/src/main/asciidoc/_chapters/security.adoc
@@ -101,7 +101,10 @@ for RPCs (e.g `hbase.security.authentication` = `kerberos`).
hbase.security.authentication
kerberos
- The Kerberos keytab file to use for SPNEGO authentication by the web server.
+
+ Controls whether or not secure authentication is enabled for HBase.
+ Possible values are 'simple' (no authentication), and 'kerberos'.
+
----
@@ -135,6 +138,15 @@ A number of properties exist to configure SPNEGO authentication for the web serv
as a part of the SPNEGO authentication handshake. If this is not provided, Java's `Random` library
will be used for the secret.
+
+ hbase.security.authentication.spnego.kerberos.endpoint.whitelist
+
+ Controls whether or not secure authentication is enabled for conf, metrics endpoints.
+ (e.g. /conf, /jmx, /metrics, /prometheus)
+ It is valid only when "hbase.security.authentication.ui.config.protected" (for /conf),
+ "hbase.security.authentication.ui.metrics.protected" (for /jmx, /metrics, /prometheus) is false.
+
+
----
=== Defining administrators of the Web UI
@@ -274,6 +286,17 @@ Users who wish to change this would set the following in their hbase-site.xml:
----
+Metrics endpoints (like /jmx, /metrics, /prometheus specified in "hbase.http.metrics.servlets") are
+only allowed to admins by default.
+To allow any authenticated user to access metrics endpoints, set the following in their hbase-site.xml:
+[source,xml]
+----
+
+ hbase.security.authentication.ui.metrics.protected
+ false
+
+----
+
To disable showing stack traces in HBase UI for hiding sensitive information, set the following in hbase-site:
[source,xml]
----