I'm trying to connect to a jmx port remotely but I can't seem to connect to it even though the port is open. Its a java process running in a container on a server thats a Nomad worker. Its running on 29406
.
Here is what netstat
shows:
netstat -tulpn | grep 29406
(Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)
tcp 0 0 10.137.2.166:29406 0.0.0.0:* LISTEN -
udp 0 0 10.137.2.166:29406 0.0.0.0:* -
And this is whats in /etc/hosts
cat /etc/hosts
127.0.0.1 localhost
# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
ff02::3 ip6-allhosts
I've downloaded jmxterm
on the server to try and connect to it, and noticed an interesting behavior. When I try using localhost
to connect to the port, I get this:
#RuntimeIOException: Runtime IO exception: Failed to retrieve RMIServer stub: javax.naming.ServiceUnavailableException [Root exception is java.rmi.ConnectException: Connection refused to host: localhost; nested exception is:
java.net.ConnectException: Connection refused (Connection refused)]
When I use its own IP address, it then seems to work:
$>open 10.137.2.166:29406
#Connection to 10.137.2.166:29406 is opened
$>
Curious to understand why localhost doesn't work when I'm running this on the server itself...
The only way I've gotten jconsole
(running on my laptop) to connect to it is by using an ssh tunnel like this:
ssh -Nf -D 7777 10.137.2.166
jconsole -J-DsocksProxyHost=localhost -J-DsocksProxyPort=7777 service:jmx:rmi:///jndi/rmi://10.137.2.166:29406/jmxrmi -J-DsocksNonProxyHosts=
I feel like I should be able to connect to it without creating a tunnel but unsure why I can't. If I run telnet locally from my laptop to the host, the connection does seem to open...
telnet 10.137.2.166 29406
Trying 10.137.2.166...
Connected to 10.137.2.166.
Escape character is '^]'.
Remote JMX ConnectionsRight click anywhere in the blank area under the application tree and select Add JMX Connection. Provide the machine name and port number for a running JMX agent, that has been started with the appropriate system properties to allow remote management.
JMX Definition The Java Management Extensions (JMX) framework provides a configurable, scalable, and reliable infrastructure for managing Java applications. Furthermore, it defines a concept of MBean for real-time management of the application. The framework allows managing an application locally or remotely.
To connect JConsole to server process, in the Remote Process section, specify the URL service:jmx:rmi:///jndi/rmi://localhost:2047/fmq and credentials pertaining to the server. Default user name and password are admin and passwd respectively.
To open the JMX port on the remote JVM, you must enter the port number to use for the JMX RMI connection. Be sure to specify an unused port number. From a command line, go to the bin directory in the <JRE_HOME> directory that contains the Java Runtime Environment (JRE) implementation, for example jre/bin.
But for monitoring a remote process, you need to assign an RMI port number to your Java application. There is no default JMX port number due to security and other reasons.
The process of remote JMX connection is quite different from the local JMX connection. There are 4 ways in which you can do JConsole remote monitoring. SSL and authentication both disabled. SSL enabled and authentication disabled. Authentication enabled and SSL disabled. Both SSL and authentication enabled.
You have to define the JMX port number by setting the system property “com.sun.management.jmxremote.port”. Be careful not to assign TCP ports that are already in use. If you try to use a port that is already in use, your Java application will fail at startup and throw an ExportException.
Make sure to set the JMX_PORT with the standard port 7199 in your cassandra-env.sh and restart the node. It may be set in the jvm.options file in DSE, in which case, make sure to add -Dcassandra.jmx.local.port=7199 inside the jvm.options file.
To successful JMX handshake
the jmx server should be available by a host name outside (should also be declared on server jvm via java.rmi.server.hostname
system property)
in addition to one open port (can be explicitly declared via com.sun.management.jmxremote.rmi.port
jvm property) the jmx server chooses random another that's used for new jmx connection. It's quite problematic because you can't foresee particular port in order to exclude it from server's firewall restrictions, so the tunneling is necessary.
Server listened at only 10.137.2.166. When you trying to create new socket with localhost domain, your application tying to establish 127.0.0.1 adress but your application not listening at this ip.
If you want to connect with localhost domain you have few options for solving.
Change your server configuration to listen on 0.0.0.0 .
Listening at 0.0.0.0 its not recommended for security reasons .
Use iptables to forward port. Requires root privileges.
sysctl net.ipv4.ip_forward=1
iptables -t nat -A PREROUTING -p tcp -i lo --dport 29406 -j DNAT --to-destination 10.137.2.166:29406
iptables -A FORWARD -p tcp -d 10.137.2.166 --dport 29406 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
socat TCP-LISTEN:29406,fork,bind=127.0.0.1 TCP:10.137.2.166:29406
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With