[ZBX-10370] Java Gateway cannot connect to remote JMX server if RMI registry is forced by SSL Created: 2016 Feb 10 Updated: 2024 Jul 18 Resolved: 2021 Feb 27 |
|
Status: | Closed |
Project: | ZABBIX BUGS AND ISSUES |
Component/s: | Java gateway (J) |
Affects Version/s: | 3.0.0rc2, 5.0.7 |
Fix Version/s: | 4.0.30rc1, 5.0.10rc1, 5.2.6rc1, 5.4.0beta1, 5.4 (plan) |
Type: | Problem report | Priority: | Major |
Reporter: | Pablo | Assignee: | Artjoms Rimdjonoks |
Resolution: | Fixed | Votes: | 1 |
Labels: | None | ||
Remaining Estimate: | Not Specified | ||
Time Spent: | Not Specified | ||
Original Estimate: | Not Specified |
Attachments: |
![]() |
||||||||||||
Issue Links: |
|
||||||||||||
Team: | |||||||||||||
Sprint: | Sprint 72 (Jan 2021), Sprint 73 (Feb 2021) | ||||||||||||
Story Points: | 2 |
Description |
I've tested it with glassfish and one needs to do HashMap envSSL = new HashMap<>(env != null ? env : Collections.emptyMap()); envSSL.put("com.sun.jndi.rmi.factory.socket", new SslRMIClientSocketFactory()); jmxc = JMXConnectorFactory.connect(url, envSSL); Before jmxc = JMXConnectorFactory.connect(url, envSSL); Failing to do this returns in IOEXceptiom: non-JRMP server at remote endpoint |
Comments |
Comment by Pablo [ 2016 Feb 12 ] |
Moreover, I am sure it would be handy to have some sort of way of allowing SSL connections to servers using a self-signed certificate. (e.g. DEV, SIT, UAT Servers) After some digging, I added this to my own version of the java gateway to skip SSL cert verification System.setProperty("com.sun.net.ssl.checkRevocation", "false"); TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() { public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; } public void checkClientTrusted(X509Certificate[] certs, String authType) { } public void checkServerTrusted(X509Certificate[] certs, String authType) { } } }; try { logger.info("Hacking SSL Validation"); SSLContext sc = SSLContext.getInstance("SSL"); sc.init(null, trustAllCerts, new java.security.SecureRandom()); SSLContext.setDefault(sc); logger.info("SSL Validation hacked"); } catch (Exception e) { throw new RuntimeException(e); } |
Comment by Aleksandrs Saveljevs [ 2016 Feb 15 ] |
If you set up SSL command-line parameters as described at https://www.zabbix.com/documentation/2.4/manual/config/items/itemtypes/jmx_monitoring , does it start working? |
Comment by Pablo [ 2016 Feb 15 ] |
Possibly like that or with some specific Glassfish properties to disable JMX auth and JMX SSL.... But we wouldn't want to connect to prod servers without SSL or without credentials either. Why are you asking? |
Comment by Aleksandrs Saveljevs [ 2016 Feb 15 ] |
The issue description suggests modifying Java gateway code. However, the page at https://www.zabbix.com/documentation/2.4/manual/config/items/itemtypes/jmx_monitoring suggests adding command-line parameters like the following to get SSL working: java \ -Djava.rmi.server.hostname=192.168.3.14 \ -Dcom.sun.management.jmxremote \ -Dcom.sun.management.jmxremote.port=12345 \ -Dcom.sun.management.jmxremote.authenticate=true \ -Dcom.sun.management.jmxremote.password.file=/etc/java-6-openjdk/management/jmxremote.password \ -Dcom.sun.management.jmxremote.access.file=/etc/java-6-openjdk/management/jmxremote.access \ -Dcom.sun.management.jmxremote.ssl=true \ -Djavax.net.ssl.keyStore=$YOUR_KEY_STORE \ -Djavax.net.ssl.keyStorePassword=$YOUR_KEY_STORE_PASSWORD \ -Djavax.net.ssl.trustStore=$YOUR_TRUST_STORE \ -Djavax.net.ssl.trustStorePassword=$YOUR_TRUST_STORE_PASSWORD \ -Dcom.sun.management.jmxremote.ssl.need.client.auth=true \ -jar /usr/share/doc/openjdk-6-jre-headless/demo/jfc/Notepad/Notepad.jar In your case, only a subset may be needed or maybe one should use other properties specific to Glassfish. So I was wondering whether you can achieve the same effect (get SSL working) by modifying the way Java gateway is started, but not changing the code itself? |
Comment by Pablo [ 2016 Feb 15 ] |
Ok, I got you now. With that bit of code there, you can enable SSL on the target java application and you can also protect the jmx connection with user name and password (glassfish has both SSL + Auth enabled by default) With the keyStore settings on that bit of code are for the the application to find an appropiate SSL certificate. But that bit of code is for the application the gateway will be connecting to (NotePad, GlassFish, etc) The problem on the java gateway itself is that it can not open a SSL connection to GlassFish unless you use specify the SSL socket factory SslRMIClientSocketFactory(). Not sure how it would work when connecting to the sample NotePad application but when attempting to do so against glassfish it says: Failing to do this returns in IOEXceptiom: non JRMP endpoint on remote server. I also looked into how to achieve this through JVM command line parameters passed to the java gateway on startup but I couldn't figure out how. |
Comment by Aleksandrs Saveljevs [ 2016 Feb 15 ] |
Another reason that I am asking is that if it is possible to make Java gateway connect to Glassfish using SSL using command-line parameters, then this is the preferred way and this issue should be closed as "Won't fix". We should only leave this issue open if the code change is really necessary for it to work. If you are not sure, it would be wonderful if you would discuss that at https://www.zabbix.org/wiki/Getting_help . |
Comment by Pablo [ 2016 Feb 15 ] |
Hey Alek, I understand what you mean. I am not aware of any command line parameters to specify the socket type. It may work with -Dcom.sun.jndi.rmi.factory.socket= fully classified class name. Not sure, problem being is that the gateway may only work in SSL mode by doing so? My skype id is pablo.anahata-it.com.au if you want to chat. |
Comment by Pablo [ 2016 Feb 22 ] |
Alex, I am on the zabbix IRC channel now. We created a fork of the java gateway using maven with the workaround for self-signed SSL certificates and SSL over JMX. It is here https://bitbucket.org/anahata/anahata-zabbix-java-gateway I think it needs a bit of improvement around pooling JMX connections. We are happy to help with the java side of things. You can email me on [email protected] if you need a hand on the java side. Otherwise skype / irc good too. |
Comment by Aleksandrs Saveljevs [ 2016 Feb 22 ] |
We seem to have it documented at https://www.zabbix.com/documentation/2.4/manual/config/items/itemtypes/jmx_monitoring how to enable SSL for a basic monitored application, but we do not seem to give an example on how to enable SSL for Java gateway. I should probably remember how it is done and then we will decide what to do with this issue - will it only require a documentation update or some code changes are necessary, too. |
Comment by Pablo [ 2016 Feb 23 ] |
Alek, what is documented here https://www.zabbix.com/documentation/2.4/manual/config/items/itemtypes/jmx_monitoring is the process to launch a java application (like the NotePad example) so it can be monitored with and without SSL. Glassfish or Java EE application servers (what is more often monitored) the JMX configuration is different, for example in GlassFish, to lookup a JMX connection from a remote client (such as the zabbix java gateway) one needs to specify the SSLRmi socket factory as Glassfish exposes JMX through RMI. Ok, so what I would do if i was you Alek, is try to see how many java ee servers with SSL zabbix can monitor. The most common Java EE Servers are: GlasFish/Payara, Tomcat/TomEE, WebLogic/WildFly, Geronimo, WebSphere |
Comment by richlv [ 2016 Feb 23 ] |
quite offtopic, but in the region where zabbix is developed, that shortening is not common - you might just go with the full form of "Aleksandrs" (although the correct language form would be "Aleksandr", we can leave that topic for the zabbix conference or a similar event |
Comment by Pablo [ 2016 Feb 23 ] |
I am from Spain but here in Australia everything gets shortened, I am not aware of any other country in the world which shortens names more than Australia, but yes, I agree with you, does need further discussion. |
Comment by Aleksandrs Saveljevs [ 2016 Mar 07 ] |
pranahata, I will not have time to research this issue on this occasion. For now, you might wish to consult with https://www.zabbix.org/wiki/Getting_help if you run into any SSL issues with Java gateway. |
Comment by A B [ 2016 Sep 18 ] |
Having just run into this issue on Tomcat, I think I can clarify the confusion a bit. The problem stems from the fact that two different services/ports/connections are involved when using Java RMI:
Now, enabling SSL as described in the zabbix docs will enable SSL only for the object connection, but the registry connection will still be insecure (non-SSL). This used to be a common setup. However, it appears that Glassfish (as inferred from the above comments), and newer versions of Tomcat (specifically versions > 7.0.40 of the tomcat-catalina-jmx-remote lib) also run the registry on SSL, and that is not currently supported by zabbix and would require the above rmi-connection-factory changes. A custom trust-manager as described in the first comment is not necessary (nor desired) if the javax.net.ssl.trustStore system property has been properly set as described in the docs. |
Comment by Oleksii Zagorskyi [ 2020 Dec 18 ] |
To emulate those troubles for a java app it's possible to force SSL for RMI registry by this option for JVM:
-Dcom.sun.management.jmxremote.registry.ssl=true
To test such connection you can use jmxterm with option "-s" when connecting to remote host. From its help:
I can confirm for sure that it's not possible to do something like that in current java gateway. Here I found a fork of gateway and it looks like modification is simple and possible. jmxterm does following if -s option used: if (options.isSecureRmiRegistry()) { // Required to prevent "java.rmi.ConnectIOException: non-JRMP server at remote endpoint" // error env.put("com.sun.jndi.rmi.factory.socket", new SslRMIClientSocketFactory()); } For example currently it's not possible to monitor Cassandra (v3.11.9) because if forcibly enables SSL for RMI registry (somewhere internally, not on JVM level) and I could not find a way to disable it. Produced error: non-JRMP server at remote endpoint So we really need such a feature in zabbix. |
Comment by Oleksii Zagorskyi [ 2020 Dec 23 ] |
Simple way to check that the JMX agent requires SSL for RMI registry is to check from command line this way, select any:
curl -vvv -k https://127.0.0.1:7199
openssl s_client -showcerts -connect 127.0.0.1:7199
if you see that certificate is received when opening connection - SSL for RMI registry must be used. |
Comment by Artjoms Rimdjonoks [ 2021 Feb 24 ] |
Available in versions:
Updated documentation: |
Comment by Oleksii Zagorskyi [ 2021 Feb 26 ] |
Technical detail from developers:
|