<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>bogdan@j3e &#187; JMX</title>
	<atom:link href="http://www.bserban.org/category/jmx/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.bserban.org</link>
	<description>Web, Java, J2EE, SaaS, Tips&#38;Tricks</description>
	<lastBuildDate>Thu, 08 Jul 2010 11:53:28 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Creating a secure JMX Agent in JDK 1.5</title>
		<link>http://www.bserban.org/2009/10/creating-a-secure-jmx-agent-in-jdk-1-5/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=creating-a-secure-jmx-agent-in-jdk-1-5</link>
		<comments>http://www.bserban.org/2009/10/creating-a-secure-jmx-agent-in-jdk-1-5/#comments</comments>
		<pubDate>Sat, 31 Oct 2009 17:03:39 +0000</pubDate>
		<dc:creator>bserban</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[JMX]]></category>
		<category><![CDATA[Monitoring]]></category>
		<category><![CDATA[Agent]]></category>
		<category><![CDATA[JMX Architecture]]></category>
		<category><![CDATA[JMX JDK 1.5]]></category>
		<category><![CDATA[JMXConnectorServer]]></category>
		<category><![CDATA[MBeanServer]]></category>
		<category><![CDATA[SSL JMX]]></category>

		<guid isPermaLink="false">http://www.bserban.org/?p=254</guid>
		<description><![CDATA[What is JMX? Java Management Extension is an open technology for management, and monitoring that can be deployed wherever management and monitoring are needed. The most common use in a web application is for application management. This is very often an afterthought which results in many unmanaged application deployments. You can monitor you application for [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.bserban.org%2F2009%2F10%2Fcreating-a-secure-jmx-agent-in-jdk-1-5%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.bserban.org%2F2009%2F10%2Fcreating-a-secure-jmx-agent-in-jdk-1-5%2F&amp;source=bserban&amp;style=normal&amp;service=bit.ly&amp;hashtags=Agent,JMX,JMX+Architecture,JMX+JDK+1.5,JMXConnectorServer,MBeanServer,SSL+JMX" height="61" width="50" /><br />
			</a>
		</div>
<h2>What is JMX?</h2>
<p>Java Management Extension is an open technology for management, and monitoring that can be deployed wherever management and monitoring are needed. The most common use in a web application is for application management. This is very often an afterthought which results in many unmanaged application deployments.</p>
<p>You can monitor you application for availability and performance but in the same time you can use the JMX to manage and monitor you application from business perspective. Application&#8217;s runtime metrics can be expose through JMX, or in a service oriented architecture you could use JMX to control your services.</p>
<p>All good but when you start to work with <strong>JMX and JDK 1.5</strong> soon you will discover one big limitation that was fixed in jdk 1.6 update 16 if i recall correctly:</p>
<blockquote><p>Default RMI JMX agent for remote access opens 2 ports, one which is set by the -Dcom.sun.management.jmxremote.port=XXXX <strong>and one randomly assigned port.</strong>. What about firewalls?</p></blockquote>
<h2>JMX service url</h2>
<p>service:jmx:rmi://hostname:<strong>port1</strong>/jndi/rmi//hostname:<strong>port2</strong>/jmxrmi</p>
<p>Where:</p>
<ul>
<li><strong>port1 </strong>is the port number on which the <strong>RMIServer </strong>and <strong>RMIConnection </strong>remote objects are exported</li>
<li><strong>port2 </strong>is the port number of the <strong>RMI Registry</strong></li>
</ul>
<p><span id="more-254"></span><br />
To access the RMIAgent you only need to know were the RMI registry is located from which to obtain the connection objects. I guess this was the reason to randomly assign the port1, but you have pretty high chances to have a firewall problem.</p>
<p>The solution is to replace the default agent and to create your own version of JMX Agent to provide access to RMI connection on a specific port.</p>
<h2>JMX Architecture</h2>
<p>There are three main components that makes the JMX possible:</p>
<ul>
<li>Instrumentation<strong> </strong>layer, the managed beans and their resources. What you want to manage</li>
<li>JMX Agent, standard management agent that directly controls resources and makes them available to remote management applications. It is a mean to expose the managed beans, mbean server, monitoring, timing, relation, and class-loading services.</li>
<li>Remote management, permits the interaction between remote clients and the JMX Agent. There are a couple of default adapters that are built in, these are: HTTP Adapter (for viewing management data), RMI Adapter, SOAP Adapter, and SNMP Adapter.</li>
</ul>
<h2>Creating the Agent</h2>
<p>To overcome the problems in JDK 1.5 explained above we need to create an java agent to export the RMI Registry and the RMIServer on specific ports.</p>
<p>This is pretty straight forward, we just need to export the RMIRegistry o a specific port, to get the MBeanServer and to create a JMXConnectorServer between those two. Then we just need to start the connector server and it is done</p>
<pre class="brush: java">....................
LocateRegistry.createRegistry(port);
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
final String hostname = InetAddress.getLocalHost().getHostName();
JMXServiceURL url = new JMXServiceURL(&quot;service:jmx:rmi://&quot;+hostname+&quot;:&quot;+port+&quot;/jndi/rmi://&quot;+hostname+&quot;:&quot;+port+&quot;/jmxrmi&quot;);
JMXConnectorServer cs = JMXConnectorServerFactory.newJMXConnectorServer(url, env, mbs);
cs.start();
</pre>
<p>Simple as it gets, but right now we don;t have any security in place. If we want to add SSL and authorization things will complicate a little.</p>
<h2>Securing the Agent</h2>
<p>To make the access secure we have to expose the RMIRegisty over the SSL. For this we need to make the following modification:</p>
<pre class="brush: java">
..............
SslRMIClientSocketFactory csf = new SslRMIClientSocketFactory();
SslRMIServerSocketFactory ssf = new SslRMIServerSocketFactory();
Registry registry = LocateRegistry.createRegistry(port, csf, ssf);
................

// Now specify the SSL Socket Factories:
//
// For the client side (remote)
//
env.put(RMIConnectorServer.RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE, csf);
// For the server side (local)
//
env.put(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE, ssf);
// For binding the JMX RMI Connector Server with the registry
// created above:
//
env.put(&quot;com.sun.jndi.rmi.factory.socket&quot;, csf);

final RMIServerImpl stub = new RMIJRMPServerImpl(port, csf, ssf, env);

final JMXConnectorServer cs =
new RMIConnectorServer(new JMXServiceURL(&quot;rmi&quot;, hostname, port),
env, stub, mbs) {
@Override
public JMXServiceURL getAddress() {
return url;
}
@Override
public synchronized void start() throws IOException {
try {
registry.bind(&quot;jmxrmi&quot;, stub);
} catch (AlreadyBoundException x) {
final IOException io = new IOException(x.getMessage());
io.initCause(x);
throw io;
}
super.start();
}
};
cs.start();</pre>
<p>As you see we had to secure also the connection between ConnectorServer and JMX agent and for RMI server and client. Not that simple as the unsecure version. To add the authorization we just need to provide the credentials. Usually these are store in files and passed to the jmx connector server using environment variables:</p>
<pre class="brush: java">env.put(&quot;jmx.remote.x.password.file&quot;, pasword);
env.put(&quot;jmx.remote.x.access.file&quot;, access);
</pre>
<p>And their content:</p>
<pre class="brush: java">admin password1
monitor password2
..................
admin readwrite
monitor readonly
</pre>
<p>In order that SSL connections to work we need to create a keystore. This is done using keytool and can be create like this:</p>
<pre class="brush: java">
keytool -genkey -keyalg RSA -keysize 1024 -dname &quot;CN=org.bserban.www&quot; -keystore ./jmx-demo.jks -storepass bserban
</pre>
<h3>Running the Agent</h3>
<pre class="brush: java">
java -javaagent:jmx-agent.jar -Djavax.net.ssl.trustStore=./jmx-demo.jks -Djavax.net.ssl.trustPassword=bserban -Djavax.net.ssl.keyStore=./jmx-demo.jks -Djavax.net.ssl.keyStorePassword=bserban org.abserban.jmx.agent.StartAgentStandalone
</pre>
<h3>Running the Client</h3>
<pre class="brush: java">
java -Djavax.net.ssl.trustStore=./jmx-demo.jks -Djavax.net.ssl.trustPassword=bserban -Djavax.net.ssl.keyStore=./jmx-demo.jks -Djavax.net.ssl.keyStorePassword=bserban org.abserban.jmx.client.StartClient -host:localhost -port:8787 -status:on
</pre>
<p>See the comple code from Resources section. It includes the complete java code, ant file and the keystore.</p>
<h3>Resources</h3>
<ul>
<li><a href="http://www.bserban.org/wp-content/uploads/2009/10/jmx-agent.zip">Comple source code</a></li>
<li><a href="http://java.sun.com/javase/technologies/core/mntr-mgmt/javamanagement/best-practices.jsp">JMX Best practices</a></li>
<li><a href="http://java.sun.com/javase/technologies/core/mntr-mgmt/javamanagement/articles.jsp">JMX Articles</a></li>
</ul>
<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.bserban.org%2F2009%2F10%2Fcreating-a-secure-jmx-agent-in-jdk-1-5%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.bserban.org%2F2009%2F10%2Fcreating-a-secure-jmx-agent-in-jdk-1-5%2F&amp;source=bserban&amp;style=normal&amp;service=bit.ly&amp;hashtags=Agent,JMX,JMX+Architecture,JMX+JDK+1.5,JMXConnectorServer,MBeanServer,SSL+JMX" height="61" width="50" /><br />
			</a>
		</div>
]]></content:encoded>
			<wfw:commentRss>http://www.bserban.org/2009/10/creating-a-secure-jmx-agent-in-jdk-1-5/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
