Objectopia

Author Archive

Securing your JBoss JMX Invoker Layer

Posted by Jon Court on October 1, 2009

If you use JBoss and have a nicely secured JMX Console and/or Web Console it’s a fairly safe bet that, like me, you haven’t secured the invoker layer; meaning any old monkey can most likely shutdown your container whenever they feel like it.

Recently I implemented an MBean in JBoss to use as a batch trigger from a ControlM implementation and was surprised (probably shouldn’t have been though) that all my carefully crafted security for the JMXConsole and Web Console was ignored with complete impunity by the tool (twiddle.sh) that I used to invoke my MBean. Since then I’ve been through a pile of pain trying to get an RMI call to a JBoss XMBean to require authentication and I thought I’d put some instructions in plain language on how to do it.

I do this for two reasons:

  1. because I bet a lot of developers miss this one; and
  2. because the documentation and other information I find online is limited and confusing.

For demonstration I’m going to use a standard JBoss MBean for setting system properties in a running application container.

A Simple Example of Setting a System Property in JBoss using Twiddle

Using the default JBoss version of twiddle.sh (in the bin directory beneath JBoss home) against the default JNP location of JBoss (localhost:1099) you can execute the following to set a system property in a running container.

# this assumes you're in the bin directory of JBoss Home.
./twiddle.sh -s localhost:1099 invoke "jboss:type=Service,name=SystemProperties" set myprop mypropvalue
'null'

To verify that you have been succesful (assuming you didn’t get an exception in the last operation) you can do the following:

# this assumes you're in the bin directory of JBoss Home.
./twiddle.sh -s localhost:1099 invoke "jboss:type=Service,name=SystemProperties" get myprop
mypropvalue

This example will work from anywhere on your network where you’re not prevented from reaching the JNP URL of the container (prevented by a firewall or IP filter for example) regardless of the JMX Console and Web Console security you’ve put in place (there is plenty of documentation around for securing the JMX Console and Web Console). This is because the JMX Console and Web Console are HTTP based and as such are secured in the normal way you would secure a website on JBoss (i.e. in web-inf.xml and jboss-web.xml) whereas the invoker layer is not HTTP based and as such must use an alternate method of security; the key file in this operation is the jmx-invoker-service.xml file in the JBoss deploy directory.

Securing the Invoker Layer

The invoker layer is the one you are calling through when you query or invoke on an MBean via RMI (i.e. with twiddle.sh – as above). This layer is not subject to the security constraints you will have placed on your HTTP based JMX Console or Web Consoles.

To make this layer secure the key file you’re interested in is the jmx-invoker-service.xml in the JBoss deploy directory; and the key operation configuration you will need to change is for ‘invoke’.

The default configuration of the invoke operation in this file is:

<server>

	<!-- excluded for brevity -->

	<mbean code="org.jboss.jmx.connector.invoker.InvokerAdaptorService" name="jboss.jmx:type=adaptor,name=Invoker" xmbean-dd="">
		<xmbean>
			<description>The JMX Detached Invoker Service</description>
			<class>org.jboss.jmx.connector.invoker.InvokerAdaptorService</class>

			<!-- excluded for brevity -->

			<operation>
				<description>The detached invoker entry point</description>
				<name>invoke</name>
				<parameter>
					<description>The method invocation context</description>
					<name>invocation</name>
					<type>org.jboss.invocation.Invocation</type>
				</parameter>
				<return-type>java.lang.Object</return-type>
				<descriptors>
					<interceptors>

						<!-- Uncomment to require authenticated users -->
						<!-- <interceptor code="org.jboss.jmx.connector.invoker.AuthenticationInterceptor" securityDomain="java:/jaas/jmx-console"/> -->

						<!-- Interceptor that deals with non-serializable results -->
						<interceptor code="org.jboss.jmx.connector.invoker.SerializableInterceptor" policyClass="StripModelMBeanInfoPolicy"/>

					</interceptors>
				</descriptors>
			</operation>
		</xmbean>
	</mbean>
</server>

So to switch on authentication we do what it says and ‘Uncomment to require authenticated users’:

<server>

	<!-- excluded for brevity -->

	<mbean code="org.jboss.jmx.connector.invoker.InvokerAdaptorService" name="jboss.jmx:type=adaptor,name=Invoker" xmbean-dd="">
		<xmbean>
			<description>The JMX Detached Invoker Service</description>
			<class>org.jboss.jmx.connector.invoker.InvokerAdaptorService</class>

			<!-- excluded for brevity -->

			<operation>
				<description>The detached invoker entry point</description>
				<name>invoke</name>
				<parameter>
					<description>The method invocation context</description>
					<name>invocation</name>
					<type>org.jboss.invocation.Invocation</type>
				</parameter>
				<return-type>java.lang.Object</return-type>
				<descriptors>
					<interceptors>

						<!-- Uncomment to require authenticated users -->
						<interceptor code="org.jboss.jmx.connector.invoker.AuthenticationInterceptor" securityDomain="java:/jaas/jmx-console"/>

						<!-- Interceptor that deals with non-serializable results -->
						<interceptor code="org.jboss.jmx.connector.invoker.SerializableInterceptor" policyClass="StripModelMBeanInfoPolicy"/>

					</interceptors>
				</descriptors>
			</operation>
		</xmbean>
	</mbean>
</server>

If you haven’t changed the default security realm for your JMX Console (i.e. java:/jaas/jmx-console) you will now have an invoker layer secured with the same credentials as for your JMX Console. To change this add a new security realm to your global login-config.xml in the conf directory of your container and match the name you give it in the securityDomain attribute of the Authentication Interceptor.

I’ve not yet delved too deeply into setting a specific set of roles, at this point I set my invoker user to JBossAdmin which means that user can do pretty much anything exposed to JMX. That’s ok for my purposes tho (feel free to write a response with the details of setting roles for particular JMX functions :-) ).

Invoking on a Secure Invoker Layer

Ok so now that it’s secure how do you invoke an operation on it?

With the default JBoss twiddle.sh utility there are arguments -u (or –user=) for user and -p (–password=) for password.

# this assumes you're in the bin directory of JBoss Home.
./twiddle.sh -s localhost:1099 --user=myuser --password=mypassword invoke "jboss:type=Service,name=SystemProperties" get myprop
mypropvalue

These arguments work fine except your password is now in clear text and even worse is visible in the process list while it’s executing – in clear text with ‘password=’ conveniently placed for extraction by a simple script!! This seems a bit of an oversight in the tool to me.

To get around this issue in my environment I took the source and modified the main class of twiddle.jar to accept a password from Standard In (patch is below – no promises or guarantees though) which prevents the password showing in your password list and allows you to use standard encryption utilities to decrypt and pipe it into the process without ever making it visible clear text.

You would now invoke as follows:

# this assumes you're in the bin directory of JBoss Home.
mypassword | ./twiddle.sh -s localhost:1099 --user=myuser invoke "jboss:type=Service,name=SystemProperties" get myprop
mypropvalue

or better; from an encrypted password file (or better yet a repository) such as follows:

# this assumes you're in the bin directory of JBoss Home and have previously encrypted your password and encryption key into ~/.<username>.key and ~/.<username>.psw.
KEY=`cat ~/.<execution username>.key`
PWD=`cat ~/.<execution username>.psw | crypt $KEY`

PWD | ./twiddle.sh -s localhost:1099 --user=myuser invoke "jboss:type=Service,name=SystemProperties" get myprop
mypropvalue

to encrypt your password to be used as above you might do:

echo "<password>" | crypt > ~/.<execution username>.psw

which will request an encryption key which you would save as follows (for this example anyway):

cat "<encryption key>" > ~/.<execution username>.key

These files would, of course, be accessable only from your execution user.

Securing the JMX Console

For reference the key files you’re interested in here are:

  • conf/login-config.xml
  • deploy/jmx-console.war/META-INF/web.xml
  • deploy/jmx-console.war/META-INF/jboss-web.xml

Securing the JMX Web Console

For reference the key files you’re interested in here are:

  • conf/login-config.xml
  • deploy/management/web-console.war/META-INF/web.xml
  • deploy/management/web-console.war/META-INF/jboss-web.xml

Stack

These instructions will apply broadly but for reference purposes the stack I have is:

  • JBoss 4.2.3.GA
  • Java jdk1.6.0_13
  • Windows XP or Solaris 10

References

http://www.jboss.org/community/wiki/Twiddle

http://www.jboss.org/community/wiki/jbossserver-aquicktour

https://jira.jboss.org/jira/secure/attachment/12313982/jboss-securejmx.pdf (PDF Document)

Regards,
Jon

:)

Patch For Twiddle to Take Password from StdIn (no promises or guarantees)


Index: src/main/org/jboss/console/twiddle/Twiddle.java
===================================================================
--- src/main/org/jboss/console/twiddle/Twiddle.java    (revision 94201)
+++ src/main/org/jboss/console/twiddle/Twiddle.java    (working copy)
@@ -24,8 +24,10 @@
 import gnu.getopt.Getopt;
 import gnu.getopt.LongOpt;

+import java.io.BufferedReader;
 import java.io.File;
 import java.io.InputStream;
+import java.io.InputStreamReader;
 import java.io.PrintWriter;
 import java.net.MalformedURLException;
 import java.net.URL;
@@ -41,7 +43,6 @@
 import javax.naming.Context;
 import javax.naming.InitialContext;
 import javax.naming.NamingException;
-
 import org.jboss.console.twiddle.command.Command;
 import org.jboss.console.twiddle.command.CommandContext;
 import org.jboss.console.twiddle.command.CommandException;
@@ -148,7 +149,7 @@
 }
 };
 }
-
+
 public Command createCommand(final String name)
 throws NoSuchCommandException, Exception
 {
@@ -383,7 +384,7 @@

 out.println("A JMX client to 'twiddle' with a remote JBoss server.");
 out.println();
-      out.println("usage: " + PROGRAM_NAME + " [options] <command> [command_arguments]");
+      out.println("usage: [echo <password> | ] " + PROGRAM_NAME + " [options] <command> [command_arguments]");
 out.println();
 out.println("options:");
 out.println("    -h, --help                Show this help message");
@@ -397,6 +398,10 @@
 out.println("    -u, --user=<name>         Specify the username for authentication");
 out.println("    -p, --password=<name>     Specify the password for authentication");
 out.println("    -q, --quiet               Be somewhat more quiet");
+      out.println();
+      out.println("A password should be passed in by echoing it and piping it to the command. If you");
+      out.println("use the -p (--password) option your password may be visible in clear text in a ");
+      out.println("process listing such as `ps -ef`.");
 out.flush();
 }

@@ -421,6 +426,28 @@
 Getopt getopt = new Getopt(PROGRAM_NAME, args, sopts, lopts);
 int code;

+        /* Get standard in if it's there - assume it's a password. This is to allow a password to be passed and
+         * prevent it showing in a process listing (e.g. ps -ef in Unix). The -p argument will be ignored if
+         * the password is passed through Standard In.
+         */
+        boolean passwordRetrievedFromStdIn = false;
+        if (System.in.available() > 0) {
+            InputStreamReader inp = new InputStreamReader(System.in);
+            BufferedReader br = new BufferedReader(inp);
+            String stdin = br.readLine();
+
+            if (stdin != null &amp;&amp; stdin.trim().length() > 0) {
+                String password = stdin.trim();
+                SecurityAssociation.setCredential(password);
+
+                passwordRetrievedFromStdIn = true;
+
+                if (log.isDebugEnabled()) {
+                    log.debug("Password retrieved from standard in. Ignoring -p argument.");
+                }
+            }
+        }
+
 PROCESS_ARGUMENTS:

 while ((code = getopt.getopt()) != -1)
@@ -531,8 +558,13 @@
 SecurityAssociation.setPrincipal(new SimplePrincipal(username));
 break;
 case 'p':
-                 String password = getopt.getOptarg();
-                 SecurityAssociation.setCredential(password);
+                  if (!passwordRetrievedFromStdIn) {
+                     String password = getopt.getOptarg();
+                     SecurityAssociation.setCredential(password);
+
+                     log.warn("Password retrieved from -p argument. Your password may be visible in cleartext in a process listing during execution. " +
+                             "Consider using Standard In to enter the password instead (i.e. echo \"password\" | twiddle ...)");
+                  }
 break;

 // Enable quiet operations
 light="true"

Posted in Java etc... | Tagged: , , , , , , , , , , , , , , | 3 Comments »

Passionate About Programming

Posted by Jon Court on June 27, 2009

Today I bought The Passionate Programmer from the Pragmatic Bookstore; this is the 2nd Edition of My Job Went to India: 52 Ways to Save Your Job and has been re-targeted more clearly at becoming an ‘awesome developer’ rather than ‘doing enough to not get fired’ which the earlier title implied. While buying this I was distracted by a post on The Pragmatic Life blog called Share Your Passion which inspired me to share what it is that makes us (the bloggers here) passionate about developing software. BTW: So far the book is great – thanks Chad.

There is synchronicity at play here; when we started this blog the other day we were toying with subtitles and one of the ones we considered seriously was a tongue in check ‘awesomeness codified’ (personally I still like this the best even though I didn’t come up with it :-P ). Part of the reason we started this blog is to put stuff out in the public domain to get feedback. To reach out to people who know and understand more than us in the public domain and to share what we’ve found to those close behind us on the curve. We are hoping to get the sort of feedback that will help us move closer to ‘awesomeness’ in software development. We also want to have a place to whinge about things we find annoying :-P .

Each of us is near the top of the chain in our organisation; we have broad and deep skills in many areas of the Java and Java EE space and have been around the block many times in both successful and failed projects; we’ve been shouted at, we’ve worked all night, gotten depressed and received accolades and glory. Also, a large part of our experience has been in banking – which has it’s own world of pain points but can also be a glorious industry to work in for a software developer.

Obviously you take the good with the bad – but how have we kept our heads above water (psychologically) during the bad times – it is because we are passionate about what we do and deep down we are still enjoying the cut and thrust of software development it even when the poo is hitting the fan.

We were discussing recently how much we enjoyed one night a few years ago where we were in the office all night and most of the next day (after a full days work too) because of the intensity of the situation that the business was in. Basically we received in one night far more volume than was expected and we had to ‘massage’ it through systems that were in their infancy and in no way ready to scale to the level of data we had to process. Regardless of how we got into this situation (obviously in an ideal world we might have planned better) we had to now manage it and were on the critical path of a successful or failed year end process (i.e. make or lose lotsa money). This meant that we had some very senior executive director level people in the business right down to the current season of graduate interns and us all working as a unit, in the zone, to get over the line. It was stressful, difficult and tiring but we felt a part of something; we were able to display skills and aptitudes in a very visible way and deliver results instantly, not just the results in managing overburdened systems but in joining business decisions using peripheral skills gained in building software for the business we were a part of. It was an environment of mutual trust and respect with everybody intensely focused on a positive outcome regardless of position or role in the business. This is awesomeness codified.

Anyway, back to the point – we want to become ‘awesome developers’. This doesn’t mean ‘they who know the most api calls in the java.lang package’ or ‘they who can make JBoss sing the national anthem – in a language of your choice (while washing the dishes)’*; it means we want to love what we are doing and to inspire others (in the space) to love what they are doing; it means we want to be able to deliver robust, reusable, reliable and ‘awesome’ solutions better and better every time; it means we accept that someone will always know more than us and that we will strive to meet those people that we might incorporate what they know into delivering better and better solutions; it means we want to be a part of and understand the businesses we work with and within, again so we can deliver better and better solutions; it means we want colleagues (it & business) to say ‘wow, they really care about what they do’.

So this is why we blog. We want the feedback; we want to attract developers who are already awesome – though they may not know it – to help us improve. However, to be brutally honest maybe we just want to be famous :) .

* we can though, well – maybe not the dishes bit.

Posted in Opinion | Tagged: , , , | 1 Comment »

Using aspects of Maven, Ant and Ivy for a Robust and Reusable Build System. Part 1.

Posted by Jon Court on June 21, 2009

Introduction

Over the last four or so years I’ve been working with systems composed of many small to medium sized components. These components are either combined as dependencies or integrated as services to each other. For each component an individual build and release procedure and technology suite has been required; and though the technology has generally been the same it’s been my experience that each and every build is it’s own individual beast.

From the experiences I’ve gained in our efforts to improve the build structure I have quite a good understanding of what a bad and a good build system looks like. Over the next few weeks I’m going to write down the conclusions we have come too and what I think is a solid build system which makes good use of the tools we have in the industry at present. In this I’m hoping to showcase the strengths of Ivy and Maven; and how their different philosophies might be stronger when used together.

The tools I will be showcasing will be Apache Ant, Apache Ivy and Apache Maven.

The Problem

The suite of problems that we have faced repeatedly were:

  1. Each build was created independently of the others meaning there was no consistency to the patterns used. There was a learning curve every time you move to a different component.
  2. Each components build file was generally a copy of another components build script with masses of subtle ‘tweaks’ to make it fit. Often this was done by a developer who didn’t really understand the original build all that well causing subtle changes in the meaning of some of the targets and other properties. When a build looks the same but really isn’t mistakes are always made when you’re updating it.
  3. There was no dependency management. Build files referenced a committed project dedicated to storing 3rd party jars, and builds of components. This project was more than 4GB by the time we got rid of it. Checking that out from CVS would take hours and without it no builds (scripted or IDE based) worked.
  4. Many of the component projects had interdependencies in the IDE Workspace (we use Eclipse), which presented a challenge to any developer’s computer to process. Opening a workspace meant the computer was unusable frequently during the day while an IDE build was taking place.
  5. Getting a workspace set-up for a new starter on the team usually took someone on the team plus the new starter a full day.

These problems added up to considerably frustration and time as you might imagine.

Build and Release Principals

The suite of principals that I follow for a build and release process is below. I don’t pretend to have come up with these – they are often accepted industry practice and I only reiterate them.

  1. Every build is a candidate for release. There is no separation between an ‘integration’ build and a ‘release’ build and I believe the terms should be dropped all together. To qualify this I should say ‘any build done on the build server is a candidate for release’. In treating following this principal you remove the need to have a ‘special’ build with differences from the build you use every other time. Using the same build implementation in all cases makes it far easier to make it reusable and it means you don’t need a second build configuration on your build server – again a source of differences. Note however that I don’t suggest you treat builds done on a developers machine as release candidates as there is too much room for unknowns to enter the build and a developer build is rarely if ever repeatable – that’s not to say they should use a different build however. Separating a local build from a build server build is a problem for your dependency management system not the build itself.
  2. Every build has a unique and permanent build number; i.e. avoid update-able artefacts. To support having every build as a candidate for release it’s necessary for every build to be uniquely identifiable and unchanging. It should not be possible to re-use a build number for another build of the same artefact.
  3. You must be able to retrieve the exact code that went into any numbered build; i.e. tag every successful build. If any build is a candidate for release then it may actually make it all the way to Production. For Production you you need to be able the pull up exactly the code that went into it for debugging and support. This means every build should be traceable back to the code – hence the code should be tagged for every build. Tagging should be an integral and automated part of the build. In CVS you have to generate an explicit tag; in Subversion you could probably get away with recording the commit id of the build in the output and/or build job or similar – still it’s probably better to tag explicitly. You might think – wow, that’s a lot of tags – but it’s not really unless your smashing a CI server with build-able commits every few minutes; and even then if your tagging convention is intelligent it’s easy to skim the tags to the one you want. How often do you really need to pull up a tag? Usually it’s a branch already or simply Trunk (HEAD in CVS) anyway.
  4. Builds must be repeatable. They should be scripted and tagged at the very least; exporting a jar from an IDE is not a repeatable build. Tagging is not necessary in a local machine build where it is just for some developer testing but the build itself should still be done by the same script as you would use for a QA or Production grade build.
  5. A dedicated build server is important. To satisfy the requirement to have repeatable builds it’s important to have a an environment that only changes in a controlled fashion. Developers machines are not a controlled environment. This doesn’t have to be a Continuous Integration (CI) server (thought it is recommended); a dedicated build machine is under someone’s desk would be sufficient initially (for a small team anyway). It shouldn’t be an install of an IDE that is doing the build on the dedicated machine either – IDE’s can do all sorts of unknowable and unrepeatable ‘magic’ under the covers for a build.
  6. Dependency management makes your life much easier. Maven or Ivy fill this role admirably.
  7. Unit test execution must be a part of the build. Just get it going – it’s surprisingly easy to embed it in your build script and automating it encourages to developers to write more and better unit tests.
  8. It’s got to be easily reusable. If a completely new build is used for each and every project (even if it’s copy/paste) then every project will ultimately be built differently. While each of these may accomplish all of these principals it’s going to be difficult for developers to transfer between projects. The build structure or style should be second nature to every developer in team; struggling to understand how the build works for a project that would otherwise be structured the same is not a good place to be – there is business functionality to write!! Note also that nothing can be considered ‘reusable’ until its actually been reused successfully.

Some principals which are not directly related to a build implementation, but do have overlap are:

  1. A ‘sign-off’ process for deploying artefacts through to UAT and Production should be in place.
  2. Artefacts should be promotable; i.e. don’t embed environment information in your artefacts. You should be able to promote an artefact from System Test, to UAT to Production without changing it in any way. This means all environment specific information should be externalised. In larger organisations the environment information would normally be inaccessible to developers from UAT upwards (to Production); there would normally be an Environments or Operations team with the responsibility of maintaining UAT and Production environments.

What’s Next

In the next post I’m going to cover the structure and technology of the build we are using now and describe why we think it’s far better than what we’ve had before.

Reblog this post [with Zemanta]

Posted in Java etc... | Tagged: , , , | Leave a Comment »

MS Word for Mac – Hate the Toolbox

Posted by Jon Court on June 18, 2009

Is it just me or is the toolbox in MS Word 2008 for Mac ridiculously small (read: horrid). I’m battling with a document with many styles at the moment and am finding myself scrolling up and down, up and down endlessly in a scroll window that displays 5 styles at a time. I’ve got RSI just thinking about it.

On a lighter note – I’m lovin’ the new Ribbon concept in the Windows version. Who ever designed that deserves a pat on the back (and a big bonus). It takes a little getting used to but is just great when your up the learning curve.

If there is some friendly competition between the Word for Mac and the Word for Windows UI teams then I think the Windows team well and truly wins this round.

Jon

PS: If anyone knows how to increase the size of the toolbox or dock it please tell me how. Please – I’m dying here.

Posted in Grrrr... | Tagged: | Leave a Comment »