java 如何配置 JMX 以仅绑定到 localhost?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/35367232/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to configure JMX to bind to localhost only?
提问by Michael
I run Tomcat8 using JDK8 on Centos6. I enable JMX using the following options:
我在 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"
Unfortunately, when I check what ports are opened I discover that these ports listen to all IP:
不幸的是,当我检查打开了哪些端口时,我发现这些端口侦听所有 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
I suppose that if I configure -Dcom.sun.management.jmxremote.local.only=true
all ports should be bind to localhost only (::ffff:127.0.0.1
will appear before all ports).
我想如果我配置-Dcom.sun.management.jmxremote.local.only=true
所有端口应该只绑定到本地主机(::ffff:127.0.0.1
将出现在所有端口之前)。
How to configure JMX to bind to localhost only?
如何配置 JMX 以仅绑定到 localhost?
Added
添加
I do not create JMX I use Tomcat JMX: https://tomcat.apache.org/tomcat-8.0-doc/monitoring.html
.
我不创建 JMX 我使用 Tomcat JMX: https://tomcat.apache.org/tomcat-8.0-doc/monitoring.html
.
采纳答案by Michael-O
As far as I understand thisanswer and read Oracle's docs about it, there seems to be noway to configure it without coding. Thissays in the chapter "Connector server attributes":
据我了解这个答案并阅读了有关它的 Oracle 文档,似乎没有办法在没有编码的情况下配置它。这在“连接器服务器属性”一章中说:
When using the default JRMP transport, RMI socket factories can be specified using the attributes
jmx.remote.rmi.client.socket.factory
andjmx.remote.rmi.server.socket.factory
in the environment given to theRMIConnectorServer
constructor. The values of these attributes must be of typeRMIClientSocketFactory
andRMIServerSocketFactory
, respectively. These factories are used when creating the RMI objects associated with the connector.
使用默认的 JRMP 传输时,可以使用属性指定 RMI 套接字工厂,
jmx.remote.rmi.client.socket.factory
并jmx.remote.rmi.server.socket.factory
在给定RMIConnectorServer
构造函数的环境中指定。这些属性的值的类型必须是RMIClientSocketFactory
和RMIServerSocketFactory
分别。这些工厂在创建与连接器关联的 RMI 对象时使用。
The only option I see is to implement a custom factory like hereand pass the classname to the property along with the JAR/class in classpath.
我看到的唯一选择是实现像这里这样的自定义工厂,并将类名与类路径中的 JAR/类一起传递给属性。
Correct me if I am wrong.
如果我错了,请纠正我。
回答by peterh
What you ask for is unnecessary.
你所要求的是不必要的。
com.sun.management.jmxremote.local.only=true
(which by the way is already the default) means it will only acceptconnections from localhost. It doesn't mean it will only bind to the loopback interface as you assume. Not accepting connections from something not on the local host is just another way of doing it. From sun.management.jmxremote.LocalRMIServerSocketFactory
you can see it is being done like this:
com.sun.management.jmxremote.local.only=true
(顺便说一下,这已经是默认设置)意味着它只会接受来自本地主机的连接。这并不意味着它只会像您假设的那样绑定到环回接口。不接受来自不在本地主机上的东西的连接只是另一种方式。从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;
}
}
}
Why it was done like this rather than binding to loopback, I don't know. But I believe it is just as secure. (or maybe not?)
为什么这样做而不是绑定到环回,我不知道。但我相信它同样安全。(或者可能不是?)
But if you really want to, then since Java 8u102 and Java 7u131 system property com.sun.management.jmxremote.host
binds the underlying RMI registry to the selected network interface. The value can be any string which is accepted by InetAddress.getByName(String).
但是,如果您真的想要,那么由于 Java 8u102 和 Java 7u131 系统属性会将com.sun.management.jmxremote.host
底层 RMI 注册表绑定到选定的网络接口。该值可以是InetAddress.getByName(String)接受的任何字符串。
Example:
例子:
-Dcom.sun.management.jmxremote.host=localhost
-Dcom.sun.management.jmxremote.host=localhost
see: JDK-6425769for more information.
有关更多信息,请参阅:JDK-6425769。
Links: Java 8u102 Release Notes
What the docs doesn't mention anywhere is that even when setting com.sun.management.jmxremote.host
you'll still see one JMX port which is bound to all network interfaces. This is because if com.sun.management.jmxremote.local.only=true
then an instance of sun.management.jmxremote.LocalRMIServerSocketFactory
will be started and that one doesn't allow customization, i.e. it doesn't respect com.sun.management.jmxremote.host
property. If that is a bug, an oversight in the JDK-6425769implementation or intentional, I do not know.
文档在任何地方都没有提到的是,即使在设置时,com.sun.management.jmxremote.host
您仍然会看到一个绑定到所有网络接口的 JMX 端口。这是因为如果com.sun.management.jmxremote.local.only=true
然后sun.management.jmxremote.LocalRMIServerSocketFactory
将启动一个实例并且该实例不允许自定义,即它不尊重com.sun.management.jmxremote.host
属性。如果这是一个错误,JDK-6425769实现中的疏忽还是故意的,我不知道。