I have a simple Thrift based java application I have written. It is really very simple, not much more than a "Hello World" message transport using Thrift in java. I have been told that I need to add Kerberos support to my message. I have done some googling and am surprised that Thrift does not already have Kerberos support in some form (or if it does, I cannot find it). I thought about writing my own wrapper using GSSAPI, but I cannot wrap/unwrap my Thrift message as that screws up the Thrift message format.
Has anyone ever Kerberized Thrift?.. or know how it would be done?
Thanks, in advance.
**So, I guess there is a way to do this via the SASL/GSS APIs. It confuses me as to why I don't see any great examples of this on the internet anywhere. However, I post an example of what I have created in the hopes that it will be a help to others... or that someone can correct my delusion of doing something useful here.
Sample Server code:
TServerSocket serverTransport = new TServerSocket(7911); // new server on port 7911
HelloWorldService.Processor<Iface> processor = new HelloWorldService.Processer<Iface>(new ThriftServerImpl()); // This is my thrift implementation for my server
Map<String, String> saslProperties = new HashMap<String, String>(); // need a map for properties
saslProperties.put(Sasl.QOP, "true");
saslProperties.put(Sasl.QOP, "auth-conf"); // authorization and confidentiality
TSaslServerTransport.Factory saslTransportFactory = new TSaslServerTransport.Factory(); // Creating the server definition
saslTransportFactory.addServerDefinition(
"GSSAPI", // tell SASL to use GSSAPI, which supports Kerberos
"myserviceprincipal", // base kerberos principal name - myprincipal/[email protected]
"my.server.com", // kerberos principal server - myprincipal/[email protected]
saslProps, // Properties set, above
new SaslRpcServer.SaslGssCallbackHandler())); // I don't know what this really does... but I stole it from Hadoop and it works.. so there.
Tserver server = new TThreadPoolServer(newTThreadPoolSErver.Args(serverTransport).transportFactory(saslTrasnportFactory).processor(processor));
server.serve(); // Thrift server start
Sample Client Code
TTransport transport = new TSocket("my.server.com", 7911); // client to connect to server and port
saslProperties.put(Sasl.QOP, "true");
saslProperties.put(Sasl.QOP, "auth-conf"); // authorization and confidentiality
TTransport saslTransport = new TSaslTransport(
"GSSAPI", // tell SASL to use GSSAPI, which supports Kerberos
null, // authorizationid - null
"myserviceprincipal", // base kerberos principal name - myprincipal/[email protected]
"my.server.com", // kerberos principal server - myprincipal/[email protected]
saslProps, // Properties set, above
null, // callback handler - null
transport); // underlying transport
TProtocol protocol = new TBinaryProtocol(saslTransport); // set up our new Thrift protocol
HelloWorldService.Client client = new HelloWorldService.Client(protocol); // Setup our thrift client
saslTransport.open();
String response = client.hello("Hi There"); // send message
System.out.println("response = " + response);
transport.close();
Other condsiderations:
* I set several java properties on both the client and the server.
- java.security.krb5.realm = MY.REALM // realm name
- java.security.krb5.kdc = my.kdc.com // kdc server
- javax.security.auth.useSubjectCredsOnly = false // Allow JAAS to get the TGT.
- java.security.auth.login.config = /etc/myapp/conf/jaas.conf - required jaas file
- sun.security.krb5.debug = true // helped with diagnosing problems.
* The jaas.conf file specified, above, needs to have two entries (maybe only one per server...). I cannot remember where I gleaned this information from.. but here is my file:
com.sun.security.jgss.initiate {
com.sun.security.auth.module.Krb5LoginModule required
useKeyTab=true
keyTab="/etc/myapp/conf/myapp.keytab"
useTicketCache=true
principal="myuserprincipal"
debug=true;
};
com.sun.security.jgss.accept {
com.sun.security.auth.module.Krb5LoginModule required
useKeyTab=true
keyTab="/etc/myapp/conf/myapp.keytab"
useTicketCache=false
principal="myserviceprincipal/my.server.com"
debug=true;
};
(back to considerations....)
* Despite having a Sasl.QOP of "auth-conf".. the first(?) message that gets transmitted is not encrypted. Maybe this is just a handshake, or something. The remaining messages appear to be encrypted, but this first one prints an ugly message to the console of "No encryption was performed by peer". It would be nice to not get that message, as it will cause grief down the road (warranted or not).
Anyway, I hope this helps someone... or alternatively can provoke some improvements that will help me. :) Hard to believe I spend 2-3 days doing this, and only a small amount of code came out of it , but I knew neither Kerberos or Thrift very well when I started.
Thanks for reading.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With