我在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
。
答案 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了解详情。
文档在任何地方都没有提到的是,即使设置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
构造函数。这些属性的值 必须是RMIClientSocketFactory
和RMIServerSocketFactory
类型, 分别。创建RMI对象时使用这些工厂 与连接器相关联。
我看到的唯一选择是实现类似here的自定义工厂,并将类名与类路径中的JAR /类一起传递给属性。
如果我错了,请纠正我。