Securing Thrift Traffic: Uncommon But Important Use Case

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 ...");
    server.serve();
    }
}

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);
 
    transport.close();
  }
}

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">
  <modelVersion>4.0.0</modelVersion>
 
  <groupId>org.doublecloud</groupId>
  <artifactId>ThriftDemo</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>
 
  <name>ThriftDemo</name>
  <url>http://maven.apache.org</url>
 
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>
 
  <pluginRepositories>
    <pluginRepository>
      <id>dtrott</id>
      <url>http://maven.davidtrott.com/repository</url>
    </pluginRepository>
  </pluginRepositories>
 
  <dependencies>
 
    <dependency>
      <groupId>org.apache.thrift</groupId>
      <artifactId>libthrift</artifactId>
      <version>0.9.1</version>
    </dependency>
 
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>1.5.8</version>
    </dependency>
 
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-log4j12</artifactId>
      <version>1.5.2</version>
    </dependency>
 
    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>1.2.14</version>
    </dependency>
 
    <dependency>
      <groupId>org.apache.commons</groupId>
      <artifactId>commons-lang3</artifactId>
      <version>3.1</version>
    </dependency>
 
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
 
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.thrift.tools</groupId>
        <artifactId>maven-thrift-plugin</artifactId>
        <version>0.1.10</version>
        <configuration>
          <thriftExecutable>C:\Dev\thrift-0.9.1\thrift-0.9.1.exe</thriftExecutable>
        </configuration>
        <executions>
          <execution>
            <id>thrift-sources</id>
            <phase>generate-sources</phase>
            <goals>
              <goal>compile</goal>
            </goals>
          </execution>
          <execution>
            <id>thrift-test-sources</id>
            <phase>generate-test-sources</phase>
            <goals>
              <goal>testCompile</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>2.3.2</version>
        <configuration>
          <source>1.7</source>
          <target>1.7</target>
        </configuration>
      </plugin>
    </plugins>
  </build>
 
</project>
This entry was posted in Software Development and tagged , . Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*

You may use these HTML tags and attributes <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

  • NEED HELP?


    My company has created products like vSearch ("Super vCenter"), vijavaNG APIs, EAM APIs, ICE tool. We also help clients with virtualization and cloud computing on customized development, training. Should you, or someone you know, need these products and services, please feel free to contact me: steve __AT__ doublecloud.org.

    Me: Steve Jin, VMware vExpert who authored the VMware VI and vSphere SDK by Prentice Hall, and created the de factor open source vSphere Java API while working at VMware engineering. Companies like Cisco, EMC, NetApp, HP, Dell, VMware, are among the users of the API and other tools I developed for their products, internal IT orchestration, and test automation.