Home > Software Development > Securing Thrift Traffic: Uncommon But Important Use Case

Securing Thrift Traffic: Uncommon But Important Use Case

January 22nd, 2014 Leave a comment Go to comments

Thrift is mostly used for distributed systems which run mostly in house. There is no strong demand for securing the traffic on the wire. There are however use cases in which the Thrift services are exposed as a public service. In these use cases, the Thrift traffic should be secured with SSL/TLS. It comes with a price which more work on client and server on encryption and decryption. This is not a big deal for light load server, but for heavy load server it could be a problem. It can be mitigated with hardware acceleration on load balance servers between which and the client can be SSL, but not after that to the Thrift server.

The following are two Java files: one for the server, and the other for the client. The thrift IDL (hello.thrift) is exactly the same as we had seen in previous blog. That is the beauty of the design – the interface is independent of the underlying transport. In other words, for the same interface, you can have transport with a plain socket, secure socket, or even thrift over Http/Https. In the example, we just use secure socket.

Lost VMs or Containers? Too Many Consoles? Too Slow GUI? Time to learn how to "Google" and manage your VMware and clouds in a fast and secure HTML5 App.

Before going to the code, let’s first create the needed keys following the instructions from this very well-written blog.

keytool -genkeypair -alias certificatekey -keyalg RSA -validity 7 -keystore keystore.jks
keytool -export -alias certificatekey -keystore keystore.jks -rfc -file cert.cer
keytool -import -alias certificatekey -file cert.cer -keystore truststore.jks

The keystore.jks is for the server, and the truststore.jks is for the client. Optionally, you can configure the client to skip server certificate validation. Check out the source of vijava API for code on how to do it.

Because I use Maven project structure, I just copy them into src/main/resources under the project home. This step is important because the following code assumes it’s there. You can optionally provide full path in Java source code if you want to skip this step.

Here is the SecureHelloServer.java:

package org.doublecloud.thriftdemo;
import java.net.InetAddress;
import java.net.UnknownHostException;
import org.apache.thrift.server.TServer;
import org.apache.thrift.server.TThreadPoolServer;
import org.apache.thrift.transport.TSSLTransportFactory;
import org.apache.thrift.transport.TServerSocket;
import org.apache.thrift.transport.TTransportException;
public class SecureHelloServer
  public static void main(String[] args) throws TTransportException, UnknownHostException
    TSSLTransportFactory.TSSLTransportParameters params
            = new TSSLTransportFactory.TSSLTransportParameters();
    String jksFilePath = SecureHelloServer.class.getResource("/keystore.jks").toString();
    params.setKeyStore(jksFilePath.substring("file:/".length()), "doublecloud");
    TServerSocket serverTransport = TSSLTransportFactory.getServerSocket(
            7911, 10000, InetAddress.getByName("localhost"), params);
    Hello.Processor processor = new Hello.Processor(new HelloImpl());
    TServer server = new TThreadPoolServer(
            new TThreadPoolServer.Args(serverTransport).processor(processor));
    System.out.println("Starting server on port 7911 ...");

Here is the SecureHelloClient.java:

package org.doublecloud.thriftdemo;
import org.apache.thrift.TException;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.TSSLTransportFactory;
import org.apache.thrift.transport.TTransport;
public class SecureHelloClient
  public static void main(String[] args) throws TException
    TSSLTransportFactory.TSSLTransportParameters params
            = new TSSLTransportFactory.TSSLTransportParameters("TLS", null);
    String jksFilePath = SecureHelloClient.class.getResource("/truststore.jks").toString();
    params.setTrustStore(jksFilePath.substring("file:/".length()), "doublecloud");
    TTransport transport = TSSLTransportFactory.getClientSocket(
            "localhost", 7911, 10000, params);
    TProtocol protocol = new TBinaryProtocol(transport);
    Hello.Client client = new Hello.Client(protocol);
    String result = client.hi();
    System.out.println("return from server: " + result);

To build the project, you want to have pom.xml like the following. This is essentially the same as we had in the previous blog post.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
Categories: Software Development Tags: ,
  1. No comments yet.
  1. No trackbacks yet.