Repository: hive Updated Branches: refs/heads/master 546c75c59 -> 74e5c75e4
HIVE-12485: Secure HS2 web UI with kerberos(Jimmy, reviewed by Szehon) Project: http://git-wip-us.apache.org/repos/asf/hive/repo Commit: http://git-wip-us.apache.org/repos/asf/hive/commit/74e5c75e Tree: http://git-wip-us.apache.org/repos/asf/hive/tree/74e5c75e Diff: http://git-wip-us.apache.org/repos/asf/hive/diff/74e5c75e Branch: refs/heads/master Commit: 74e5c75e495dac5b2aeff03ee6ef936f28161014 Parents: 546c75c Author: Jimmy Xiang <jxi...@apache.org> Authored: Fri Dec 4 15:09:48 2015 -0800 Committer: Jimmy Xiang <jxi...@apache.org> Committed: Wed Dec 9 11:38:08 2015 -0800 ---------------------------------------------------------------------- .../org/apache/hadoop/hive/conf/HiveConf.java | 10 ++++- .../java/org/apache/hive/http/HttpServer.java | 47 ++++++++++++++++++++ .../apache/hive/service/server/HiveServer2.java | 15 +++++++ 3 files changed, 71 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/hive/blob/74e5c75e/common/src/java/org/apache/hadoop/hive/conf/HiveConf.java ---------------------------------------------------------------------- diff --git a/common/src/java/org/apache/hadoop/hive/conf/HiveConf.java b/common/src/java/org/apache/hadoop/hive/conf/HiveConf.java index d52f994..058f91d 100644 --- a/common/src/java/org/apache/hadoop/hive/conf/HiveConf.java +++ b/common/src/java/org/apache/hadoop/hive/conf/HiveConf.java @@ -1852,12 +1852,20 @@ public class HiveConf extends Configuration { HIVE_SERVER2_WEBUI_BIND_HOST("hive.server2.webui.host", "0.0.0.0", "The host address the HiveServer2 WebUI will listen on"), HIVE_SERVER2_WEBUI_PORT("hive.server2.webui.port", 10002, "The port the HiveServer2 WebUI will listen on"), HIVE_SERVER2_WEBUI_MAX_THREADS("hive.server2.webui.max.threads", 50, "The max HiveServer2 WebUI threads"), - HIVE_SERVER2_WEBUI_USE_SSL("hive.server2.webui.use.SSL", false, + HIVE_SERVER2_WEBUI_USE_SSL("hive.server2.webui.use.ssl", false, "Set this to true for using SSL encryption for HiveServer2 WebUI."), HIVE_SERVER2_WEBUI_SSL_KEYSTORE_PATH("hive.server2.webui.keystore.path", "", "SSL certificate keystore location for HiveServer2 WebUI."), HIVE_SERVER2_WEBUI_SSL_KEYSTORE_PASSWORD("hive.server2.webui.keystore.password", "", "SSL certificate keystore password for HiveServer2 WebUI."), + HIVE_SERVER2_WEBUI_USE_SPNEGO("hive.server2.webui.use.spnego", false, + "If true, the HiveServer2 WebUI will be secured with SPNEGO. Clients must authenticate with Kerberos."), + HIVE_SERVER2_WEBUI_SPNEGO_KEYTAB("hive.server2.webui.spnego.keytab", "", + "The path to the Kerberos Keytab file containing the HiveServer2 WebUI SPNEGO service principal."), + HIVE_SERVER2_WEBUI_SPNEGO_PRINCIPAL("hive.server2.webui.spnego.principal", + "HTTP/_h...@example.com", "The HiveServer2 WebUI SPNEGO service principal.\n" + + "The special string _HOST will be replaced automatically with \n" + + "the value of hive.server2.webui.host or the correct host name."), // Tez session settings HIVE_SERVER2_TEZ_DEFAULT_QUEUES("hive.server2.tez.default.queues", "", http://git-wip-us.apache.org/repos/asf/hive/blob/74e5c75e/common/src/java/org/apache/hive/http/HttpServer.java ---------------------------------------------------------------------- diff --git a/common/src/java/org/apache/hive/http/HttpServer.java b/common/src/java/org/apache/hive/http/HttpServer.java index 4b0ed68..68730af 100644 --- a/common/src/java/org/apache/hive/http/HttpServer.java +++ b/common/src/java/org/apache/hive/http/HttpServer.java @@ -34,7 +34,9 @@ import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.CommonConfigurationKeys; import org.apache.hadoop.hive.conf.HiveConf; import org.apache.hadoop.hive.conf.HiveConf.ConfVars; +import org.apache.hadoop.security.SecurityUtil; import org.apache.hadoop.security.UserGroupInformation; +import org.apache.hadoop.security.authentication.server.AuthenticationFilter; import org.apache.hadoop.security.authorize.AccessControlList; import org.apache.hadoop.util.Shell; import org.apache.logging.log4j.LogManager; @@ -51,7 +53,10 @@ import org.eclipse.jetty.server.handler.ContextHandlerCollection; import org.eclipse.jetty.server.nio.SelectChannelConnector; import org.eclipse.jetty.server.ssl.SslSelectChannelConnector; import org.eclipse.jetty.servlet.DefaultServlet; +import org.eclipse.jetty.servlet.FilterHolder; +import org.eclipse.jetty.servlet.FilterMapping; import org.eclipse.jetty.servlet.ServletContextHandler; +import org.eclipse.jetty.servlet.ServletHandler; import org.eclipse.jetty.servlet.ServletHolder; import org.eclipse.jetty.util.ssl.SslContextFactory; import org.eclipse.jetty.util.thread.QueuedThreadPool; @@ -82,6 +87,12 @@ public class HttpServer { webServer = new Server(); appDir = getWebAppsPath(b.name); webAppContext = createWebAppContext(b); + + if (b.useSPNEGO) { + // Secure the web server with kerberos + setupSpnegoFilter(b); + } + initializeWebServer(b); } @@ -94,6 +105,9 @@ public class HttpServer { private Map<String, Object> contextAttrs = new HashMap<String, Object>(); private String keyStorePassword; private String keyStorePath; + private String spnegoPrincipal; + private String spnegoKeytab; + private boolean useSPNEGO; private boolean useSSL; public HttpServer build() throws IOException { @@ -148,6 +162,21 @@ public class HttpServer { return this; } + public Builder setUseSPNEGO(boolean useSPNEGO) { + this.useSPNEGO = useSPNEGO; + return this; + } + + public Builder setSPNEGOPrincipal(String principal) { + this.spnegoPrincipal = principal; + return this; + } + + public Builder setSPNEGOKeytab(String keytab) { + this.spnegoKeytab = keytab; + return this; + } + public Builder setContextAttribute(String name, Object value) { contextAttrs.put(name, value); return this; @@ -267,6 +296,24 @@ public class HttpServer { } /** + * Secure the web server with kerberos (AuthenticationFilter). + */ + void setupSpnegoFilter(Builder b) throws IOException { + Map<String, String> params = new HashMap<String, String>(); + params.put("kerberos.principal", + SecurityUtil.getServerPrincipal(b.spnegoPrincipal, b.host)); + params.put("kerberos.keytab", b.spnegoKeytab); + params.put(AuthenticationFilter.AUTH_TYPE, "kerberos"); + FilterHolder holder = new FilterHolder(); + holder.setClassName(AuthenticationFilter.class.getName()); + holder.setInitParameters(params); + + ServletHandler handler = webAppContext.getServletHandler(); + handler.addFilterWithMapping( + holder, "/*", FilterMapping.ALL); + } + + /** * Create a channel connector for "http/https" requests */ Connector createChannelConnector(int queueSize, Builder b) { http://git-wip-us.apache.org/repos/asf/hive/blob/74e5c75e/service/src/java/org/apache/hive/service/server/HiveServer2.java ---------------------------------------------------------------------- diff --git a/service/src/java/org/apache/hive/service/server/HiveServer2.java b/service/src/java/org/apache/hive/service/server/HiveServer2.java index cad541a..2f55591 100644 --- a/service/src/java/org/apache/hive/service/server/HiveServer2.java +++ b/service/src/java/org/apache/hive/service/server/HiveServer2.java @@ -155,6 +155,21 @@ public class HiveServer2 extends CompositeService { builder.setKeyStorePath(keyStorePath); builder.setUseSSL(true); } + if (hiveConf.getBoolVar(ConfVars.HIVE_SERVER2_WEBUI_USE_SPNEGO)) { + String spnegoPrincipal = hiveConf.getVar( + ConfVars.HIVE_SERVER2_WEBUI_SPNEGO_PRINCIPAL); + String spnegoKeytab = hiveConf.getVar( + ConfVars.HIVE_SERVER2_WEBUI_SPNEGO_KEYTAB); + if (Strings.isBlank(spnegoPrincipal) || Strings.isBlank(spnegoKeytab)) { + throw new IllegalArgumentException( + ConfVars.HIVE_SERVER2_WEBUI_SPNEGO_PRINCIPAL.varname + + "/" + ConfVars.HIVE_SERVER2_WEBUI_SPNEGO_KEYTAB.varname + + " Not configured for SPNEGO authentication"); + } + builder.setSPNEGOPrincipal(spnegoPrincipal); + builder.setSPNEGOKeytab(spnegoKeytab); + builder.setUseSPNEGO(true); + } webServer = builder.build(); } }