ssl - Troubleshooting Java RMI Client network connection refusal -
this has never worked before - i'm setting environment first time.
multiple updates below
i've got rmi server running in "daemon" type of process because want running @ system startup service (not using xinitd feature), can utilize ssl, , can give commands daemon pertaining goes registry via separate mechanism. (iow, i'm not using runtime.getruntime().exec("rmiregistry 2020");
)
i know rmi server , running because works:
telnet localhost <port>
my client code encodes lot of environment varriables ssl command line start - later, i'll programatically, now, starts with:
$ java -djavax.net.ssl.truststore=/var/rmissl/truststore -djavax.net.ssl.truststorepassword=<pwd> -djava.rmi.server.hostname=localhost my.package.test
at first got was:
java.rmi.connectexception: connection refused host: localhost; nested excepti on is: java.net.connectexception: connection refused
which pretty useless, except there error. so, double checked manner of things, , put in trace statements, flushes, , added command line:
-djavax.net.debug=all
this helped coinsiderably, still hard figure out error was, put suspected line loop, catching exception, , it's clear it's lookup specific object within registry that's problem, though error message sure seems misleading. here's got:
$ java -djavax.net.debug=all -djavax.net.ssl.truststore=/var/rmissl/truststore -djavax.net.ssl.truststorepassword=<pwd> -djava.rmi.server.hostname=localhost my.package.test setup security manager. find registry. lookup testclient. keystore : keystore type : jks keystore provider : init keystore init keymanager of type sunx509 truststore is: /var/rmissl/truststore truststore type : jks truststore provider : init truststore adding trusted cert: subject: cn= <my cert> issuer: cn= <my cert> algorithm: rsa; serial number: 0x<number> valid <dates> trigger seeding of securerandom done seeding securerandom ignoring unavailable cipher suite: tls_ecdhe_rsa_with_aes_256_cbc_sha ignoring unavailable cipher suite: tls_dhe_rsa_with_aes_256_cbc_sha ignoring unavailable cipher suite: tls_ecdh_rsa_with_aes_256_cbc_sha ignoring unsupported cipher suite: tls_dhe_dss_with_aes_128_cbc_sha256 ignoring unsupported cipher suite: tls_dhe_dss_with_aes_256_cbc_sha256 ignoring unsupported cipher suite: tls_dhe_rsa_with_aes_128_cbc_sha256 ignoring unsupported cipher suite: tls_ecdh_rsa_with_aes_128_cbc_sha256 ignoring unsupported cipher suite: tls_dhe_rsa_with_aes_256_cbc_sha256 ignoring unsupported cipher suite: tls_ecdhe_rsa_with_aes_256_cbc_sha384 ignoring unsupported cipher suite: tls_ecdh_ecdsa_with_aes_256_cbc_sha384 ignoring unsupported cipher suite: tls_rsa_with_aes_256_cbc_sha256 ignoring unavailable cipher suite: tls_ecdhe_ecdsa_with_aes_256_cbc_sha ignoring unsupported cipher suite: tls_ecdhe_rsa_with_aes_128_cbc_sha256 ignoring unsupported cipher suite: tls_ecdhe_ecdsa_with_aes_256_cbc_sha384 ignoring unavailable cipher suite: tls_dhe_dss_with_aes_256_cbc_sha ignoring unsupported cipher suite: tls_ecdh_rsa_with_aes_256_cbc_sha384 ignoring unsupported cipher suite: tls_ecdhe_ecdsa_with_aes_128_cbc_sha256 ignoring unsupported cipher suite: tls_ecdh_ecdsa_with_aes_128_cbc_sha256 ignoring unavailable cipher suite: tls_ecdh_ecdsa_with_aes_256_cbc_sha ignoring unavailable cipher suite: tls_rsa_with_aes_256_cbc_sha ignoring unsupported cipher suite: tls_rsa_with_aes_128_cbc_sha256 java.rmi.connectexception: connection refused host: localhost; nested exception is: java.net.connectexception: connection refused enter 'quit' exit: ignoring unavailable cipher suite: tls_ecdhe_rsa_with_aes_256_cbc_sha ignoring unavailable cipher suite: tls_dhe_rsa_with_aes_256_cbc_sha ignoring unavailable cipher suite: tls_ecdh_rsa_with_aes_256_cbc_sha ignoring unsupported cipher suite: tls_dhe_dss_with_aes_128_cbc_sha256 ignoring unsupported cipher suite: tls_dhe_dss_with_aes_256_cbc_sha256 ignoring unsupported cipher suite: tls_dhe_rsa_with_aes_128_cbc_sha256 ignoring unsupported cipher suite: tls_ecdh_rsa_with_aes_128_cbc_sha256 ignoring unsupported cipher suite: tls_dhe_rsa_with_aes_256_cbc_sha256 ignoring unsupported cipher suite: tls_ecdhe_rsa_with_aes_256_cbc_sha384 ignoring unsupported cipher suite: tls_ecdh_ecdsa_with_aes_256_cbc_sha384 ignoring unsupported cipher suite: tls_rsa_with_aes_256_cbc_sha256 ignoring unavailable cipher suite: tls_ecdhe_ecdsa_with_aes_256_cbc_sha ignoring unsupported cipher suite: tls_ecdhe_rsa_with_aes_128_cbc_sha256 ignoring unsupported cipher suite: tls_ecdhe_ecdsa_with_aes_256_cbc_sha384 ignoring unavailable cipher suite: tls_dhe_dss_with_aes_256_cbc_sha ignoring unsupported cipher suite: tls_ecdh_rsa_with_aes_256_cbc_sha384 ignoring unsupported cipher suite: tls_ecdhe_ecdsa_with_aes_128_cbc_sha256 ignoring unsupported cipher suite: tls_ecdh_ecdsa_with_aes_128_cbc_sha256 ignoring unavailable cipher suite: tls_ecdh_ecdsa_with_aes_256_cbc_sha ignoring unavailable cipher suite: tls_rsa_with_aes_256_cbc_sha ignoring unsupported cipher suite: tls_rsa_with_aes_128_cbc_sha256 java.rmi.connectexception: connection refused host: localhost; nested exception is: java.net.connectexception: connection refused enter 'quit' exit:
note loop structure permits better analysis of error; output regarding truststore , certificate(s) isn't repeated.
this suggests me it's not finding suitable cipher suite use, on same system! client , server both looking same truststores, etc.
in case thinks helpful, here's client code:
import java.rmi.*; import java.rmi.registry.*; import java.io.*; import java.net.*; import javax.rmi.ssl.*; public class test { private static string serverhost = "localhost"; private static int serverport = 6543; private static registry registry; private static testclient c; public static void main(string[] args) throws exception { msg("setup security manager."); system.setsecuritymanager(new rmisecuritymanager()); msg("find registry."); registry = locateregistry.getregistry(serverhost, serverport, new sslrmiclientsocketfactory()); msg("lookup testclient."); boolean keeplooping = true; while (keeplooping) { try { c = (testclient)registry.lookup(testclient.class.getsimplename()); } catch (exception e) { msg(e.tostring()); } keeplooping = !(prompt("enter 'quit' exit: ").equals("quit")); } } public static void msg(string message) { system.out.println(message); system.out.flush(); } public static string prompt(string prompt) { string out = ""; bufferedreader br = new bufferedreader(new inputstreamreader(system.in)); try { system.out.print(prompt); out = br.readline(); } catch (ioexception e) { msg("io error reading standard-in: "+e.tostring()); } return out; } }
update one:
following own hunch, discovered environment variable used set cipher suites used in sslrmi socket factories. so, added server side:
javax.rmi.ssl.client.enabledciphersuites="tls_ecdhe_rsa_with_aes_256_cbc_sha,tls_dhe_rsa_with_aes_256_cbc_sha,tls_ecdh_rsa_with_aes_256_cbc_sha,tls_dhe_dss_with_aes_128_cbc_sha256,tls_dhe_dss_with_aes_256_cbc_sha256,tls_dhe_rsa_with_aes_128_cbc_sha256,tls_ecdh_rsa_with_aes_128_cbc_sha256,tls_dhe_rsa_with_aes_256_cbc_sha256,tls_ecdhe_rsa_with_aes_256_cbc_sha384,tls_ecdh_ecdsa_with_aes_256_cbc_sha384,tls_rsa_with_aes_256_cbc_sha256,tls_ecdhe_ecdsa_with_aes_256_cbc_sha,tls_ecdhe_rsa_with_aes_128_cbc_sha256,tls_ecdhe_ecdsa_with_aes_256_cbc_sha384,tls_dhe_dss_with_aes_256_cbc_sha,tls_ecdh_rsa_with_aes_256_cbc_sha384,tls_ecdhe_ecdsa_with_aes_128_cbc_sha256,tls_ecdh_ecdsa_with_aes_128_cbc_sha256,tls_ecdh_ecdsa_with_aes_256_cbc_sha,tls_rsa_with_aes_256_cbc_sha,tls_rsa_with_aes_128_cbc_sha256"
this entire list either "unavailable" or "unsupported" - perhaps it's overkill, want server take whatever client has available.
this changed output considerably! however, still hangs on same statement, time, tracing turned off, get:
java.rmi.connectioexception: error during jrmp connection establishment; nested exception is: javax.net.ssl.sslhandshakeexception: remote host closed connection during handshake
when add tracing, there's lot of data protocol chosen , it's doing , gets (heavily cropped before excerpt):
... 0080: 00 0f 00 10 00 11 00 02 00 12 00 04 00 05 00 14 ................ 0090: 00 08 00 16 00 0b 00 02 01 00 .......... main, received eofexception: error main, handling exception: javax.net.ssl.sslhandshakeexception: remote host closed connection during handshake main, send tlsv1 alert: fatal, description = handshake_failure main, write: tlsv1 alert, length = 2 [raw write]: length = 7 0000: 15 03 01 00 02 02 28 ......( main, called closesocket() java.rmi.connectioexception: error during jrmp connection establishment; nested exception is: javax.net.ssl.sslhandshakeexception: remote host closed connection during handshake
update two:
on suggestion of ejp, respect on topic answers others, tested premise server isn't running registry, or, @ least, not on system/port combination client looking.
to test hypothesis start , stop server , clients behavior changes substantially. in case it's not running, long block of alternately "ignoring unavailable" or "ignoring unsupported" cipher suites, followed names, reported in first case above.
when server running, client gives different response, sending me detailed information particulars of making encrypted connection, reported in first update above. furhter, says remote host closed connection during handshake, handshake underway when dropped. additionally, this:
$ netstat -n -l | grep <my port number> tcp 0 0 :::<my port number> :::* listen
i think that's conclusive...
update three:
i noticed output had changed somewhat, should clarify, etc. presently when test, , i'm sure there's listener on port on system registry (hopefully) started correctly, using same truststore , keystore files client, start client , lot of trace information ssl including list of ciphers noted above, , afterward, lists randomcookie, empty session id, list of ciphers, elliptic curves, , dumps bunch of bytes, following text picks up:
0080: 00 0f 00 10 00 11 00 02 00 12 00 04 00 05 00 14 ................ 0090: 00 08 00 16 00 0b 00 02 01 00 .......... [raw read]: length = 5 0000: 15 03 01 00 02 ..... [raw read]: length = 2 0000: 02 28 .( main, read: tlsv1 alert, length = 2 main, recv tlsv1 alert: fatal, handshake_failure main, called closesocket() main, handling exception: javax.net.ssl.sslhandshakeexception: received fatal alert: handshake_failure java.rmi.connectioexception: error during jrmp connection establishment; nested exception is: javax.net.ssl.sslhandshakeexception: received fatal alert: handshake_failure
it sure nice if got clean error message why handshake dropped. notably, haven't figured out how similar output server - go? have provided javax.net.debug=all?!?!
update four:
i wondered if there problem object i've registered rmi registry. original design have 2 object interfaces created. first gets instantiated , registered. job create other objects instantiated not registered; client gets first object registry , askes second, , instance private client. client calls methods exposed second object, executed on server-side, results passed back.
to make sure wasn't playing role here, created following. note, however, did not change - it's lot shorter , thereby more fitting include here full disclosure:
package <mypackage>; import <mypackage>.*; import java.rmi.*; public interface testobject extends remote { myapi.person getobject() throws remoteexception; }
i used interface thus:
package <mypackage>; import <mypackage>.myapi; import <mypackage>.testobject; import java.rmi.*; import java.rmi.server.*; public class testobject extends unicastremoteobject implements testobject { public testobject() throws remoteexception { // set security manager rmi security manager, prevent // client process using server in malicious way. try { if (system.getsecuritymanager() == null) { system.setsecuritymanager(new rmisecuritymanager()); } } catch(exception e) { system.out.println("securitymanager load error: \n"+e); } } public myapi.person getobject() throws remoteexception { myapi c = new myapi(); myapi.person testobject = c.newperson(); testobject.firstname = "test"; testobject.lastname = "object"; return testobject; } }
i updated server code following lines:
try { testobject testobject = new testobject(); ok = true; } catch (remoteexception e) { msg("error instantiating testobject: \n"+e.tostring()); } if (ok) { name = testobject.class.getsimplename(); try { registry.bind(name, serverprocess); msg("new testobject has been bound rmi registry."); } catch(exception e) { msg("the new testobject not bound rmi registry: \n"+e.tostring()); ok = false; } }
and client with:
testobject to; try { msg("now trying 'testobject'..."); = (testobject)registry.lookup(testobject.class.getsimplename()); msg("well! did not throw exception!"); person = to.getobject(); msg("name: "+person.firstname+" "+person.lastname); } catch (exception e) { msg(e.tostring()); }
unfortunately, still throws (the same) exception.
still going, "hmmm..."
i had problem before. add line when want run class: "-dcom.sun.management.jmxremote.ssl=false" or can change code , take values ssl-hand-shake, more difficult.
Comments
Post a Comment