如何配置JMX仅绑定到localhost?

时间:2016-02-12 16:14:04

标签: java jmx

我在Centos6上使用JDK8运行Tomcat8。 我使用以下选项启用JMX:

CATALINA_OPTS="${CATALINA_OPTS} -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9123 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.local.only=true"

不幸的是,当我检查打开了哪些端口时,我发现这些端口会监听所有IP:

netstat -plunt | grep java
Proto Recv-Q Send-Q Local Address               Foreign Address             State       PID/Program name
tcp        0      0 :::60555                            :::*                LISTEN      22752/java
tcp        0      0 ::ffff:127.0.0.1:8080               :::*                LISTEN      22752/java
tcp        0      0 :::9123                             :::*                LISTEN      22752/java
tcp        0      0 :::40867                            :::*                LISTEN      22752/java

我想如果配置-Dcom.sun.management.jmxremote.local.only=true,所有端口都应该仅绑定到localhost(::ffff:127.0.0.1将出现在所有端口之前)。

如何配置JMX仅绑定到localhost?

我不创建JMX我使用Tomcat JMX:https://tomcat.apache.org/tomcat-8.0-doc/monitoring.html

2 个答案:

答案 0 :(得分:12)

你要求的是不必要的。

com.sun.management.jmxremote.local.only=true(顺便说一下,它已经是默认值)意味着它只会接受来自localhost的连接。它并不意味着它只会像您假设的那样绑定到环回接口。不接受来自不在本地主机上的东西的连接只是另一种方式。从sun.management.jmxremote.LocalRMIServerSocketFactory您可以看到它是这样完成的:

// Walk through the network interfaces to see
// if any of them matches the client's address.
// If true, then the client's address is local.
while (nis.hasMoreElements()) {
    NetworkInterface ni = nis.nextElement();
    Enumeration<InetAddress> addrs = ni.getInetAddresses();
    while (addrs.hasMoreElements()) {
        InetAddress localAddr = addrs.nextElement();
        if (localAddr.equals(remoteAddr)) {
            return socket;
        }
    }
}

为什么它是这样做而不是绑定到环回,我不知道。但我相信它同样安全。 (或者可能不是?)

但是如果你真的想要,那么因为Java 8u102和Java 7u131系统属性com.sun.management.jmxremote.host将底层RMI注册表绑定到选定的网络接口。该值可以是InetAddress.getByName(String)接受的任何字符串。

示例:

-Dcom.sun.management.jmxremote.host=localhost

请参阅:JDK-6425769了解详情。

链接:Java 8u102 Release Notes

文档在任何地方都没有提到的是,即使设置com.sun.management.jmxremote.host,您仍然会看到一个绑定到所有网络接口的JMX端口。这是因为如果com.sun.management.jmxremote.local.only=true将启动sun.management.jmxremote.LocalRMIServerSocketFactory的实例并且该实例不允许自定义,即它不尊重com.sun.management.jmxremote.host属性。如果这是一个错误,JDK-6425769实施中的疏忽或有意的,我不知道。

答案 1 :(得分:2)

据我所知this回答并阅读了Oracle关于它的文档,似乎没有没有的方式来配置它而不进行编码。 This在章节&#34;连接器服务器属性&#34;:

中说
  

使用默认的JRMP传输时,RMI套接字工厂可以   使用属性jmx.remote.rmi.client.socket.factory指定   和jmx.remote.rmi.server.socket.factory在给予的环境中   RMIConnectorServer构造函数。这些属性的值   必须是RMIClientSocketFactoryRMIServerSocketFactory类型,   分别。创建RMI对象时使用这些工厂   与连接器相关联。

我看到的唯一选择是实现类似here的自定义工厂,并将类名与类路径中的JAR /类一起传递给属性。

如果我错了,请纠正我。