2

I'm trying to get logging information on the server side when a client tries to connect but fails using SSL.

The obvious way to do this is to set the flag -Djavax.net.debug=ssl, but this won't work, because:

  1. it's way too verbose
  2. any of the modifiers (i.e. -Djavax.net.debug=ssl:record:handshake etc) won't work (this is a known bug referenced here, yet a lot of sites on the web suggest using these).

I've thought of capturing all Standard output to a file and filtering from there, but there are other messages that are supposed to go to standard out that i'd also catch.

Someone recommended using logger, but i'm not sure if it's possible to capture javax.net.debug output using logger

What I need

Is there any way to output logging information for ssl that isn't 200+ lines per request or

is there any way to get the ssl logging to go to a separate file while leaving everything else unaffected.

Thanks!

Eugène Adell
  • 3,089
  • 2
  • 18
  • 34
zyzz
  • 85
  • 2
  • 11

2 Answers2

0

This was asked already without any answer.

There is no way to go get rid of the JDK-8044609 bug which doesn't respect the verbosity configuration, and, worse, the mixing of outputs coming from different threads. It's problematic by design.

If you were going to code anything and not only rely on ready to use servers (Tomcat, JBOSS,..), there are a couple of things you can do :

  • Coding your own classes listed in the JSSE Customization will inhibit the default output logging
  • Implement your own output that will catch all calls to System.out and only print the messages that you want. This might be difficult, and you have 2 ways to choose a message to print or ignore : checking it with a REGEX, or checking from which thread it's coming.

Replacing the default output is given here (tested successfully). Identifying the calling thread is given here , also tested, here is a sample output of mixing these 2 solutions :

->sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:254)
->HTTPSClient.main(HTTPSClient.java:24)
->-->
->%% No cached client session
->java.lang.Thread.getStackTrace(Thread.java:1556)
->Interceptor.println(HTTPSClient.java:93)
->sun.security.ssl.HandshakeMessage$ClientHello.print(HandshakeMessage.java:306)
->sun.security.ssl.Handshaker.kickstart(Handshaker.java:1064)
->sun.security.ssl.SSLSocketImpl.kickstartHandshake(SSLSocketImpl.java:1487)
->sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1351)
->sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403)
->sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387)
->sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:559)
->sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
->sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1546)
->sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1474)
->sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:254)
->HTTPSClient.main(HTTPSClient.java:24)
->-->
->*** ClientHello, TLSv1.2
->RandomCookie:  ->GMT: 1504449179 ->bytes = { 240->, 208->, 36->, 132->, 222->, 113->, 11->, 186->, 189->, 196->, 141->, 203->, 159->, 37->, 198->, 123->, 253->, 150->, 193->, 44->, 78->, 85->, 128->, 220->, 54->, 90->, 33->, 16->java.lang.Thread.getStackTrace(Thread.java:1556)
->Interceptor.println(HTTPSClient.java:93)
->sun.security.ssl.RandomCookie.print(RandomCookie.java:87)
->sun.security.ssl.HandshakeMessage$ClientHello.print(HandshakeMessage.java:310)
->sun.security.ssl.Handshaker.kickstart(Handshaker.java:1064)

is there any way to get the ssl logging to go to a separate file while leaving everything else unaffected.

Yes, now you can deduce from above how to do. Identify the calling thread and send to different outputs.

The solution might look harsh and not the one you expected, but as you see it wasn't answered for years and the Java dev team didn't move too.

Eugène Adell
  • 3,089
  • 2
  • 18
  • 34
0

I've written a debugging JSSE provider that lets you do your own method level logging, by adding a proxy for the trust manager and key manager, with an example showing integration into SLF4J. You turn that on and it should do what you want.

<dependency>
    <groupId>com.tersesystems.debugjsse</groupId>
    <artifactId>debugjsse</artifactId>
    <version>0.1.0-SNAPSHOT</version>
</dependency>

https://tersesystems.com/blog/2018/07/27/debug-java-tls-ssl-provider/

The only other way I know of is to swap out the debug method, which can be done using https://tersesystems.com/blog/2014/03/02/monkeypatching-java-classes/. Even with that, it's inconsistent, because some classes use the Debug class and some directly write to System.out.println. There was a patch but it never got anywhere.

Will Sargent
  • 4,346
  • 1
  • 31
  • 53