From: markt Date: Fri, 26 Sep 2008 22:20:51 +0000 (+0000) Subject: Add a new listener that enables the JMX ports to be fixed. This makes using jconsole... X-Git-Url: https://git.internetallee.de/?a=commitdiff_plain;h=74f9870dc34c899c917f6d98424e92ecd50cc3ce;p=tomcat7.0 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. git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@699523 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/java/org/apache/catalina/mbeans/Constants.java b/java/org/apache/catalina/mbeans/Constants.java new file mode 100644 index 000000000..ff0c963d0 --- /dev/null +++ b/java/org/apache/catalina/mbeans/Constants.java @@ -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"; + +} + diff --git a/java/org/apache/catalina/mbeans/JmxRemoteLifecycleListener.java b/java/org/apache/catalina/mbeans/JmxRemoteLifecycleListener.java new file mode 100644 index 000000000..634e18f66 --- /dev/null +++ b/java/org/apache/catalina/mbeans/JmxRemoteLifecycleListener.java @@ -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 env = new HashMap(); + + 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); + } + } + } + +} diff --git a/java/org/apache/catalina/mbeans/LocalStrings.properties b/java/org/apache/catalina/mbeans/LocalStrings.properties new file mode 100644 index 000000000..8c5c7b52d --- /dev/null +++ b/java/org/apache/catalina/mbeans/LocalStrings.properties @@ -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 diff --git a/webapps/docs/config/listeners.xml b/webapps/docs/config/listeners.xml new file mode 100644 index 000000000..c7fce023b --- /dev/null +++ b/webapps/docs/config/listeners.xml @@ -0,0 +1,201 @@ + + + +]> + + + &project; + + + The LifeCycle Listener Component + + + + + +
+ +

A Listener element defines a component that performs + actions when specific events occur, usually Tomcat starting or Tomcat + stopping.

+ +

Listeners may be nested inside a Server, + Engine, Host or + Context. Some Listeners are only intended to be + nested inside specific elements. These constraints are noted in the + documentation below.

+ +
+ +
+ + + +

All implementations of Listener + support the following attributes:

+ + + + +

Java class name of the implementation to use. This class must + implement the org.apache.catalina.LifecycleListener + interface.

+
+ +
+ +
+ + + +

Unlike most Catalina components, there are several standard + Listener implementations available. As a result, + the className attribute MUST be used to select the + implementation you wish to use.

+ +

APR Lifecycle Listener (org.apache.catalina.core.AprLifecycleListener)

+ +

The APR Lifecycle Listener checks for the presence of + the APR/native library and loads the library if it is present. For more + information see the APR/native guide.

+ +

This listener must only be nested within Server + elements.

+ +

The following additional attributes are support by the APR + Lifecycle Listener:

+ + + + +

Name of the SSLEngine to use. off: Do not use SSL, on: Use SSL but no + specific ENGINE. The default value is on. This initializes the + native SSL engine, which must be enabled in the APR/native connector by + the use of the SSLEnabled attribute.

+

See the Official OpenSSL website + for more details on supported SSL hardware engines and manufacturers. +

+
+ +
+ +

Jasper Listener (org.apache.catalina.core.JasperListener)

+ +

The Jasper Listener 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 + Jasper How To.

+ +

This listener must only be nested within Server + elements.

+ +

No additional attributes are support by the Jasper Listener + .

+ +

Server Lifecycle Listener + (org.apache.catalina.mbeans.ServerLifecycleListener)

+ +

The Server Lifecycle Listener 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.

+ +

This listener must only be nested within Server + elements.

+ +

No additional attributes are support by the Server Lifecycle + Listener.

+ +

Global Resources Lifecycle Listener + (org.apache.catalina.mbeans.GlobalResourcesLifecycleListener)

+ +

The Global Resources Lifecycle Listener initialises the + Global JNDI resources defined in server.xml as part of the Global Resources element. Without this + listener, none of the Global Resources will be available.

+ +

This listener must only be nested within Server + elements.

+ +

No additional attributes are support by the Global Resources + Lifecycle Listener.

+ +

JMX Remote Lifecycle Listener + (org.apache.catalina.mbeans.JmxRemoteLifecycleListener)

+ +

The JMX Remote Lifecycle Listener 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 + + Monitoring and Management Using JMX included with the Java SDK + documentation.

+ +

If this listener was configured in server.xml as: + +<Listener className="org.apache.catalina.mbeans.JmxRemoteLifecycleListener" + rmiRegistryPort="10001" rmiServerPort="10002" /> + + with the following system properties set (eg in setenv.sh): + +-Dcom.sun.management.jmxremote.password.file=${catalina.base}/conf/jmxremote.password +-Dcom.sun.management.jmxremote.access.file=${catalina.base}/conf/jmxremote.access + + 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. +

+ +

JMX access should be considered equivalent to administartive + access and secured accordingly.

+ +

This listener must only be nested within Server + elements.

+ +

The following additional attributes are support by the JMX Remote + Lifecycle Listener:

+ + + + +

The port to be used by the JMX/RMI registry. The replaces the use of + the com.sun.management.jmxremote.port system propoerty that + should not be set when using this valve.

+
+ + +

The port to be used by the JMX/RMI server.

+
+ +
+ +
+ +
+ +
+ +

No element may be nested inside a Listener.

+ +
+ + + +
diff --git a/webapps/docs/config/project.xml b/webapps/docs/config/project.xml index db556387d..05a6ec9fe 100644 --- a/webapps/docs/config/project.xml +++ b/webapps/docs/config/project.xml @@ -54,6 +54,7 @@ +