GNU/Linux >> Linux Esercitazione >  >> Linux

Errore JDBC di SQL Server su Java 8:il driver non è stato in grado di stabilire una connessione sicura a SQL Server utilizzando la crittografia SSL (Secure Sockets Layer)

Ho attivato la registrazione SSL nella JVM Java 8 su un'istanza Linux che riproduce il problema. La registrazione SSL è attivata utilizzando -Djavax.net.debug=ssl:handshake:verbose . Questo ha rivelato alcune informazioni utili.

La soluzione alternativa che stiamo utilizzando in produzione e che ha dimostrato di funzionare per noi è impostare questo parametro su JVM:

 -Djdk.tls.client.protocols=TLSv1

Se desideri maggiori dettagli, continua a leggere.

Su un server in cui il problema può essere riprodotto (di nuovo, solo il 5-10% delle volte), ho osservato quanto segue:

*** ClientHello, TLSv1.2
--- 8<-- SNIP -----
main, WRITE: TLSv1.2 Handshake, length = 195
main, READ: TLSv1.2 Handshake, length = 1130
*** ServerHello, TLSv1.2
--- 8<-- SNIP -----
%% Initialized:  [Session-79, TLS_DHE_RSA_WITH_AES_128_GCM_SHA256]
** TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
--- 8<-- SNIP -----
Algorithm: [SHA1withRSA]
--- 8<-- SNIP -----
*** Diffie-Hellman ServerKeyExchange
--- 8<-- SNIP -----
*** ServerHelloDone
*** ClientKeyExchange, DH
--- 8<-- SNIP -----
main, WRITE: TLSv1.2 Handshake, length = 133
--- 8<-- SNIP -----
main, WRITE: TLSv1.2 Change Cipher Spec, length = 1
*** Finished
verify_data:  { 108, 116, 29, 115, 13, 26, 154, 198, 17, 125, 114, 166 }
***
main, WRITE: TLSv1.2 Handshake, length = 40
main, called close()
main, called closeInternal(true)
main, SEND TLSv1.2 ALERT:  warning, description = close_notify
main, WRITE: TLSv1.2 Alert, length = 26
main, called closeSocket(true)
main, waiting for close_notify or alert: state 5
main, received EOFException: ignored
main, called closeInternal(false)
main, close invoked again; state = 5
main, handling exception: java.io.IOException: SQL Server returned an incomplete response. The connection has been closed. ClientConnectionId:12a722b3-d61d-4ce4-8319-af049a0a4415

Nota che TLSv1.2 viene selezionato dal server del database e utilizzato in questo scambio. Ho osservato che, quando le connessioni falliscono dal servizio Linux problematico, TLSv1.2 è SEMPRE il livello selezionato. Tuttavia, le connessioni non SEMPRE falliscono quando viene utilizzato TLSv1.2. Falliscono solo il 5-10% delle volte.

Ora ecco uno scambio da un server che NON presenta il problema. Tutto il resto è uguale. Cioè, connessione allo stesso database, stessa versione della JVM (Java 1.8.0_60), stesso driver JDBC, ecc. Si noti che, qui, TLSv1 viene selezionato dal server del database invece di TLSv1.2 come nel caso del server difettoso.

*** ClientHello, TLSv1.2
--- 8<-- SNIP -----
main, WRITE: TLSv1.2 Handshake, length = 207
main, READ: TLSv1 Handshake, length = 604
*** ServerHello, TLSv1
--- 8<-- SNIP -----
Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA
--- 8<-- SNIP -----
%% Initialized:  [Session-79, TLS_RSA_WITH_AES_128_CBC_SHA]
** TLS_RSA_WITH_AES_128_CBC_SHA
--- 8<-- SNIP -----
Algorithm: [SHA1withRSA]
--- 8<-- SNIP -----
***
*** ServerHelloDone
*** ClientKeyExchange, RSA PreMasterSecret, TLSv1
--- 8<-- SNIP -----
main, WRITE: TLSv1 Handshake, length = 134
main, WRITE: TLSv1 Change Cipher Spec, length = 1
*** Finished
verify_data:  { 26, 155, 166, 89, 229, 193, 126, 39, 103, 206, 126, 21 }
***
main, WRITE: TLSv1 Handshake, length = 48
main, READ: TLSv1 Change Cipher Spec, length = 1
main, READ: TLSv1 Handshake, length = 48
*** Finished

Pertanto, quando TLSv1 viene negoziato tra Linux JVM e SQL Server, le connessioni hanno SEMPRE successo. Quando TLSv1.2 viene negoziato, otteniamo sporadici errori di connessione.

(Nota:Java 7 (1.7.0_51) negozia sempre TLSv1, motivo per cui il problema non si è mai verificato per noi con una JVM Java 7.)

Le domande aperte che abbiamo ancora sono:

  1. PERCHÉ è che la stessa JVM Java 8 eseguita da 2 diversi server Linux negozierà sempre TLSv1, ma quando si connette da un altro server Linux negozia sempre TLSv1.2.
  2. E anche perché le connessioni negoziate TLSv1.2 hanno successo la maggior parte delle volte, ma non tutte, su quel server?

Aggiornamento 10/06/2017: Questo post di Microsoft descrive il problema e la soluzione proposta.

Risorse:

http://www.infoworld.com/article/2849292/operating-systems/more-patch-problems-reported-with-the-ms14-066-kb-2992611-winshock-mess.html

http://www.infoworld.com/article/2849292/operating-systems/more-patch-problems-reported-with-the-ms14-066-kb-2992611-winshock-mess.html

http://blogs.msdn.com/b/jdbcteam/archive/2008/09/09/the-driver-could-not-establish-a-secure-connection-to-sql-server-by-using-secure- socket-layer-ssl-encryption.aspx

Java 8, JCE Unlimited Strength Policy e Handshake SSL su TLS

http://blogs.msdn.com/b/saponsqlserver/archive/2013/05/10/analyzing-jdbc-connection-issues.aspx

https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html#descPhase2

https://blogs.oracle.com/java-platform-group/entry/java_8_will_use_tls


Questo sembra essere stato risolto nella versione 4.2 del driver MS SQL JDBC. Ho creato un programma in cui mi sono connesso al server 1000 volte, facendo una pausa di 100 ms tra ogni tentativo. Con la versione 4.1 sono riuscito a riprodurre ogni volta il problema, anche se si è verificato solo sporadicamente. Con la versione 4.2 non sono riuscito a riprodurre il problema.


Prima di aggiornare SQL JDBC Driver, controlla prima la compatibilità:

  • Sqljdbc.jar richiede un JRE di 5 e supporta l'API JDBC 3.0
  • Sqljdbc4.jar richiede un JRE di 6 e supporta l'API JDBC 4.0
  • Sqljdbc41.jar richiede un JRE di 7 e supporta l'API JDBC 4.1
  • Sqljdbc42.jar richiede un JRE di 8 e supporta l'API JDBC 4.2

Fonte:https://www.microsoft.com/en-us/download/details.aspx?id=11774


Linux
  1. Modifica il timeout MySQL su un server

  2. Come proteggere una connessione SSL con Apache su Ubuntu 18.04

  3. FATAL:Errore modulo non trovato utilizzando modprobe

  4. Utilizzo di openssl per ottenere il certificato da un server

  5. httpd:impossibile determinare in modo affidabile il nome di dominio completo del server, utilizzando 127.0.0.1 per ServerName

Come correggere l'errore rifiutato dalla connessione SSH

Correzione:impossibile stabilire una connessione FTP a un server SFTP in FileZilla

Risoluzione dei problemi:errori di connessione al server

Errore FTP:impossibile connettersi al server - Il criterio 534 richiede SSL

Correzione dell'errore del tubo rotto con la connessione SSH

WSL - GEDIT Impossibile inizializzare il server:Impossibile connettersi:connessione rifiutata