I have my JMX server which registers beans reading from local file and make them available to other JMX clients on demand. Server can be accessed either using "jconsole" or by Java app running under Tomcat container.
What i want is to add authentication in order to prevent "unknown" identity accessing JMX Server. To achieve this i have added Kerberos authentication @ server using following JVM options
-Dcom.sun.management.jmxremote=true
-Dcom.sun.management.jmxremote.port=5555
-Dcom.sun.management.jmxremote.authenticate=true
-Dcom.sun.management.jmxremote.ssl=false
-Djava.security.auth.login.config=./conf/jaas.conf
-Djava.security.krb5.conf=./conf/krb5.conf
-Dcom.sun.management.jmxremote.login.config=MyKrbAuth
-Ddynamic.mbean.store=./conf/mbeans
-Djava.net.preferIPv4Stack=true
my jaas.conf looks like this >>
MyKrbAuth {
com.sun.security.auth.module.Krb5LoginModule required debug=true debugNative=true;
};
When I start my JMX server with above configuration and try to connect it using "jconsole", I get the following exception at client side and connection fails>>
Cipher: Crypto Permission check failed
Cipher: granted: (CryptoPermission * 128)
Cipher: requesting: (CryptoPermission AES 256)
But at server authentication appears to be successful >>
[java] [STARTED] Mbean Server
[java] Debug is true storeKey false useTicketCache false useKeyTab false doNotPrompt false ticketCache is null isInitiator true KeyTab is null refreshKrb5Config is false principal is null tryFirstPass is false useFirstPass is false storePass is false clearPass is false
[java] [Krb5LoginModule] user entered username: username
[java]
[java] Acquire TGT using AS Exchange
[java] principal is [email protected]
[java] EncryptionKey: keyType=3 keyBytes (hex dump)=0000: FD 46 7C 02 19 9B 34 E9
[java] EncryptionKey: keyType=1 keyBytes (hex dump)=0000: FD 46 7C 02 19 9B 34 E9
[java] EncryptionKey: keyType=23 keyBytes (hex dump)=0000: FE 6D 82 01 8A D7 AB 60 98
[java] EncryptionKey: keyType=16 keyBytes (hex dump)=0000: 89 02 31 5D F7 5B 3E 89 BC F7 8A 01 A1 80 C7
[java] EncryptionKey: keyType=17 keyBytes (hex dump)=0000: A5 67 71 17 F6 57 A9 26 01 09 B1 EB 75 46 6C
[java]
[java] Commit Succeeded
[java]
From above it seems that client not able to decode response (which is AES256 encrypted).. How to fix it ??
By default, JMX is only locally accessible and secure: It can be accessed through Unix sockets. This means you need to have access to the machine and run JMX tools with the same user as your application. It's usually enough for development but not for production.
You need to include the unlimited strength cryptography policy file (link is for Java 6, see java.oracle.com for others) in your Java installation. By default Java does not allow you to use strong encryption like AES256 (because of absurd US export laws which consider encryption to be weapons/munition). The policy file will unlock stronger encryption.
Managed to fixed above problem. Here are the steps to introduce Kerberos authentication/authorization at your JMX client/server
To enable Kerberos @ JMX server,
Start server with following set of args =>
-Dcom.sun.management.jmxremote=true
-Dcom.sun.management.jmxremote.port=<port_no>
-Dcom.sun.management.jmxremote.authenticate=true
-Dcom.sun.management.jmxremote.ssl=false
-Djava.security.auth.login.config=<locatin_of_jaas.conf>
-Djava.security.krb5.conf=<locatin_of_krb5.conf>
-Dcom.sun.management.jmxremote.login.config=<name_of_login_config_to_be_used>
-Djava.net.preferIPv4Stack=true
Add access entry in $JAVA_HOME/jre/lib/management/jmxremote.access. Once user get authenticated, read/write access to JMX server will be provided on basis of jmxremote.access. Location of .access file can be provided using following jvm arg at server start up
-Dcom.sun.management.jmxremote.access.file=<acees_control_file>
To enable Kerberos @ JMX Client (jconsole)
Start jconsole with debug option & connect to server
jconsole -J-Djava.security.debug=all
if requested encryption is AES256, then download unlimited strength cryptography policy jar files, extract and place policy files at $JAVA_HOME/jre/lib/security/. [Thanks to Mark for pointing out policy inclusion.]
Above should make Kerberos work at both JMX client and JMX server side
If you are still facing problem in connection then you can enable verbose debugging for jconsole using logging.properties file =>
handlers = java.util.logging.ConsoleHandler
.level = INFO
java.util.logging.ConsoleHandler.level = FINEST
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
// Use FINER or FINEST for javax.management.remote.level - FINEST is very verbose...
javax.management.level = FINEST
javax.management.remote.level = FINER
And start jconsole using
jconsole -J-Djava.util.logging.config.file=<location_of_logging.properties>
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