Developing for Splunk Enterprise

"No appropriate protocol (protocol is disabled or cipher suites are inappropriate)" when connecting to Splunk Enterprise

Communicator

Hi all,

I've been doing some testing on my local machine prior to going to any test or live Splunk environments, but, for some reason, it's started throwing exceptions when trying to connect from Eclipse to my localhost:8089 Splunk instance. This previously worked and I've changed no config, so I'm not really sure what's happened.

Was previously using 6.1.3, but upgraded to 6.2.1 and am experiencing the same issues. The Splunk connection code in my java app hasn't changed in over a month, so I'm at a bit of a loss. What's more is the current version of this code is in production and connects to local lightweight forwarders without any issues.

Exception below:
2015/01/23 15:11:42 INFO com.companyname.perfmonreader.splunk.SplunkConnectHandler - Setting up Splunk connection service
Exception in thread "Thread-0" java.lang.RuntimeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)
at com.splunk.HttpService.send(HttpService.java:345)
at com.splunk.Service.send(Service.java:1268)
at com.splunk.HttpService.post(HttpService.java:243)
at com.splunk.Service.login(Service.java:1099)
at com.splunk.Service.login(Service.java:1079)
at com.splunk.Service.connect(Service.java:183)
at com.companyname.perfmonreader.splunk.SplunkConnectHandler.run(SplunkConnectHandler.java:20)
at java.lang.Thread.run(Unknown Source)
Caused by: javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)
at sun.security.ssl.Handshaker.activate(Unknown Source)
at sun.security.ssl.SSLSocketImpl.kickstartHandshake(Unknown Source)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
at sun.net.www.protocol.https.HttpsClient.afterConnect(Unknown Source)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.getOutputStream0(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(Unknown Source)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(Unknown Source)
at com.splunk.HttpService.send(HttpService.java:338)
... 7 more

The code being used is as follows (simplified for readability):
loginArgs.setUsername(splunkProps.getProperty("username"));
loginArgs.setPassword(splunkProps.getProperty("password"));
loginArgs.setPort(Integer.parseInt(splunkProps.getProperty("port")));
loginArgs.setHost(InetAddress.getLocalHost().getHostName());
SplunkServiceHandler.setService(Service.connect(loginArgs));

Any help would be greatly appreciated!

Cheers,
Alex

Tags (1)
1 Solution

Engager

Hi Alex,

Splunk needs to release a new jar without SSLv3 hardwired (in HttpService.java) in order to make this work with the latest Java 8. Meanwhile you need to stick with Java 7 or build your own jar from the SDK package and use SSLv2 instead.

View solution in original post

Engager

It may works if you just change the scheme from "https" to "http" while setting this in ServiceArgs. I have faced and resolved it by this way with splunk jar 1.5.0.0

Path Finder

Hi Sunrej, I am getting the following error in SDK 1.5.0 Did you also get it? Or do you know how to resolve it? I have changed https to http in .splunkrc file. And I am using JRE7

java.lang.RuntimeException: Connection reset
        at com.splunk.HttpService.send(HttpService.java:427)
        at com.splunk.Service.send(Service.java:1293)
        at com.splunk.HttpService.post(HttpService.java:308)
        at com.splunk.Service.login(Service.java:1122)
        at com.splunk.Service.login(Service.java:1101)
        at com.splunk.Service.connect(Service.java:187)
        at com.splunk.examples.search.Program.run(Unknown Source)
        at com.splunk.examples.search.Program.main(Unknown Source)
Caused by: java.net.SocketException: Connection reset
        at java.net.SocketInputStream.read(SocketInputStream.java:196)
        at java.net.SocketInputStream.read(SocketInputStream.java:122)
        at java.io.BufferedInputStream.fill(BufferedInputStream.java:235)
        at java.io.BufferedInputStream.read1(BufferedInputStream.java:275)
        at java.io.BufferedInputStream.read(BufferedInputStream.java:334)
        at sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:690)
        at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:633)
        at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:661)
        at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1324)
        at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:468)
        at com.splunk.HttpService.send(HttpService.java:425)
        ... 7 more
0 Karma

Splunk Employee
Splunk Employee

The issue is now fixed in the version 1.4.0 of Splunk, the code has been redesigned.
SSLv3 is disabled by default in Java 1.8 in favour of TLS but in the Splunk API the protocol SSLv3 is still enabled by default.
To use TLSv1.2, there is no longer need to modify the code in "com.splunk.HttpService".
As the code in this class has been modified, it offers a convenient way to override a method to use TLSv1.2 instead of the default SSLv3.

The method to override is "setSslSecurityProtocol()":

HttpService.setSslSecurityProtocol(SSLSecurityProtocol.TLSv1_2)

The sample code below illustrates the new way to override SSlv3 by TLSv1.2 (tested with Java 1.8.x and Splunk Java SDK 1.4.0):

import java.io.*;
import com.splunk.*;

public class SearchExport {
    public static void main(String[] args) throws IOException {
        if(args.length != 4) {
            System.out.println("Usage:\n\tjava SplunkConnect <username> <password> <hostname> <port>");
            System.out.println("\tE.G. java SplunkConnect admin P@55w0rd 127.0.0.1 8089\n");
            System.exit(1);
        }


        /* Overriding the static method setSslSecurityProtocol to implement the security protocol of choice */
        HttpService.setSslSecurityProtocol(SSLSecurityProtocol.TLSv1_2);
        /* end comment for overriding the method setSslSecurityProtocol */

        ServiceArgs loginArgs = new ServiceArgs();
        loginArgs.setUsername(args[0]);
        loginArgs.setPassword(args[1]);
        loginArgs.setHost(args[2]);
        loginArgs.setPort(new Integer(args[3]));

        Service svc = Service.connect(loginArgs);
        JobExportArgs exportArgs = new JobExportArgs();
        exportArgs.setSearchMode(JobExportArgs.SearchMode.NORMAL);
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        System.out.print("Enter a search string then press <ENTER>: ");
        String mySearch = br.readLine();

        if(!(mySearch.trim().startsWith("|")) && !(mySearch.substring(0, 6).equalsIgnoreCase("search"))) {
            mySearch = "search " + mySearch;    
        }

        InputStream exportSearch = svc.export(mySearch, exportArgs);
        MultiResultsReaderXml resultsReader = new MultiResultsReaderXml(exportSearch);

        long counter = 0;
        for(SearchResults searchResults : resultsReader) {
            for(Event event : searchResults) {
                System.out.println("**** Event " + ++counter + " ****");
                for(String key : event.keySet()) {
                    System.out.println("\t" + key + ": " + event.get(key));
                }
            }
        }
        resultsReader.close();
    }
}

Path Finder

April 14, 2015 - same issue - tried the #jdk.tls.disabledAlgorithms=SSLv3 approach and I now get:
"java.lang.RuntimeException: Unrecognized SSL message, plaintext connection?"

Editing and rebuilding the SDK doesn't seem very user friendly, surely Splunk isn't expecting developers to do that!

0 Karma

Explorer

Any chance this new 1.4.0 version will become available in the http://splunk.artifactoryonline.com/splunk/ext-releases-local repository? I would love to be able to use this.

0 Karma

Splunk Employee
Splunk Employee

We’ve just released version 1.4 of the Splunk SDK for Java. This version brings support for Java version 8, including the ability to manually configure the SSL security protocol of your choosing!

Get the bits here: http://dev.splunk.com/goto/sdk-java-jar
Read the docs here: http://dev.splunk.com/view/java-sdk/SP-CAAAEK3

0 Karma

Engager

This a comment but not an answer. I have downloaded the latest Splunk and SDK but I continue to get the : "No appropriate protocol" error. On previous versions I commented the "#jdk.tls.disabledAlgorithms=SSLv3" line in java.security and that worked. But with the latest versions (downloaded today) I cannot query Splunk from my Java app. I looked in the code and the SDK still uses SSLv3 in HttpService.java. Any other suggestions? Are their any other security flags that could be set to stop SSLv3?

0 Karma

Explorer

Now SSLv3 is disabled by default in updated versions of JDK.
As alternative you can update the /lib/security/java.security file and comment the line #jdk.tls.disabledAlgorithms=SSLv3
Same issue and Worked here.

Path Finder

Just figured this out myself.

Long morning of rolling back packages to figure this out.

Engager

Worked for me, thanks!

0 Karma

Engager

This works

0 Karma

Splunk Employee
Splunk Employee

You can recompile the jar after editing the HttpService.java to assign the appropriate SSLContext if SSLv3 is not appropriate:

--- /splunk/src/splunk-sdk-java/splunk-sdk-java-1.3.1/splunk/com/splunk/HttpService.java 2014-08-21 14:07:12.000000000 -0400 
+++ /splunk/src/splunk-sdk-java/patch/splunk/com/splunk/HttpService.java 2014-12-16 00:12:59.655857080 -0500 
@@ -397,7 +397,7 @@ 
} 
}; 
try { 
- SSLContext context = SSLContext.getInstance("SSL"); 
+ SSLContext context = SSLContext.getInstance("TLSv1.2"); 
context.init(null, trustAll, new java.security.SecureRandom()); 
return new SSLv3SocketFactory(context.getSocketFactory()); 
} catch (Exception e) { 
@@ -408,7 +408,7 @@ 
private static final class SSLv3SocketFactory extends SSLSocketFactory { 
private final SSLSocketFactory delegate; 

- public static final String[] PROTOCOLS = {"SSLv3"}; 
+ public static final String[] PROTOCOLS = {"TLSv1.2"}; 

private SSLv3SocketFactory(SSLSocketFactory delegate) { 
this.delegate = delegate;

Reference:
http://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html#SSLContext

Engager

Hi Alex,

Splunk needs to release a new jar without SSLv3 hardwired (in HttpService.java) in order to make this work with the latest Java 8. Meanwhile you need to stick with Java 7 or build your own jar from the SDK package and use SSLv2 instead.

View solution in original post

Communicator

Ah that was daft of me. I had updated Java a week before to 8u31 (previously 8u25, I think) and this broke it. Tried recompiling with different SSL, but just ended up rolling back Java.

Many thanks!

0 Karma

Explorer

Now SSLv3 is disabled by default in updated versions of JDK.
As alternative you can update the /lib/security/java.security file and comment the line #jdk.tls.disabledAlgorithms=SSLv3
Same issue and Worked here.