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] ----