Uploaded image for project: 'Hive'
  1. Hive
  2. HIVE-26723

JDBC - Configurable canonical name checking for Kerberos

    XMLWordPrintableJSON

Details

    Description

      Probelm

      Hive JDBC converts the host name from connection string to the canonical name.  In some use cases  this behaviour leads to an `SSLHandshakeExcpetion` because the certificate of Hive server is not issued for the canonical host name but for an alias.

      Context

      • Hive server 2 is deployed into an Kubernetes/Openshift cluster having name hs2.subdomain.example.com ()
      • a wildcard certificate for a subdomain is added to the Java cacerts. i.e. *.subdomain.example.com
      • hive-beeline-3.1.3000.2022.0.8.0-3.jar
      • hive-jdbc-3.1.3000.2022.0.8.0-3.jar
      • open a Kerberos authenticated connection

       

      Steps to reproduce

      JAVA_TOOL_OPTIONS="-Djava.security.auth.login.config=gss-jaas.conf -Dsun.security.jgss.debug=true -Djavax.security.auth.useSubjectCredsOnly=false" ./beeline -u "jdbc:hive2://hs2.subdomain.example.com:443/default;transportMode=http;httpPath=cliservice;socketTimeout=60;ssl=true;retries=1;principal=myhiveprincipal/mydomain.example.com" --verbose=true
      HADOOP_HOME not set, executing beeline using JAVA
      Picked up JAVA_TOOL_OPTIONS: -Djava.security.auth.login.config=gss-jaas.conf -Dsun.security.jgss.debug=true -Djavax.security.auth.useSubjectCredsOnly=false
      !connect jdbc:hive2://hs2.subdomain.example.com:443/default;transportMode=http;httpPath=cliservice;socketTimeout=60;ssl=true;retries=1;principal=myhiveprincipal/mydomain.example.com '' [passwd stripped] 
      Connecting to jdbc:hive2://hs2.subdomain.example.com:443/default;transportMode=http;httpPath=cliservice;socketTimeout=60;ssl=true;retries=1;principal=myhiveprincipal/mydomain.example.com
      Search Subject for Kerberos V5 INIT cred (<<DEF>>, sun.security.jgss.krb5.Krb5InitCredential)
      Error: Could not open client transport with JDBC Uri: jdbc:hive2://hs2.subdomain.example.com:443/default;transportMode=http;httpPath=cliservice;socketTimeout=60;ssl=true;retries=1;principal=myhiveprincipal/mydomain.example.com: Could not establish connection to jdbc:hive2://hs2.subdomain.example.com:443/default;transportMode=http;httpPath=cliservice;socketTimeout=60;ssl=true;retries=1;principal=myhiveprincipal/mydomain.example.com: javax.net.ssl.SSLHandshakeException: Remote host terminated the handshake (state=08S01,code=0)
      java.sql.SQLException: Could not open client transport with JDBC Uri: jdbc:hive2://hs2.subdomain.example.com:443/default;transportMode=http;httpPath=cliservice;socketTimeout=60;ssl=true;retries=1;principal=myhiveprincipal/mydomain.example.com: Could not establish connection to jdbc:hive2://hs2.subdomain.example.com:443/default;transportMode=http;httpPath=cliservice;socketTimeout=60;ssl=true;retries=1;principal=myhiveprincipal/mydomain.example.com: javax.net.ssl.SSLHandshakeException: Remote host terminated the handshake
          at org.apache.hive.jdbc.HiveConnection.<init>(HiveConnection.java:406)
          at org.apache.hive.jdbc.HiveConnection.<init>(HiveConnection.java:280)
          at org.apache.hive.jdbc.HiveDriver.connect(HiveDriver.java:107)
          at java.sql.DriverManager.getConnection(DriverManager.java:664)
          at java.sql.DriverManager.getConnection(DriverManager.java:208)
          at org.apache.hive.beeline.DatabaseConnection.connect(DatabaseConnection.java:145)
          at org.apache.hive.beeline.DatabaseConnection.getConnection(DatabaseConnection.java:209)
          at org.apache.hive.beeline.Commands.connect(Commands.java:1680)
          at org.apache.hive.beeline.Commands.connect(Commands.java:1574)
          at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
          at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
          at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
          at java.lang.reflect.Method.invoke(Method.java:498)
          at org.apache.hive.beeline.ReflectiveCommandHandler.execute(ReflectiveCommandHandler.java:56)
          at org.apache.hive.beeline.BeeLine.execCommandWithPrefix(BeeLine.java:1463)
          at org.apache.hive.beeline.BeeLine.dispatch(BeeLine.java:1502)
          at org.apache.hive.beeline.BeeLine.connectUsingArgs(BeeLine.java:922)
          at org.apache.hive.beeline.BeeLine.initArgs(BeeLine.java:804)
          at org.apache.hive.beeline.BeeLine.begin(BeeLine.java:1115)
          at org.apache.hive.beeline.BeeLine.begin(BeeLine.java:1089)
          at org.apache.hive.beeline.BeeLine.mainWithInputRedirection(BeeLine.java:547)
          at org.apache.hive.beeline.BeeLine.main(BeeLine.java:529)
      Caused by: java.sql.SQLException: Could not establish connection to jdbc:hive2://hs2.subdomain.example.com:443/default;transportMode=http;httpPath=cliservice;socketTimeout=60;ssl=true;retries=1;principal=myhiveprincipal/mydomain.example.com;xenableCanonicalHostnameCheck=false: javax.net.ssl.SSLHandshakeException: Remote host terminated the handshake
          at org.apache.hive.jdbc.HiveConnection.openSession(HiveConnection.java:1115)
          at org.apache.hive.jdbc.HiveConnection.<init>(HiveConnection.java:378)
          ... 21 more
      Caused by: org.apache.thrift.transport.TTransportException: javax.net.ssl.SSLHandshakeException: Remote host terminated the handshake
          at org.apache.thrift.transport.THttpClient.flushUsingHttpClient(THttpClient.java:297)
          at org.apache.thrift.transport.THttpClient.flush(THttpClient.java:316)
          at org.apache.thrift.TServiceClient.sendBase(TServiceClient.java:73)
          at org.apache.thrift.TServiceClient.sendBase(TServiceClient.java:62)
          at org.apache.hive.service.rpc.thrift.TCLIService$Client.send_OpenSession(TCLIService.java:143)
          at org.apache.hive.service.rpc.thrift.TCLIService$Client.OpenSession(TCLIService.java:135)
          at org.apache.hive.jdbc.HiveConnection.openSession(HiveConnection.java:1169)
          at org.apache.hive.jdbc.HiveConnection.openSession(HiveConnection.java:1100)
          ... 22 more
      Caused by: javax.net.ssl.SSLHandshakeException: Remote host terminated the handshake
          at sun.security.ssl.SSLSocketImpl.handleEOF(SSLSocketImpl.java:1575)
          at sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1405)
          at sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1305)
          at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:440)
          at org.apache.http.conn.ssl.SSLConnectionSocketFactory.createLayeredSocket(SSLConnectionSocketFactory.java:436)
          at org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket(SSLConnectionSocketFactory.java:384)
          at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:142)
          at org.apache.http.impl.conn.BasicHttpClientConnectionManager.connect(BasicHttpClientConnectionManager.java:313)
          at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:393)
          at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:236)
          at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:186)
          at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89)
          at org.apache.http.impl.execchain.ServiceUnavailableRetryExec.execute(ServiceUnavailableRetryExec.java:85)
          at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
          at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185)
          at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:118)
          at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:56)
          at org.apache.thrift.transport.THttpClient.flushUsingHttpClient(THttpClient.java:251)
          ... 29 more
      Caused by: java.io.EOFException: SSL peer shut down incorrectly
          at sun.security.ssl.SSLSocketInputRecord.decode(SSLSocketInputRecord.java:167)
          at sun.security.ssl.SSLTransport.decode(SSLTransport.java:109)
          at sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1397)
          ... 45 more
       

       

      Deep dive

      When javax.net.debug is set to all, then we can see that the canonical host name is used at certificate validation.

      JAVA_TOOL_OPTIONS="-Djava.security.auth.login.config=gss-jaas.conf -Dsun.security.jgss.debug=true -Djavax.security.auth.useSubjectCredsOnly=false -Djavax.net.debug=all" ./beeline -u "jdbc:hive2://hs2.subdomain.example.com:443/default;transportMode=http;httpPath=cliservice;socketTimeout=60;ssl=true;retries=1;principal=myhiveprincipal/mydomain.example.com" --verbose=true
      
      ...
        "compression methods" : "00",
        "extensions"          : [
          "server_name (0)": {
            type=host_name (0), value=canonicalhostname.example.com
          },
          "supported_groups (10)": {
            "versions": [secp256r1, secp384r1, secp521r1, ffdhe2048, ffdhe3072, ffdhe4096, ffdhe6144, ffdhe8192]
          },
      
      ... 

       

       

      Attachments

        Issue Links

          Activity

            People

              schjan János Schmidt
              schjan János Schmidt
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Time Tracking

                  Estimated:
                  Original Estimate - Not Specified
                  Not Specified
                  Remaining:
                  Remaining Estimate - 0h
                  0h
                  Logged:
                  Time Spent - 1h
                  1h