Monday Oct 03, 2005

One password to rule them all!

A few weeks ago I talked about how easy it is to get started with jconsole. The focus of that discussion was local monitoring and management where jconsole connects to applications running as the same user on the same machine. It is a simple scenario with simple configuration and jconsole doesn't need to prompt for username and password.

Now let us move onto the more complicated (and arguably more realistic) scenario where an application is deployed over a number of machines. In these cases the configuration of the JMX agent gets more complicated as it involves setting up SSL, a password file, and choosing a port number for the agent. This is all described on the Monitoring and Management with JMX page. One bugaboo with all this is that the password and access files create yet another place for user administration and yet another password to remember. If the application environment is distributed across the globe then it means sharing files in a secure manner or maybe a password file per machine. SSL client certificates provide a better alternative but in many environments they are a missing piece in the overall security infrastructure. Assuming you aren't using SSL client certs then another alternative to password authentication is LDAP. In many companies there is already directory server infrastructure and many of your applications may be using LDAP already. So today I want to talk about configuring the JMX agent to use LDAP instead of the file-based authentication.

Let's start by talking about the JMXAuthenticator implementation in the JMX agent. It is based on Java Authentication and Authorization Service (JAAS). Authentication is performed by passing the user credentials to a JAAS LoginModule. By default it uses a LoginModule that authenticates using the password and access files. An alternative LoginModule (and hence an alternative authentication mechanism), is specified using the property. The property is set to the name of a JAAS login configuration entry. For LDAP that means we need to set it to the entry name for an LDAP-based LoginModule.

J2SETM 5.0 didn't ship with an LDAP based LoginModule but there is one in a Mustang (Java SE 6.0) thanks to Vincent Ryan. The LoginModule is To use it we need to create a JAAS configuration entry. I've created the configuration file ldap.config and configured the entry to work within Sun. Here's how it looks:

SunConfig { REQUIRED

If you aren't familar with the syntax of the configuration file then the Configuration class details the information needed for configuration, and there are examples available.

The specification for the LoginModule details all the options. In this example I've named the entry "SunConfig". The flag "REQUIRED" means that authentication is required to succeed. The other items are module options. The userProvider option identifies the LDAP directory. It's a LDAP URL (or a list of URLs). The URL identifies the LDAP server to use and the position in the directory tree where user entries are located. The userFilter module option is another piece of LDAP configuration. It specifies the search filter to use to locate a user entry in the LDAP directory. The token "{USERNAME}" is replaced with the username before the filter is used to search the directory. If all this looks like gobbledegook then have a chat with your LDAP administrator to get the magic settings for your environment.

The authzIdentity takes a bit of explaining and we'll come back to it shortly. The final module option in this confguration is useSSL which indictaes if the connection to the LDAP server uses SSL or not. The default is true but I've tried to keep this example simple and so it is disabled.

So now we have a JAAS configuration entry for the LDAP LoginModule. The next piece is to configure two system properties:

  • configures the JMX agent to use our JAAS configuration entry
  • specifies the JAAS configuration file to load

Here's a sample command line with all the properties set:

     -jar MyApplication.jar

I've snuck in two other properties here. The property configures the TCP port number, and specifies if SSL is enabled or disabled (I've chosen to disable it to keep the configuration simple but you'll want to enable it in production environments).

At this point we have our configuration so we start the application. The JMX agent starts with the application so we now try to connect using jconsole. For example I'll assume the application is on "myserver" and we're "John Doe" (username "jdoe"). To connect we start jconsole, switch to the Remote tab of the Connection Dialog, and enter the connection details:

When we press the Connect button then jconsole will connect to the JMX agent, and the JMX agent will attempt to authenticate "jdoe".

When you initially setup your configuration it can be useful to add the debug opton to the JAAS configuration entry. If you add debug=true then the LdapLoginModule will print trace information to standard output. Here's an example for when jdoe does a successful login:

[LdapLoginModule] search-first mode; SSL disabled
[LdapLoginModule] user provider: ldap://sun-ds/ou=people,dc=sun,dc=com
[LdapLoginModule] searching for entry belonging to user: jdoe
[LdapLoginModule] found entry: cn=John Doe,ou=people,dc=sun,dc=com
[LdapLoginModule] attempting to authenticate user: jdoe
[LdapLoginModule] authentication succeeded
[LdapLoginModule] added X500Principal "CN=John Doe,OU=people, DC=sun, DC=com" to Subject
[LdapLoginModule] added UserPrincipal "jdoe" to Subject
[LdapLoginModule] added UserPrincipal "monitorRole" to Subject

This log is saying that the LoginModule searched for the user entry "jdoe". It was found and then the password was authenticated.

If the password was entered incorrectly then you'll see something like this:

[LdapLoginModule] search-first mode; SSL disabled
[LdapLoginModule] user provider: ldap://sun-ds/ou=people,dc=sun,dc=com
[LdapLoginModule] searching for entry belonging to user: jdoe
[LdapLoginModule] found entry: cn=John Doe,ou=people,dc=sun,dc=com
[LdapLoginModule] attempting to authenticate user: jdoe
[LdapLoginModule] authentication failed
[LdapLoginModule] aborted authentication

Now let's get back to the authzIdentity module option that I skipped over earilier. In the example I used authzIdentity=monitorRole which means that all authenticated users get read-only access to the managed VM. In technical terms the Principle named monitorRole is added to each authenticated user (or Subject). The name monitorRole corresponds to an entry in the JMX access file. The JMX access file is usually ${JRE_HOME}/lib/management/jmxremote.access but you can use the property to specify an alternative file if you wish. By default the file contains two roles, namely monitorRole with readonly access, and controlRole with readwrite access. In some environments it might make sense to allow all users access to the managed VM but more realistically there will only be a small number of technical staff that will be monitoring and managing the applications. In that case we need to update the configuration as follows:

So, assuming we want our "John Doe" to have read-write access then we create an entry in the JMX access file as follows:

jdoe    readwrite

So what does this mean? When John Doe connects he will be authenticated using his normal LDAP password. Once authenticated he has readwrite access to the managed application (by virtue of the entry in the access file).

In summary, I think you will agree that the ability for the JMX agent to authenticate users using LDAP is very nice. It eliminates the need to manage additional password files and for those managing applications it means there is only one password to remember. There is some configuration required and specific users still need to be setup in the access file but overall it is a whole lot better than having to mantain password files.

Thursday Sep 29, 2005

Time to update the J2SE Troubleshooting Guide!

One of the documents created for J2SETM 5.0 was the Troubleshooting and Diagnostic Guide. It was a late decision to create this document with the result that its scope was much narrower than might be expected. However it served a useful purpose in that it created an awareness of the troubleshooting tools that were new to J2SE 5.0. It also served as a useful place to send people when troubleshooting questions came up (like how to find the error log that is generated when a fatal error occurs).

It's now time to start thinking about updating the document for Mustang. The initial document focused on the HotSpotTM virtual machine. The document for Mustang needs to be wider in scope and cover troubleshooting problems with client-side applications, deployment, and many other areas. Mustang brings a lot of new and updated diagnostic features. I touched on the heap dump capabilities here, and Sundar has started a series on the Object Query Language feature in jhat. There are many other useful items and these need to be written up.

If you have ideas for areas that should be covered in the updated Troubleshooting Guide please send a mail to Also, send feedback if you think that one big document isn't the right format for this - the original reason for putting everything into one document was to allow people to print it out. I don't know many trees suffered needlessly so send feedback if you think an alternative format would be better. Finally, if you would like to contribute content then please step forward. In particular if you recently diagnosed a really awkward problem with a deployed application then others might benefit from a write-up of the steps that you took to diagnose it.

Friday Sep 23, 2005

Getting started with jconsole just got easier!

J2SETM 5.0 brought some great monitoring and management capabilites to the JavaTM platform. The built-in instrumentation in the Java Virtual Machine means you can monitor and manage it using JMX. And of course, if the application have been instrumented with JMX then it gets even better. As part of the monitoring and management implementation a JMX-compliant monitoring tool called jconsole was developed. I hope you have tried it. If you haven't tried it let then a good starting place is the this page on Monitoring and Management Using JMX

One of the goals during the development of jconsole was that it should be easy to get going very quickly. The JMX agent has lots of configuration properties but a new user should be able to avoid most of this and get going in a few simple steps. All you need is to start the application with a simple property on the command line. When this property is set then the JMX agent starts up in a way that allows jconsole to connect without needing to prompt for connection details. This is somethings called local monitoring because it restricts the monitoring to the local machine (you have to be the same user too). The property is so you start your application like this:

java App

Once the application is running then jconsole can connect. If you know the process-id (pid) then "jconsole <process-id>" should do it. Alternatively, if you don't know the process id then start jconsole without any parameters and select the application in the connection dialog.

It turns out that it gets even simpler in Mustang (Java SE 6.0). The reason is that jconsole has been updated so that it can connect to applications that did not start up with the JMX agent. This is rather useful as it allows jconsole to connect to applets in the browser, Java Web Start applications, and other applications where it isn't easy to fiddle with the command line.

So how does it work? jconsole uses a JMXConnector client to connect to the JMXConnectorServer in the target application. In the application isn't started with the JMX agent then there isn't a JMXConnectorServer and jconsole doesn't have anything to connect too. In that case it uses a HotSpotTM VM specific mechanism to start the JMX agent in the target VM. Once the agent is started then jconsole connects as normal.

This sounds very cool so let us see how it looks. First, we start jconsole. I haven't use any parameters so jconsole opens the Connection Dialog. I've selected the Local Tab and jconsole shows me the applications that I have running on this machine. In this screen-shot I have clicked ona Java Web Start application called bugster:

Next I press the Connect button. Behind the scenes the JMX agent is started in the target VM and jconsole connects. (By the way, that checkbox column with the title Enabled just indictaes if the JMX agent is running in the target VM or not - this is probably not the best way to indicate this but jconsole is due a new connection dialog soon and it should look much better). Once the connection is established jconsole opens up Summary Tab which gives me a summary of the bugster application.

I'm sure you'll agree this is rather neat and makes getting started with jconsole very easy.




Top Tags
« July 2016

No bookmarks in folder