You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@hive.apache.org by "ASF GitHub Bot (Jira)" <ji...@apache.org> on 2022/11/10 20:35:00 UTC

[jira] [Work logged] (HIVE-26723) JDBC - Configurable canonical name checking for Kerberos

     [ https://issues.apache.org/jira/browse/HIVE-26723?focusedWorklogId=825077&page=com.atlassian.jira.plugin.system.issuetabpanels:worklog-tabpanel#worklog-825077 ]

ASF GitHub Bot logged work on HIVE-26723:
-----------------------------------------

                Author: ASF GitHub Bot
            Created on: 10/Nov/22 20:34
            Start Date: 10/Nov/22 20:34
    Worklog Time Spent: 10m 
      Work Description: schjan79 opened a new pull request, #3749:
URL: https://github.com/apache/hive/pull/3749

   
   ### What changes were proposed in this pull request?
   
   Hive JDBC client validates the host name by its canonical name by default. This behaviour leads to `SSLHandshakeExcpetion` when trying to connect using alias name with Kerberos authentication. To solve this issue a new connection property is introduced to be able disabling canonical host name check: 'enableCanonicalHostnameCheck' having default value `true`.
   
   When the property is not given in connection string (or its value is true) then the original behaviour is applied i.e. checking canonical host name.
   
   
   ### Why are the changes needed?
   
   It is not possible to create SSL connection with Kerberos authentication when the server certificate is not issued to the canonical host name but to an alternative domain name.
   
   See details about the exception and steps for reproducing in the [JIRA#26723](https://issues.apache.org/jira/browse/HIVE-26723)
   
   ### Does this PR introduce _any_ user-facing change?
   
   A new JDBC connection URL property has been introduced: `enableCanonicalHostnameCheck` to be able to turn off the canonical host name checking. Its default value is `true` so if it is not set the canonical host name is checked when building up the SSL connection.
   
   To turn off the canonical host name checking just add this property to the connection string, i.e:
   ```bash
   ./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"
   ```
    
   ### How was this patch tested?
   
   There are no new unit tests because the fix is in the `HiveConnection` constructor which contains lot of logic inside and also builds new SSL connections. 
   IMO it would have been far too much effort to mock the whole environment for creating unit tests against this tiny change. :(
   
   There wasn't any already existing test against `HiveConnection` that could be extended with this new feature/bugfix. It is misleading that there is a class having name `TestHiveConnection` but there is no any tests that would test the class `HiveConnection` itself.
   
   BTW It was tested manually: after this fix when the steps in JIRA are executed again using the new JARs then the SSL connection is created successfully, and I was able to execute queries.
    
   




Issue Time Tracking
-------------------

            Worklog Id:     (was: 825077)
    Remaining Estimate: 0h
            Time Spent: 10m

> JDBC - Configurable canonical name checking for Kerberos
> --------------------------------------------------------
>
>                 Key: HIVE-26723
>                 URL: https://issues.apache.org/jira/browse/HIVE-26723
>             Project: Hive
>          Issue Type: Bug
>            Reporter: János Schmidt
>            Priority: Major
>          Time Spent: 10m
>  Remaining Estimate: 0h
>
> h1. 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.
> h1. 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
>  
> h1. Steps to reproduce
> {code:bash}
> 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
>  {code}
>  
> h1. Deep dive
> When _*javax.net.debug*_ is set to {_}*all*{_}, then we can see that the canonical host name is used at certificate validation.
> {code:bash}
> 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]
>     },
> ... {code}
>  
>  



--
This message was sent by Atlassian Jira
(v8.20.10#820010)