我在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"
Run Code Online (Sandbox Code Playgroud)
不幸的是,当我检查打开了哪些端口时,我发现这些端口会监听所有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
Run Code Online (Sandbox Code Playgroud)
我想如果我配置-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.
pet*_*erh 15
你要求的是不必要的.
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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
为什么它是这样做而不是绑定到环回,我不知道.但我相信它同样安全.(或者可能不是?)
但是如果你真的想要,那么因为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属性.如果这是一个bug,JDK-6425769实施中的疏忽或故意,我不知道.
据我理解这个答案并阅读Oracle的相关文档,似乎没有办法在不编码的情况下配置它。这在“连接器服务器属性”一章中说:
jmx.remote.rmi.client.socket.factory当使用默认的 JRMP 传输时,可以使用属性和jmx.remote.rmi.server.socket.factory在给定构造函数的环境中指定 RMI 套接字工厂RMIConnectorServer。这些属性的值必须分别为RMIClientSocketFactory和RMIServerSocketFactory类型。创建与连接器关联的 RMI 对象时将使用这些工厂。
我看到的唯一选择是实现一个像这里一样的自定义工厂,并将类名与类路径中的 JAR/类一起传递给属性。
如果我错了请纠正我。