Java – spring: you cannot connect to JMX server from behind the firewall using RMI

My spring application runs on the machine behind the NAT firewall (pfsense) The internal IP of the machine is a.b.c.d and the NAT IP is w.x.y.z

The serviceurl configured by spring is set as my internal IP (a.b.c.d) on port 1100. When I start the application, I provide the following switches:

-Dcom.sun.management.jmxremote -Djava.rmi.server.hostname=w.x.y.z -Dcom.sun.management.jmxremote.port=1099 -Dcom.sun.management.jmxremote.local.only=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false

As shown above, I set - DJava rmi. server. Hostname = w.x.y.z to connect to the application through NAT I also opened the relevant port on the machine firewall and set the port from w.x.y.z: 1100 to a.b.c.d: 1100

When I tried to connect to the application from outside the network using jconsole on w.x.y.z: 1100, I got a Java io. IOException:jmxrmi

java.io.IOException: jmxrmi
at sun.tools.jconsole.ProxyClient.checkSslConfig(ProxyClient.java:236)
at sun.tools.jconsole.ProxyClient.<init>(ProxyClient.java:127)
at sun.tools.jconsole.ProxyClient.getProxyClient(ProxyClient.java:483)
at sun.tools.jconsole.JConsole$3.run(JConsole.java:524)
 Caused by: java.rmi.NotBoundException: jmxrmi
at sun.rmi.registry.RegistryImpl.lookup(RegistryImpl.java:136)
at sun.rmi.registry.RegistryImpl_Skel.dispatch(UnkNown Source)
at sun.rmi.server.UnicastServerRef.oldDispatch(UnicastServerRef.java:409)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:267)
at sun.rmi.transport.Transport$1.run(Transport.java:177)
at sun.rmi.transport.Transport$1.run(Transport.java:174)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:173)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:556)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:811)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:670)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:744)
at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:275)
at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:252)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:378)
at sun.rmi.registry.RegistryImpl_Stub.lookup(UnkNown Source)
at sun.tools.jconsole.ProxyClient.checkSslConfig(ProxyClient.java:234)

If I try to connect using jconsole on w.x.y.z: 1099, I will receive Java rmi. Connectexception How do I expose my JMX MBean outside the natted firewall?

java.rmi.ConnectException: Connection refused to host: w.x.y.z; nested exception is: 
java.net.ConnectException: Operation timed out
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:619)
at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:216)
at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:202)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:129)
at javax.management.remote.rmi.RMIServerImpl_Stub.newClient(UnkNown Source)
at javax.management.remote.rmi.RMIConnector.getConnection(RMIConnector.java:2373)
at javax.management.remote.rmi.RMIConnector.connect(RMIConnector.java:297)
at sun.tools.jconsole.ProxyClient.tryConnect(ProxyClient.java:355)
at sun.tools.jconsole.ProxyClient.connect(ProxyClient.java:313)
at sun.tools.jconsole.VMPanel$2.run(VMPanel.java:292)
Caused by: java.net.ConnectException: Operation timed out
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:339)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:200)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:182)
at java.net.socksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.socket.connect(Socket.java:579)
at java.net.socket.connect(Socket.java:528)
at java.net.socket.<init>(Socket.java:425)
at java.net.socket.<init>(Socket.java:208)
at sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket(RMIDirectSocketFactory.java:40)
at sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket(RMIMasterSocketFactory.java:147)
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:613)
... 9 more

Interestingly, I can use telnet to connect to two ports (1099 and 1100) on w.x.y.z

The relevant parts of my spring configuration are:

<bean id="registry" class="org.springframework.remoting.rmi.RmiRegistryfactorybean">
    <property name="port" value="1100" />
</bean>
<bean id="serverConnector" class="org.springframework.jmx.support.ConnectorServerfactorybean" depends-on="registry">
    <property name="server" ref="mbeanServer" />
    <property name="objectName" value="connector:name=rmi" />
    <property name="serviceUrl" value="service:jmx:rmi://a.b.c.d:1100/jndi/rmi://a.b.c.d:1100/server" />
    <property name="environment">
        <props>
            <prop key="jmx.remote.jndi.rebind">true</prop>
        </props>
    </property>
</bean>
<bean id="mbeanServer" class="org.springframework.jmx.support.MBeanServerfactorybean">
    <!-- indicate to first look for a server -->
    <property name="locateExistingServerIfPossible" value="true"/>
</bean>

Note: I don't use any servlet containers

Editor: the first answer provides me with the basis to solve my specific problem, which can be seen in the second answer

Solution

Use COM sun. management. jmxremote. The initial port defined by port is called registry port and is only used to start negotiation and determine the next port for "real" communication Java RMI mechanism uses dynamically allocated ports, which is usually incompatible with firewalls

What port is used by Java RMI connection?

In other words, for JMX, it can be solved

a) Lock both ports using system properties (Java 7 required)

com.sun.management.jmxremote.port
com.sun.management.jmxremote.rmi.port

b) Use custom code to request a specific port See jconsole over SSH local port forwarding

You can also see:

> Why Java opens 3 ports when JMX is configured? > http://realjenius.com/2012/11/21/java7-jmx-tunneling-freedom/

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>