0

I have an Ubuntu VM with R and Rserve installed for remote calls. I start Rserve in debug mode from the terminal with:

R CMD Rserve.dbg

And this is the output:

Rserve 1.8-6 () (C)Copyright 2002-2013 Simon Urbanek

Loading config file /etc/Rserv.conf
conf> command="remote", parameter="enable"
conf> command="plaintext", parameter="disable"
conf> command="encoding", parameter="utf8"
conf> command="pwdfile", parameter="/etc/RserveAuth.txt"
conf> command="auth", parameter="required"
conf> command="qap", parameter="disable"
conf> command="qap.tls.port", parameter="6311"
conf> command="tls.key", parameter="server.key"
conf> command="tls.cert", parameter="server.crt"
conf> command="tls.ca", parameter="rootCA.crt"
Loaded config file /etc/Rserv.conf

R version 3.5.3 (2019-03-11) -- "Great Truth"
Copyright (C) 2019 The R Foundation for Statistical Computing
Platform: x86_64-pc-linux-gnu (64-bit)

R is free software and comes with ABSOLUTELY NO WARRANTY.
You are welcome to redistribute it under certain conditions.
Type 'license()' or 'licence()' for distribution details.

  Natural language support but running in an English locale

R is a collaborative project with many contributors.
Type 'contributors()' for more information and
'citation()' on how to cite R or R packages in publications.

Type 'demo()' for some demos, 'help()' for on-line help, or
'help.start()' for an HTML browser interface to help.
Type 'q()' to quit R.

 - create_server(port = 6311, socket = <NULL>, mode = 0, flags = 0x800)
INFO: adding server 0x5618de18b9d0 (total 1 servers)
Rserve: Ok, ready to answer queries.

I generated the key and self-signed certificates with OPENSSL.

Now on the client side, I have a Java application just requesting the version of R that Rserve is sitting on top of as a test of functionality:

import org.rosuda.REngine.REXP;
import org.rosuda.REngine.Rserve.RConnection;

public class RJava {
    public static void main(String[] args) throws Exception{
        //Run R code on remote R installation via Rserve.
        String remoteIP="10.16.24.63"; //Ubuntu VM Box
        int port=6311;
        String user="TEST";
        String pass="12345";

        //Connect to the remote server.
        RConnection connection = new RConnection(remoteIP,port);//Remote server
        connection.login(user, pass);

        //Run a command.
        REXP x = connection.eval("R.version.string");
        System.out.println(x.asString());

        //Disconnect.
        connection.close();
    }
}

The problem is the client code hangs on the call to the RConnection constructor. I've let it go for ten minutes and nothing changes until I kill the server. On the server side I just see:

INFO: accepted connection for server 0x5618de18b9d0, calling connected
connection accepted.

I can't find any documentation to help at this point. Is this possibly a client configuration problem?

Also, if I remove all the TLS configuration items from Rserv.conf, Rserve will work as expected no problem with this client code, so I know it is set up correctly.

wcg5003
  • 53
  • 1
  • 7

1 Answers1

0

I figured this out on my own. It was in fact a client configuration problem. I needed to create the RConnection with an SSLSocket and also import the server certificate to the java truststore.

Relevant client code changed to this:

SSLSocketFactory sslsocketfactory = (SSLSocketFactory)SSLSocketFactory.getDefault();
SSLSocket sslsocket = (SSLSocket) sslsocketfactory.createSocket(remoteIP, port);
//Connect to the remote server.
RConnection connection = new RConnection(sslsocket);

N.B. the constructor RConnection(Socket s) is apparently not in the REngine jar, so I grabbed the source itself and put that in my project because it is included there.

Running at this point threw a javax.net.ssl.SSLHandshakeException because the cert wasn't in the truststore. So I withdrew the cert from the server using OPENSSL like this:

echo "" | openssl s_client -connect 10.16.24.63:6311 | openssl x509 -out server.crt

Then I moved that cert file to %JAVA_HOME%\jre\lib\security and ran this to import the certificate:

keytool -import -alias myAlias -file server.crt -keystore cacerts -storepass changeit

And it works! Wireshark confirms all the packets are now encrypted.

Resources:

https://stats-rosuda-devel.listserv.uni-augsburg.narkive.com/g5VM1afB/encryption-with-rserve-1-8-1

https://www.baeldung.com/java-ssl

Digital Certificate: How to import .cer file in to .truststore file using?

wcg5003
  • 53
  • 1
  • 7