This is an automated email from the ASF dual-hosted git repository.

prasanthj pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/hive.git


The following commit(s) were added to refs/heads/master by this push:
     new cd42db4  HIVE-21892: Trusted domain authentication should look at 
X-Forwarded-For header as well (Prasanth Jayachandran reviewed by Jason Dere, 
Ashutosh Bapat)
cd42db4 is described below

commit cd42db4ba746b48fdd36cf1cb9132663ea1a404f
Author: Prasanth Jayachandran <[email protected]>
AuthorDate: Wed Jun 19 15:27:22 2019 -0700

    HIVE-21892: Trusted domain authentication should look at X-Forwarded-For 
header as well (Prasanth Jayachandran reviewed by Jason Dere, Ashutosh Bapat)
---
 .../java/org/apache/hadoop/hive/conf/HiveConf.java |  7 +++++
 .../hive/service/cli/thrift/ThriftHttpServlet.java | 36 +++++++++++++---------
 2 files changed, 29 insertions(+), 14 deletions(-)

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 fcdfef3..5c58eb6 100644
--- a/common/src/java/org/apache/hadoop/hive/conf/HiveConf.java
+++ b/common/src/java/org/apache/hadoop/hive/conf/HiveConf.java
@@ -3486,6 +3486,13 @@ public class HiveConf extends Configuration {
         " it is empty, which means that all the connections to HiveServer2 are 
authenticated. " +
         "When it is non-empty, the client has to provide a Hive user name. Any 
password, if " +
         "provided, will not be used when authentication is skipped."),
+    
HIVE_SERVER2_TRUSTED_DOMAIN_USE_XFF_HEADER("hive.server2.trusted.domain.use.xff.header",
 false,
+      "When trusted domain authentication is enabled, the clients connecting 
to the HS2 could pass" +
+        "through many layers of proxy. Some proxies append its own ip address 
to 'X-Forwarded-For' header" +
+        "before passing on the request to another proxy or HS2. Some proxies 
also connect on behalf of client" +
+        "and may create a separate connection to HS2 without binding using 
client IP. For such environments, instead" +
+        "of looking at client IP from the request, if this config is set and 
if 'X-Forwarded-For' is present," +
+        "trusted domain authentication will use left most ip address from 
X-Forwarded-For header."),
     
HIVE_SERVER2_ALLOW_USER_SUBSTITUTION("hive.server2.allow.user.substitution", 
true,
         "Allow alternate user to be specified as part of HiveServer2 open 
connection request."),
     
HIVE_SERVER2_KERBEROS_KEYTAB("hive.server2.authentication.kerberos.keytab", "",
diff --git 
a/service/src/java/org/apache/hive/service/cli/thrift/ThriftHttpServlet.java 
b/service/src/java/org/apache/hive/service/cli/thrift/ThriftHttpServlet.java
index 292723e..f5411c6 100644
--- a/service/src/java/org/apache/hive/service/cli/thrift/ThriftHttpServlet.java
+++ b/service/src/java/org/apache/hive/service/cli/thrift/ThriftHttpServlet.java
@@ -150,16 +150,36 @@ public class ThriftHttpServlet extends TServlet {
           LOG.info("Could not validate cookie sent, will try to generate a new 
cookie");
         }
       }
+
+      // Set the thread local ip address
+      SessionManager.setIpAddress(clientIpAddress);
+
+      // get forwarded hosts address
+      String forwarded_for = request.getHeader(X_FORWARDED_FOR);
+      if (forwarded_for != null) {
+        LOG.debug("{}:{}", X_FORWARDED_FOR, forwarded_for);
+        List<String> forwardedAddresses = 
Arrays.asList(forwarded_for.split(","));
+        SessionManager.setForwardedAddresses(forwardedAddresses);
+      } else {
+        SessionManager.setForwardedAddresses(Collections.<String>emptyList());
+      }
+
       // If the cookie based authentication is not enabled or the request does 
not have a valid
       // cookie, use authentication depending on the server setup.
       if (clientUserName == null) {
         String trustedDomain = HiveConf.getVar(hiveConf, 
ConfVars.HIVE_SERVER2_TRUSTED_DOMAIN).trim();
-
+        final boolean useXff = HiveConf.getBoolVar(hiveConf, 
ConfVars.HIVE_SERVER2_TRUSTED_DOMAIN_USE_XFF_HEADER);
+        if (useXff && !trustedDomain.isEmpty() &&
+          SessionManager.getForwardedAddresses() != null && 
!SessionManager.getForwardedAddresses().isEmpty()) {
+          // general format of XFF header is 'X-Forwarded-For: client, proxy1, 
proxy2' where left most being the client
+          clientIpAddress = SessionManager.getForwardedAddresses().get(0);
+          LOG.info("Trusted domain authN is enabled. clientIp from 
X-Forwarded-For header: {}", clientIpAddress);
+        }
         // Skip authentication if the connection is from the trusted domain, 
if specified.
         // getRemoteHost may or may not return the FQDN of the remote host 
depending upon the
         // HTTP server configuration. So, force a reverse DNS lookup.
         String remoteHostName =
-                
InetAddress.getByName(request.getRemoteHost()).getCanonicalHostName();
+                InetAddress.getByName(clientIpAddress).getCanonicalHostName();
         if (!trustedDomain.isEmpty() &&
                 PlainSaslHelper.isHostFromTrustedDomain(remoteHostName, 
trustedDomain)) {
           LOG.info("No authentication performed because the connecting host " 
+ remoteHostName +
@@ -197,18 +217,6 @@ public class ThriftHttpServlet extends TServlet {
         SessionManager.setProxyUserName(doAsQueryParam);
       }
 
-      // Set the thread local ip address
-      SessionManager.setIpAddress(clientIpAddress);
-
-      // get forwarded hosts address
-      String forwarded_for = request.getHeader(X_FORWARDED_FOR);
-      if (forwarded_for != null) {
-        LOG.debug("{}:{}", X_FORWARDED_FOR, forwarded_for);
-        List<String> forwardedAddresses = 
Arrays.asList(forwarded_for.split(","));
-        SessionManager.setForwardedAddresses(forwardedAddresses);
-      } else {
-        SessionManager.setForwardedAddresses(Collections.<String>emptyList());
-      }
 
       // Generate new cookie and add it to the response
       if (requireNewCookie &&

Reply via email to