[
https://issues.apache.org/jira/browse/TOMEE-2294?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17136310#comment-17136310
]
Frans commented on TOMEE-2294:
------------------------------
Okay! Finally some progress!
Looking at the log line
{code:java}
org.apache.activemq.broker.jmx.ManagementContext$1.run JMX consoles can connect
to service:jmx:rmi:///jndi/rmi://localhost:1099/jmxrmi {code}
I browsed through the tomee jars until I found
org.apache.activemq.broker.jmx.ManagementContext in activemq-broker-5.15.10.jar
I used FernFlower to decompile the class, and found where the line was being
logged.
Scrolling around the class, I found that createConnector was the variable used
to toggle whether or not to enable the dodgy unauthenticated JMX port, which is
by default on connectorPort = 1099
createConnector defaults to true, and is overridden by a system property:
org.apache.activemq.broker.jmx.createConnector
{code:java}
/**
* Default activemq domain
*/
public static final String DEFAULT_DOMAIN = "org.apache.activemq";
static {
String option = Boolean.TRUE.toString();
try {
option =
System.getProperty("org.apache.activemq.broker.jmx.createConnector", "true");
} catch (Exception ex) {
} DEFAULT_CREATE_CONNECTOR = Boolean.valueOf(option);
} public static final boolean DEFAULT_CREATE_CONNECTOR;
{code}
So it appears that any call to ManagementContext.getMbeanServer() - of which
there are many - tries to find an mbean server
{code:java}
public MBeanServer getMBeanServer() {
if (this.beanServer == null) {
this.beanServer = findMBeanServer();
}
return beanServer;
}{code}
Which then creates one if it's not been initialised
{code:java}
protected synchronized MBeanServer findMBeanServer() {
MBeanServer result = null; try {
if (useMBeanServer) {
if (findTigerMbeanServer) {
result = findTigerMBeanServer();
}
if (result == null) {
// lets piggy back on another MBeanServer - we could be in
an appserver!
List<MBeanServer> list =
MBeanServerFactory.findMBeanServer(null);
if (list != null && list.size() > 0) {
result = list.get(0);
}
}
}
if (result == null && createMBeanServer) {
result = createMBeanServer();
}
} catch (NoClassDefFoundError e) {
LOG.error("Could not load MBeanServer", e);
} catch (Throwable e) {
// probably don't have access to system properties
LOG.error("Failed to initialize MBeanServer", e);
}
return result;
} {code}
And no matter whether it's looking for a tiger mbean server
{code:java}
public MBeanServer findTigerMBeanServer() {
String name = "java.lang.management.ManagementFactory";
Class<?> type = loadClass(name,
ManagementContext.class.getClassLoader());
if (type != null) {
try {
Method method = type.getMethod("getPlatformMBeanServer", new
Class[0]);
if (method != null) {
Object answer = method.invoke(null, new Object[0]);
if (answer instanceof MBeanServer) {
if (createConnector) {
createConnector((MBeanServer)answer);
}
return (MBeanServer)answer;
} else {
LOG.warn("Could not cast: {} into an MBeanServer. There
must be some classloader strangeness in town", answer);
}
} else {
LOG.warn("Method getPlatformMBeanServer() does not appear
visible on type: {}", type.getName());
}
} catch (Exception e) {
LOG.warn("Failed to call getPlatformMBeanServer() due to: ", e);
}
} else {
LOG.trace("Class not found: {} so probably running on Java 1.4",
name);
}
return null;
} {code}
or creating a non-tiger mbean server
{code:java}
protected MBeanServer createMBeanServer() throws
MalformedObjectNameException, IOException {
MBeanServer mbeanServer =
MBeanServerFactory.createMBeanServer(jmxDomainName);
locallyCreateMBeanServer = true;
if (createConnector) {
createConnector(mbeanServer);
}
return mbeanServer;
}{code}
it still does a check on createConnector.
And because the useJmx=false flag isn't propagated through to the
setCreateConnector method before the first of these calls is made, and the hard
coded default for creating this JMX port is true
{code:java}
public void setCreateConnector(boolean createConnector) {
this.createConnector = createConnector;
}{code}
the connector is created.
Then, when the start method is called on the ManagementContext, because a
management server exists (and the log entries on createConnector are DEBUG, you
get that log line
{code:java}
@Override
public void start() throws Exception {
// lets force the MBeanServer to be created if needed
if (started.compareAndSet(false, true)) {
populateMBeanSuppressionMap(); // fallback and use localhost
if (connectorHost == null) {
connectorHost = "localhost";
} // force mbean server to be looked up, so we have it
getMBeanServer(); if (connectorServer != null) {
try {
if (getMBeanServer().isRegistered(namingServiceObjectName))
{
LOG.debug("Invoking start on mbean: {}",
namingServiceObjectName);
getMBeanServer().invoke(namingServiceObjectName,
"start", null, null);
}
} catch (Throwable ignore) {
LOG.debug("Error invoking start on MBean {}. This exception
is ignored.", namingServiceObjectName, ignore);
} Thread t = new Thread("JMX connector") {
@Override
public void run() {
// ensure we use MDC logging with the broker name, so
people can see the logs if MDC was in use
if (brokerName != null) {
MDC.put("activemq.broker", brokerName);
}
try {
JMXConnectorServer server = connectorServer;
if (started.get() && server != null) {
LOG.debug("Starting JMXConnectorServer...");
try {
// need to remove MDC as we must not
inherit MDC in child threads causing leaks
MDC.remove("activemq.broker");
server.start();
} finally {
if (brokerName != null) {
MDC.put("activemq.broker", brokerName);
}
connectorStarted.countDown();
}
LOG.info("JMX consoles can connect to {}",
server.getAddress());
}
} catch (IOException e) {
LOG.warn("Failed to start JMX connector {}. Will
restart management to re-create JMX connector, trying to remedy this issue.",
e.getMessage());
LOG.debug("Reason for failed JMX connector start",
e);
} finally {
MDC.remove("activemq.broker");
}
}
};
t.setDaemon(true);
t.start();
}
}
} {code}
> Can't disable unauthenticated JMX on 1099
> -----------------------------------------
>
> Key: TOMEE-2294
> URL: https://issues.apache.org/jira/browse/TOMEE-2294
> Project: TomEE
> Issue Type: Bug
> Components: TomEE Core Server
> Reporter: Frans
> Priority: Major
> Fix For: 8.0.3
>
>
> ActiveMQ comes bundled with a JMX host that is default on unauthenticated on
> port 1099.
> {code:java}
> <Resource id="JmsResourceAdapter" type="ActiveMQResourceAdapter">
> BrokerXmlConfig = broker:(vm://broker)?useJmx=false
> ServerUrl = vm://broker
> </Resource>{code}
> Tomee's resource configuration doesn't allow this to be disabled. The above
> doesn't work.
> This can be disabled by inspecting an activemq jar's manifest, pulling down
> the same version of activemq-all, and putting that in the tomee/lib
> directory, at which point this works:
> {code:java}
> <Resource id="JmsResourceAdapter" type="ActiveMQResourceAdapter">
> BrokerXmlConfig = xbean:file:activemq.xml
> ServerUrl = vm://broker
> </Resource>
> {code}
> {code:java}
> <broker xmlns="http://activemq.apache.org/schema/core"
> useJmx="false"
> brokerName="broker"
> useShutdownHook="false"
> persistent="true"
> start="true"
> schedulerSupport="false"
> enableStatistics="false"
> offlineDurableSubscriberTimeout="259200000"
> offlineDurableSubscriberTaskSchedule="3600000">
> {code}
> However, convincing the guy hosting the server to inspect JAR manifests, pull
> down specific jars, and maintain a second configuration file seems like a lot
> of effort to go to just to have the ability to disable unauthenticated access
> to every MBean in the VM
--
This message was sent by Atlassian Jira
(v8.3.4#803005)