Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions hbase-common/src/main/resources/hbase-default.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1631,6 +1631,26 @@ possible configurations would overwhelm and obscure the important.
Possible values are 'simple' (no authentication), and 'kerberos'.
</description>
</property>
<property>
<name>hbase.security.authentication.ui.metrics.protected</name>
<value>true</value>
<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)
</description>
</property>
<property>
<name>hbase.security.authentication.spnego.kerberos.endpoint.whitelist</name>
<value></value>
<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.
</description>
</property>
<property>
<name>hbase.rest.filter.classes</name>
<value>org.apache.hadoop.hbase.rest.filter.GzipFilter</value>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 =
Expand All @@ -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 =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we have a test case similar to the hadoop PR? Else it's difficult to ensure this doesn't break in future.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I got it, thanks. I will prepare with that.

Copy link
Contributor Author

@eubnara eubnara Jan 7, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm trying to add a test case but I encountered a problem. In order to use "hbase.security.authentication.spnego.kerberos.endpoint.whitelist", HBase should use the hadoop which has HADOOP-18666.
I think HADOOP-18666 will be committed to hadoop >= 3.4.0 according to jira https://issues.apache.org/jira/browse/HADOOP-18666.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh oh, in that case this feature won't even work until we have hadoop-3.4 right/ Maybe we park this PR for later then?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think so.
Let's postpone this PR until hbase uses hadoop with HADOOP-18666.

"hbase.security.authentication.ui.metrics.protected";
public static final boolean HTTP_PRIVILEGED_METRICS_DEFAULT = true;

// The ServletContext attribute where the daemon Configuration
// gets stored.
Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -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<String, String> params = new HashMap<>();
Map<String, String> params = conf.getPropsWithPrefix(HTTP_SPNEGO_AUTHENTICATION_PREFIX);
String principalInConf = getOrEmptyString(conf, usernameConfKey);
if (!principalInConf.isEmpty()) {
params.put(HTTP_SPNEGO_AUTHENTICATION_PRINCIPAL_SUFFIX,
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down Expand Up @@ -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());
}
}
30 changes: 30 additions & 0 deletions src/main/asciidoc/_chapters/hbase-default.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -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]]
Copy link
Contributor

@NihalJain NihalJain Jan 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was going through hadoop PR. This property has been implemented in hadoop to handle any endpoint irrespective of whether it is metrics or something else. Why don't we follow same approach.? Do we really need to handle just metrics endpoint and have the other property hbase.security.authentication.ui.metrics.protected? The property will become redundant.

A generic implementation like the one in hadoop sound more useful to me. Also the name of the config will confuse others. As it seems like a generic whitelist.

Copy link
Contributor Author

@eubnara eubnara Jan 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you want to use the name "hadoop.http.authentication.kerberos.endpoint.whitelist", instead of initializing params using configurations that starts with HTTP_SPNEGO_AUTHENTICATION_PREFIX, that name should be used like:

String endpointWhitelist = getOrEmptyString(conf, "hadoop.http.authentication.kerberos.endpoint.whitelist");
if (!endpointWhitelist.isEmpty()) {
  params.put("endpoint.whitelist", endpointWhitelist);
}

Do you think it is more suitable for HBase code?

I did initialize params using configurations that starts with HTTP_SPNEGO_AUTHENTICATION_PREFIX because already other configurations uses prefix with it.

https://github.com/apache/hbase/blob/rel/2.5.5/hbase-http/src/main/java/org/apache/hadoop/hbase/http/InfoServer.java#L82

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you want to use the name "hadoop.http.authentication.kerberos.endpoint.whitelist"

Hey I did not mean to change name.

A generic implementation like the one in hadoop sound more useful to me.

What I am trying to say is current implementation in PR aims to just whitelist which are under metrics umbrella. But if you look at the hadoop PR, it aims to provide a way to whitelist any endpoint in the passed list. Can we not follow that approach and have a generic implementation where we let the user whitelist any endpoint irrespective of whether it is a metric endpoint or say /logs

Also the name of the config will confuse others. As it seems like a generic whitelist.

I mean nowhere in config name hbase.security.authentication.spnego.kerberos.endpoint.whitelist it is obvious that this can control only metrics endpoints.

Copy link
Contributor

@NihalJain NihalJain Jan 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ignore as my doubt is clear here. Just that I think even conf servlet would also require the whitelisting if one want to access it:

if (conf.getBoolean(HTTP_PRIVILEGED_CONF_KEY, HTTP_PRIVILEGED_CONF_DEFAULT)) {
?

So is this documentation correct? It is valid even if hbase.security.authentication.ui.config.protected is false and whitelist is set to \conf, isn't it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, if someone wants to disable spnego authentication completely on /conf endpoint completely, /conf should also be added to whitelist.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe then update docs to reflect same?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I updated docs.

*`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`*::
+
Expand Down
25 changes: 24 additions & 1 deletion src/main/asciidoc/_chapters/security.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,10 @@ for RPCs (e.g `hbase.security.authentication` = `kerberos`).
<property>
<name>hbase.security.authentication</name>
<value>kerberos</value>
<description>The Kerberos keytab file to use for SPNEGO authentication by the web server.</description>
<description>
Controls whether or not secure authentication is enabled for HBase.
Possible values are 'simple' (no authentication), and 'kerberos'.
</description>
</property>
----

Expand Down Expand Up @@ -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.</description>
</property>
<property>
<name>hbase.security.authentication.spnego.kerberos.endpoint.whitelist</name>
<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.
</description>
</property>
----

=== Defining administrators of the Web UI
Expand Down Expand Up @@ -274,6 +286,17 @@ Users who wish to change this would set the following in their hbase-site.xml:
</property>
----

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]
----
<property>
<name>hbase.security.authentication.ui.metrics.protected</name>
<value>false</value>
</property>
----

To disable showing stack traces in HBase UI for hiding sensitive information, set the following in hbase-site:
[source,xml]
----
Expand Down