Author: markt Date: Fri Sep 26 15:20:51 2008 New Revision: 699523 URL: http://svn.apache.org/viewvc?rev=699523&view=rev Log: Add a new listener that enables the JMX ports to be fixed. This makes using jconsole etc through a firewall / SSH tunnel etc. a lot easier. As a bonus, the config docs include all the current listeners as well.
Added: tomcat/trunk/java/org/apache/catalina/mbeans/Constants.java (with props) tomcat/trunk/java/org/apache/catalina/mbeans/JmxRemoteLifecycleListener.java (with props) tomcat/trunk/java/org/apache/catalina/mbeans/LocalStrings.properties (with props) tomcat/trunk/webapps/docs/config/listeners.xml (with props) Modified: tomcat/trunk/webapps/docs/config/project.xml Added: tomcat/trunk/java/org/apache/catalina/mbeans/Constants.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/mbeans/Constants.java?rev=699523&view=auto ============================================================================== --- tomcat/trunk/java/org/apache/catalina/mbeans/Constants.java (added) +++ tomcat/trunk/java/org/apache/catalina/mbeans/Constants.java Fri Sep 26 15:20:51 2008 @@ -0,0 +1,27 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +package org.apache.catalina.mbeans; + + +public class Constants { + + public static final String Package = "org.apache.catalina.mbeans"; + +} + Propchange: tomcat/trunk/java/org/apache/catalina/mbeans/Constants.java ------------------------------------------------------------------------------ svn:eol-style = native Added: tomcat/trunk/java/org/apache/catalina/mbeans/JmxRemoteLifecycleListener.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/mbeans/JmxRemoteLifecycleListener.java?rev=699523&view=auto ============================================================================== --- tomcat/trunk/java/org/apache/catalina/mbeans/JmxRemoteLifecycleListener.java (added) +++ tomcat/trunk/java/org/apache/catalina/mbeans/JmxRemoteLifecycleListener.java Fri Sep 26 15:20:51 2008 @@ -0,0 +1,207 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.catalina.mbeans; + +import java.io.IOException; +import java.lang.management.ManagementFactory; +import java.net.MalformedURLException; +import java.rmi.RemoteException; +import java.rmi.registry.LocateRegistry; +import java.util.HashMap; + +import javax.management.MBeanServer; +import javax.management.remote.JMXConnectorServer; +import javax.management.remote.JMXConnectorServerFactory; +import javax.management.remote.JMXServiceURL; +import javax.management.remote.rmi.RMIConnectorServer; +import javax.rmi.ssl.SslRMIClientSocketFactory; +import javax.rmi.ssl.SslRMIServerSocketFactory; + +import org.apache.catalina.Lifecycle; +import org.apache.catalina.LifecycleEvent; +import org.apache.catalina.LifecycleListener; +import org.apache.catalina.util.StringManager; +import org.apache.juli.logging.Log; +import org.apache.juli.logging.LogFactory; + +/** + * This listener fixes the port used by JMX/RMI Server making things much + * simpler if you need to connect jconsole or similar to a remote Tomcat + * instance that is running behind a firewall. Only this port is configured via + * the listener. The remainder of the configuration is via the standard system + * properties for configuring JMX. + */ +public class JmxRemoteLifecycleListener implements LifecycleListener { + + private static Log log = + LogFactory.getLog(JmxRemoteLifecycleListener.class); + + /** + * The string resources for this package. + */ + protected static final StringManager sm = + StringManager.getManager(Constants.Package); + + protected int rmiRegistryPort = -1; + protected int rmiServerPort = -1; + protected boolean rmiSSL = true; + protected String ciphers[] = null; + protected String protocols[] = null; + protected boolean clientAuth = true; + protected boolean authenticate = true; + protected String passwordFile = null; + protected String accessFile = null; + + /** + * Get the port on which the RMI server is exported. This is the port that + * is normally chosen by the RMI stack. + * @returns The port number + */ + public int getRmiServerPort() { + return rmiServerPort; + } + + /** + * Set the port on which the RMI server is exported. This is the port that + * is normally chosen by the RMI stack. + * @param theRmiServerPort The port number + */ + public void setRmiServerPort(int theRmiServerPort) { + rmiServerPort = theRmiServerPort; + } + + /** + * Get the port on which the RMI registry is exported. + * @returns The port number + */ + public int getRmiRegistryPort() { + return rmiRegistryPort; + } + + /** + * Set the port on which the RMI registryis exported. + * @param theRmiServerPort The port number + */ + public void setRmiRegistryPort(int theRmiRegistryPort) { + rmiRegistryPort = theRmiRegistryPort; + } + + private void init() { + // Get all the other parameters required from the standard system + // properties. Only need to get the parameters that affect the creation + // of the server port. + String rmiSSLValue = System.getProperty( + "com.sun.management.jmxremote.ssl", "true"); + rmiSSL = Boolean.parseBoolean(rmiSSLValue); + + String protocolsValue = System.getProperty( + "com.sun.management.jmxremote.ssl.enabled.protocols"); + if (protocolsValue != null) { + protocols = protocolsValue.split(","); + } + + String ciphersValue = System.getProperty( + "com.sun.management.jmxremote.ssl.enabled.cipher.suites"); + if (ciphersValue != null) { + ciphers = ciphersValue.split(","); + } + + String clientAuthValue = System.getProperty( + "com.sun.management.jmxremote.ssl.need.client.auth", "true"); + clientAuth = Boolean.parseBoolean(clientAuthValue); + + String authenticateValue = System.getProperty( + "com.sun.management.jmxremote.authenticate", "true"); + authenticate = Boolean.parseBoolean(authenticateValue); + + passwordFile = System.getProperty( + "com.sun.management.jmxremote.password.file", + "jmxremote.password"); + + accessFile = System.getProperty( + "com.sun.management.jmxremote.access.file", + "jmxremote.access"); + } + + + public void lifecycleEvent(LifecycleEvent event) { + // When the server starts, configure JMX/RMI + if (Lifecycle.START_EVENT == event.getType()) { + // Configure using standard jmx system properties + init(); + + // Prevent an attacker guessing the RMI object ID + System.setProperty("java.rmi.server.randomIDs", "true"); + + try { + LocateRegistry.createRegistry(rmiRegistryPort); + } catch (RemoteException e) { + log.error(sm.getString( + "jmxRemoteLifecycleListener.createRegistryFailed", + Integer.toString(rmiRegistryPort)), e); + return; + } + MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); + HashMap<String,Object> env = new HashMap<String,Object>(); + + if (rmiSSL) { + // Use SSL for RMI connection + SslRMIClientSocketFactory csf = + new SslRMIClientSocketFactory(); + SslRMIServerSocketFactory ssf = + new SslRMIServerSocketFactory(ciphers, protocols, + clientAuth); + env.put(RMIConnectorServer.RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE, + csf); + env.put(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE, + ssf); + } + if (authenticate) { + env.put("jmx.remote.x.password.file", passwordFile); + env.put("jmx.remote.x.access.file", accessFile); + } + StringBuffer url = new StringBuffer(); + url.append("service:jmx:rmi://localhost:"); + url.append(rmiServerPort); + url.append("/jndi/rmi://localhost:"); + url.append(rmiRegistryPort); + url.append("/jmxrmi"); + JMXServiceURL serviceUrl; + try { + serviceUrl = new JMXServiceURL(url.toString()); + } catch (MalformedURLException e) { + log.error(sm.getString( + "jmxRemoteLifecycleListener.invalidURL", + url.toString()), e); + return; + } + JMXConnectorServer cs; + try { + cs = JMXConnectorServerFactory.newJMXConnectorServer( + serviceUrl, env, mbs); + cs.start(); + log.info(sm.getString("jmxRemoteLifecycleListener.start", + new Integer(rmiRegistryPort), + new Integer(rmiServerPort))); + } catch (IOException e) { + log.error(sm.getString(""), e); + } + } + } + +} Propchange: tomcat/trunk/java/org/apache/catalina/mbeans/JmxRemoteLifecycleListener.java ------------------------------------------------------------------------------ svn:eol-style = native Added: tomcat/trunk/java/org/apache/catalina/mbeans/LocalStrings.properties URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/mbeans/LocalStrings.properties?rev=699523&view=auto ============================================================================== --- tomcat/trunk/java/org/apache/catalina/mbeans/LocalStrings.properties (added) +++ tomcat/trunk/java/org/apache/catalina/mbeans/LocalStrings.properties Fri Sep 26 15:20:51 2008 @@ -0,0 +1,19 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +jmxRemoteLifecycleListener.createRegistryFailed=Unable to create the RMI registry using port "{0}" +jmxRemoteLifecycleListener.invalidURL=The JMX Service URL requested, "{0}", was invalid +jmxRemoteLifecycleListener.serverFailed=The JMX connector server could not be created or failed to start +jmxRemoteLifecycleListener.start=The JMX Remote Listener has configured the registry on port {0} and the server on port {1} \ No newline at end of file Propchange: tomcat/trunk/java/org/apache/catalina/mbeans/LocalStrings.properties ------------------------------------------------------------------------------ svn:eol-style = native Added: tomcat/trunk/webapps/docs/config/listeners.xml URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/config/listeners.xml?rev=699523&view=auto ============================================================================== --- tomcat/trunk/webapps/docs/config/listeners.xml (added) +++ tomcat/trunk/webapps/docs/config/listeners.xml Fri Sep 26 15:20:51 2008 @@ -0,0 +1,201 @@ +<?xml version="1.0"?> +<!-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<!DOCTYPE document [ + <!ENTITY project SYSTEM "project.xml"> +]> +<document url="listeners.html"> + + &project; + + <properties> + <title>The LifeCycle Listener Component</title> + </properties> + +<body> + + +<section name="Introduction"> + + <p>A <strong>Listener</strong> element defines a component that performs + actions when specific events occur, usually Tomcat starting or Tomcat + stopping.</p> + + <p>Listeners may be nested inside a <a href="server.html">Server</a>, + <a href="engine.html">Engine</a>, <a href="host.html">Host</a> or + <a href="context.html">Context</a>. Some Listeners are only intended to be + nested inside specific elements. These constraints are noted in the + documentation below.</p> + +</section> + +<section name="Attributes"> + + <subsection name="Common Attributes"> + + <p>All implementations of <strong>Listener</strong> + support the following attributes:</p> + + <attributes> + + <attribute name="className" required="true"> + <p>Java class name of the implementation to use. This class must + implement the <code>org.apache.catalina.LifecycleListener</code> + interface.</p> + </attribute> + + </attributes> + + </subsection> + + <subsection name="Standard Implementation"> + + <p>Unlike most Catalina components, there are several standard + <strong>Listener</strong> implementations available. As a result, + the <code>className</code> attribute MUST be used to select the + implementation you wish to use.</p> + + <h3>APR Lifecycle Listener (org.apache.catalina.core.AprLifecycleListener)</h3> + + <p>The <strong>APR Lifecycle Listener</strong> checks for the presence of + the APR/native library and loads the library if it is present. For more + information see the <a href="../apr.html">APR/native guide</a>.</p> + + <p>This listener must only be nested within <a href="server.html">Server</a> + elements.</p> + + <p>The following additional attributes are support by the <strong>APR + Lifecycle Listener</strong>:</p> + + <attributes> + + <attribute name="SSLEngine" required="false"> + <p>Name of the SSLEngine to use. off: Do not use SSL, on: Use SSL but no + specific ENGINE. The default value is <b>on</b>. This initializes the + native SSL engine, which must be enabled in the APR/native connector by + the use of the <code>SSLEnabled</code> attribute.</p> + <p>See the <a href="http://www.openssl.org">Official OpenSSL website</a> + for more details on supported SSL hardware engines and manufacturers. + </p> + </attribute> + + </attributes> + + <h3>Jasper Listener (org.apache.catalina.core.JasperListener)</h3> + + <p>The <strong>Jasper Listener</strong> initialises the Jasper 2 JSP engine + before any web applications that may use it are loaded. For more + information on the Jasper 2 JSP engine see the + <a href="../jasper-howto.html">Jasper How To</a>.</p> + + <p>This listener must only be nested within <a href="server.html">Server</a> + elements.</p> + + <p>No additional attributes are support by the <strong>Jasper Listener + </strong>.</p> + + <h3>Server Lifecycle Listener + (org.apache.catalina.mbeans.ServerLifecycleListener)</h3> + + <p>The <strong>Server Lifecycle Listener</strong> initialises the + MBeanServer for the MBeans that may be used to manager Tomcat via JMX. + Without this listener, none of the Tomcat MBeans will be available.</p> + + <p>This listener must only be nested within <a href="server.html">Server</a> + elements.</p> + + <p>No additional attributes are support by the <strong>Server Lifecycle + Listener</strong>.</p> + + <h3>Global Resources Lifecycle Listener + (org.apache.catalina.mbeans.GlobalResourcesLifecycleListener)</h3> + + <p>The <strong>Global Resources Lifecycle Listener</strong> initialises the + Global JNDI resources defined in server.xml as part of the <a + href="globalresources.html">Global Resources</a> element. Without this + listener, none of the Global Resources will be available.</p> + + <p>This listener must only be nested within <a href="server.html">Server</a> + elements.</p> + + <p>No additional attributes are support by the <strong>Global Resources + Lifecycle Listener</strong>.</p> + + <h3>JMX Remote Lifecycle Listener + (org.apache.catalina.mbeans.JmxRemoteLifecycleListener)</h3> + + <p>The <strong>JMX Remote Lifecycle Listener</strong> fixes the port used by + the JMX/RMI Server making things much simpler if you need to connect + jconsole or a similar tool to a remote Tomcat instance that is running + behind a firewall. Only this port is configured via the listener. The + remainder of the configuration is via the standard system properties for + configuring JMX. For further information on configuring JMX see + <a href="http://java.sun.com/j2se/1.5.0/docs/guide/management/agent.html"> + Monitoring and Management Using JMX</a> included with the Java SDK + documentation.</p> + + <p>If this listener was configured in server.xml as: +<source> +<Listener className="org.apache.catalina.mbeans.JmxRemoteLifecycleListener" + rmiRegistryPort="10001" rmiServerPort="10002" /> +</source> + with the following system properties set (eg in setenv.sh): +<source> +-Dcom.sun.management.jmxremote.password.file=${catalina.base}/conf/jmxremote.password +-Dcom.sun.management.jmxremote.access.file=${catalina.base}/conf/jmxremote.access +</source> + then opening ports 10001 (RMI Registry) and 10002 (JMX/RMI Server) in your + firewall would enable jconsole to connect to a Tomcat instance running + behind a firewall. + </p> + + <p><strong>JMX access should be considered equivalent to administartive + access and secured accordingly.</strong></p> + + <p>This listener must only be nested within <a href="server.html">Server</a> + elements.</p> + + <p>The following additional attributes are support by the <strong>JMX Remote + Lifecycle Listener</strong>:</p> + + <attributes> + + <attribute name="rmiRegsitryPort" required="true"> + <p>The port to be used by the JMX/RMI registry. The replaces the use of + the <code>com.sun.management.jmxremote.port</code> system propoerty that + should not be set when using this valve.</p> + </attribute> + + <attribute name="rmiServerPort" required="true"> + <p>The port to be used by the JMX/RMI server.</p> + </attribute> + + </attributes> + + </subsection> + +</section> + +<section name="Nested Components"> + + <p>No element may be nested inside a <strong>Listener</strong>.</p> + +</section> + +</body> + +</document> Propchange: tomcat/trunk/webapps/docs/config/listeners.xml ------------------------------------------------------------------------------ svn:eol-style = native Modified: tomcat/trunk/webapps/docs/config/project.xml URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/config/project.xml?rev=699523&r1=699522&r2=699523&view=diff ============================================================================== --- tomcat/trunk/webapps/docs/config/project.xml (original) +++ tomcat/trunk/webapps/docs/config/project.xml Fri Sep 26 15:20:51 2008 @@ -54,6 +54,7 @@ </menu> <menu name="Nested Components"> + <item name="Listeners" href="listeners.html"/> <item name="Global Resources" href="globalresources.html"/> <item name="Loader" href="loader.html"/> <item name="Manager" href="manager.html"/> --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]