scp with port number specified - port

I'm trying to scp a file from a remote server to my local machine. Only port 80 is accessible.
I tried:
scp -p 80 username#www.myserver.com:/root/file.txt .
but got this error: cp: 80: No such file or directory
How do I specify the port number in a scp command?

Unlike ssh, scp uses the uppercase P switch to set the port instead of the lowercase p:
scp -P 80 ... # Use port 80 to bypass the firewall, instead of the scp default
The lowercase p switch is used with scp for the preservation of times and modes.
Here is an excerpt from scp's man page with all of the details concerning the two switches, as well as an explanation of why uppercase P was chosen for scp:
-P port   Specifies the port to connect to on the remote host. Note that this option is written with a capital 'P', because -p is already
reserved for preserving the times and modes of the file in rcp(1).
-p           Preserves modification times, access times, and modes from the original file.
Bonus Tip: How can I determine the port being used by the/an SSH daemon to accept SSH connections?
This question can be answered by using the netstat utility, as follows:
sudo netstat -tnlp | grep sshd
Or, using the far more readable word based netstat option names:
sudo netstat --tcp --numeric-ports --listening --program | grep sshd
The output you will see, assuming your ssh daemon is configured with default values its listening ports, is shown below (with a little trimming of the whitespace in between columns, in order to get the entire table to be visible without having to scroll):
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State ID/Program name
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 888/sshd: /usr/sbin
tcp6 0 0 :::22 :::* LISTEN 888/sshd: /usr/sbin
Important Note
For the above examples, sudo was used to run netstat with administrator privs, in order to be able to see all of the Program Names. If you run netstat as a regular user (i.e., without sudo and assuming you don't have admin rights granted to you, via some other method), you will only see program names shown for sockets that have your UID as the owner. The Program Names for sockets belonging to other users will not be shown (i.e., will be hidden and a placeholder hyphen will be displayed, instead):
Proto Recv-Q Send-Q Local Address Foreign Address State ID/Program name
tcp 0 0 127.0.0.1:46371 0.0.0.0:* LISTEN 4489/code
...
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN -
...
Update and aside to address one of the (heavily upvoted) comments:
With regard to Abdull's comment about scp option order, what he suggests:
scp -r some_directory -P 80 ...
..., intersperses options and parameters, since the -r switch takes no additional arguments and some_directory is treated as the first parameter to the command, making -P and all subsequent command line arguments look like additional parameters to the command (i.e., hyphen prefixed arguments are no longer considered as switches).
getopt(1) clearly defines that parameters must come after options (i.e., switches) and not be interspersed with them, willy-nilly:
The parameters getopt is called with can be divided into two parts: options which modify the way getopt will do the parsing (the options and the optstring in the SYNOPSIS), and the parameters which are to be parsed (parameters in the SYNOPSIS). The second part will start at
the first non-option parameter that is not an option argument, or after the first occurrence of '--'. If no '-o' or '--options' option is found in the first part, the first parameter of the second part is used as the short options string.
Since the -r command line option takes no further arguments, some_directory is "the first non-option parameter that is not an option argument." Therefore, as clearly spelled out in the getopt(1) man page, all succeeding command line arguments that follow it (i.e., -P 80 ...) are assumed to be non-options (and non-option arguments).
So, in effect, this is how getopt(1) sees the example presented with the end of the options and the beginning of the parameters demarcated by gray text:
scp -r some_directory -P 80 ...
This has nothing to do with scp behavior and everything to do with how POSIX standard applications parse command line options using the getopt(3) set of C functions.
For more details with regard to command line ordering and processing, please read the getopt(1) manpage using:
man 1 getopt

One additional hint. Place the '-P' option after the scp command, no matter whether the machine you are ssh-ing into is the second one (aka destination). Example:
scp -P 2222 /absolute_path/source-folder/some-file user#example.com:/absolute_path/destination-folder

You know what's cooler than -P? nothing
If you use this server more than a few times, setup/create a ~/.ssh/config file with an entry like:
Host www.myserver.com
Port 80
or
Host myserver myserver80 short any.name.u.want yes_anything well-within-reason
HostName www.myserver.com
Port 80
User username
Then you can use:
scp username#www.myserver.com:/root/file.txt .
or
scp short:/root/file.txt .
You can use anything on the "Host" line with ssh, scp, rsync, git & more
There are MANY configuration option that you can use in config files, see:
man ssh_config

I'm using different ports then standard and copy files between files like this:
scp -P 1234 user#[ip address or host name]:/var/www/mywebsite/dumps/* /var/www/myNewPathOnCurrentLocalMachine
This is only for occasional use, if it repeats itself based on a schedule you should use rsync and cron job to do it.

for use another port on scp command use capital P like this
scp -P port-number source-file/directory user#domain:/destination
ya ali

This can be achived by specifying port via the -P switch:
scp -i ~/keys/yourkey -P2222 file ubuntu#host:/directory/

Port can be specified using the scp protocol path: scp://[user#]host[:port][/path]
From man scp:
The source and target may be specified as a local pathname, a remote host with optional path in the form [user#]host:[path], or a URI in the form
scp://[user#]host[:port][/path]. Local file names can be made explicit using absolute or relative pathnames to avoid scp treating file names containing `:'
as host specifiers.
Examples:
scp local/filename scp://user#acme.com:22222/path/to/filename
scp scp://userA#foo.com:22222/path/to/filename scp://userB#bar.com:33333/path/to/filename
Note, if your path is from root, you will need to have two /s in your path. For example,
scp local/filename scp://user#acme.com:22222//root/path/to/filename

scp help tells us that port is specified by uppercase P.
~$ scp
usage: scp [-12346BCpqrv] [-c cipher] [-F ssh_config] [-i identity_file]
[-l limit] [-o ssh_option] [-P port] [-S program]
[[user#]host1:]file1 ... [[user#]host2:]file2
Hope this helps.

scp -P 22 -r DIR huezo#192.168.1.100:/home/huezo
scp -P PORT -r DIR USER#IP:/DIR

if you need copy local file to server (specify port )
scp -P 3838 /the/source/file username#server.com:/destination/file

To backup all files in all directories to a remote Synology NAS using a different remote port:
scp -P 10022 -r /media/data/somedata/* user#192.168.1.x:/var/services/homes/user/directory/

Copying file to host:
scp SourceFile remoteuser#remotehost:/directory/TargetFile
Copying file from host:
scp user#host:/directory/SourceFile TargetFile
Copying directory recursively from host:
scp -r user#host:/directory/SourceFolder TargetFolder
NOTE: If the host is using a port other than port 22, you can specify it with the -P option:
scp -P 2222 user#host:/directory/SourceFile TargetFile

Hope this will help someone looking for a perfect answer
Copying a folder or file from a server with a port defined to another server or local machine
Go to a directory where you have admin rights preferably your home directory on the machine where you want to copy files to
Write the command below
scp -r -P port user#IP_address:/home/file/pathDirectory .
**Note:** The last . on the command directs it to copy everything in that folder to your directory of preference

There are many answers, but you should just be able to keep it simple. Make sure you know what port SSH is listening on, and define it. Here is what I just used to replicate your problem.
scp -P 12222 file.7z user#193.168.X.X:/home/user/Downloads
It worked out well.

Related

Jenkins server --httpListenAddress=127.0.0.1 not working

recently I installed Jenkins server, and wanted to hide it behind Nginx proxy.
My Nginx proxy works fine and I read to restrict Jenkins to 127.0.0.1:8080 therefore, I edited the config file /etc/default/jenkins and put below line of code:
JENKINS_ARGS="--webroot=/var/cache/$NAME/war --httpPort=8080 --httpListenAddress=127.0.0.1"
After restarting jenkins, I still have access to Jenkins on port 8080
Environment:
Ubuntu 20.04
OpenJDK 11
Jenkins 2.332.1
Netstat output:
sudo netstat -plnt
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN 2313/java
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 970/nginx: master p
tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN 708/systemd-resolve
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 946/sshd: /usr/sbin
tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN 757/cupsd
tcp6 0 0 :::80 :::* LISTEN 970/nginx: master p
tcp6 0 0 :::22 :::* LISTEN 946/sshd: /usr/sbin
tcp6 0 0 ::1:631 :::* LISTEN 757/cupsd
P.S. I tried on EC2/Amazom linux 2, same issue
As of Jenkins version 2.332.1, which you indicated you are running, Jenkins made the switch from running as a service using classic SysV init scripts over to fully integrating with systemd on Linux distributions that support it, which includes Ubuntu 20.04. I don't see any signs that the systemd unit file for Jenkins ever parses /etc/default/jenkins, meaning those settings are only parsed by the SysV init script, which would explain why your configuration had no effect there.
As you found, setting the environment variable in /lib/systemd/system/jenkins.service indeed works, but your instinct is absolutely correct that it is not best practice to directly edit the unit file managed by the packaging system. As with most things in Linux, the /etc directory is where administrators are meant to put their configuration files, and /lib and /usr/lib are reserved for the package manager, so luckily systemd is no exception to this and provides a mechanism for such changes.
Systemd has the concept of "drop-in" directories where you can place ".conf" files with partial systemd unit configurations whose directives will override those in the main unit file. From the systemd.unit man page:
Along with a unit file foo.service, a "drop-in" directory foo.service.d/ may exist. All files with the suffix ".conf" from this directory will be merged in the alphanumeric order and parsed after the main unit file itself has been parsed. This is useful to alter or add configuration settings for a unit, without having to modify unit files. Each drop-in file must contain appropriate section headers.
Here's how I set up Jenkins 2.332.1 on Ubuntu 20.04 using a systemd drop-in override to bind the listener to 127.0.0.1:
Verify Jenkins is running and listening on all addresses/interfaces:
$ sudo ss -tlnp | grep 8080
LISTEN 0 50 *:8080 *:* users:(("java",pid=2688,fd=116))
Create a systemd drop-in directory for Jenkins:
$ sudo mkdir /etc/systemd/system/jenkins.service.d
Create an override file using your favorite editor. You can name it whatever you want as long as it has a .conf extension. Personally, I prefer something descriptive and to begin with a number so that I can control the lexicographic order in which the files are parsed, should I ever end up with multiple override files. Given that, I created a file /etc/systemd/system/jenkins.service.d/50-listen-address-override.conf with the following content:
[Service]
Environment="JENKINS_LISTEN_ADDRESS=127.0.0.1"
Now, all we have to do is tell systemd that we made some changes we want it to reparse:
$ sudo systemctl daemon-reload
And we can restart Jenkins to give it its new config:
$ sudo systemctl restart jenkins
If we verify our work, we can now see that Jenkins is only bound to 127.0.0.1:
$ sudo ss -tlnp | grep 8080
LISTEN 0 50 [::ffff:127.0.0.1]:8080 *:* users:(("java",pid=31636,fd=116))
For what it's worth, you can also use the command systemctl edit jenkins to create the override, and systemd will create the drop-in directory and override file automatically for you and drop you into your default editor to write the file contents, however it does not give you the freedom to choose your own name for the override file, giving it instead a generic name of override.conf.
While it won't hurt to restrict port 8080 in an AWS environment there really isn't a reason to worry about it. You'll want to setup a security group to your server so everything is blocked except for maybe port 22 (ssh), port 80 (http) and port 443 (https). You can do this through the AWS console.
To do this, go to the AWS console and select EC2 and then your instance. In the middle of the page is the "Security" tab. From there you can create a security group to determine what traffic you allow in and out.
In this way no one can connect to any ports that you don't allow in. You're not currently using https it looks like and so you may want to leave out port 443 until you're ready.

TPROXY compatibility with Docker

I'm trying to understand how TPROXY works in an effort to build a transparent proxy for Docker containers.
After lots of research I managed to create a network namespace, inject an veth interface into it and add TPROXY rules. The following script worked on a clean Ubuntu 18.04.3:
ip netns add ns0
ip link add br1 type bridge
ip link add veth0 type veth peer name veth1
ip link set veth0 master br1
ip link set veth1 netns ns0
ip addr add 192.168.3.1/24 dev br1
ip link set br1 up
ip link set veth0 up
ip netns exec ns0 ip addr add 192.168.3.2/24 dev veth1
ip netns exec ns0 ip link set veth1 up
ip netns exec ns0 ip route add default via 192.168.3.1
iptables -t mangle -A PREROUTING -i br1 -p tcp -j TPROXY --on-ip 127.0.0.1 --on-port 1234 --tproxy-mark 0x1/0x1
ip rule add fwmark 0x1 tab 30
ip route add local default dev lo tab 30
After that I launched a toy Python server from Cloudflare blog:
import socket
IP_TRANSPARENT = 19
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.setsockopt(socket.IPPROTO_IP, IP_TRANSPARENT, 1)
s.bind(('127.0.0.1', 1234))
s.listen(32)
print("[+] Bound to tcp://127.0.0.1:1234")
while True:
c, (r_ip, r_port) = s.accept()
l_ip, l_port = c.getsockname()
print("[ ] Connection from tcp://%s:%d to tcp://%s:%d" % (r_ip, r_port, l_ip, l_port))
c.send(b"hello world\n")
c.close()
And finally by running ip netns exec ns0 curl 1.2.4.8 I was able to observe a connection from 192.168.3.2 to 1.2.4.8 and receive the "hello world" message.
The problem is that it seems to have compatibility issues with Docker. All worked well in a clean environment, but once I start Docker things start to go wrong. It seems like the TPROXY rule was no longer working. Running ip netns exec ns0 curl 192.168.3.1 gave "Connection reset" and running ip netns exec ns0 curl 1.2.4.8 timed out (both should have produced the "hello world" message). I tried restoring all iptables rules, deleting ip routes and rules generated by Docker and shutting down Docker, but none worked even if I didn't configure any networks or containers.
What is happening behind the scenes and how can I get TPROXY working normally?
I traced all processes created by Docker using strace -f dockerd, and looked for lines containing exec. Most commands are iptables commands, which I have already excluded, and the lines with modprobe looked interesting. I loaded these modules one by one and figured out that the module causing the trouble is br_netfilter.
The module enables filtering of bridged packets through iptables, ip6tables and arptables. The iptables part can be disabled by executing echo "0" | sudo tee /proc/sys/net/bridge/bridge-nf-call-iptables. After executing the command, the script worked again without impacting Docker containers.
I am still confused though. I haven't understood the consequences of such a setting. I enabled packet tracing, but it seems that the packets matched the exact same set of rules before and after enabling bridge-nf-call-iptables, but in the former case the first TCP SYN packet got delivered to the Python server, in the latter case the packet got dropped for unknown reasons.
Try running docker with -p 1234
"By default, when you create a container, it does not publish any of its ports to the outside world. To make a port available to services outside of Docker, or to Docker containers which are not connected to the container’s network, use the --publish or -p flag."
https://docs.docker.com/config/containers/container-networking/

restrict SSH connection to specific URL/domain name

I have a server with 2 domain names (let's say domain1.com and domain2.com).
I can SSH into the server by ssh user#domain1.com and ssh user#domain2.com. I would like to be able to only allow ssh user#domain1.com and disable SSH acces to domain2.com.
Is that possible?
It does not seem possible to allow SSH connection only to specific domain name. The domain name is resolved by the DNS and there is no way for the SSH server to know which domain you are using. See also this answer to the same question.
One thing you might try to do is to configure a firewall (for example iptable) to drop connection to domain2.com on port 22.
A similar problem was discussed here, where they were trying to block a domain in iptables so that visitor could not access the http server using it.
Adjusting the iptables rule to your case ( and assuming that your ssh server is running on port 22) I would try this:
iptables -I INPUT -p tcp --dport 22 -m string --string "Host: domain2.com" --algo bm -j DROP
UPDATE:
As Dusan Bajic commented the rule above would only work for http traffic because it take advantage of the http header fields. This would not work for ssh traffic.

How to change Freeradius3 default port(auth1812 & Account1813)

I am using freeradius3.0.4. I need to change the default port(1812,1813) to 18120 and 18130. I don't know where it is. Please help! there is no port setting in the main conf.
Change the port under /etc/service.
This is what I get on freeRADIUS Version 3.0.16:
$ sudo freeradius -X -i 0.0.0.0 -p 1850
radiusd: #### Opening IP addresses and Ports ####
Listening on auth address * port 1850
Listening on acct address * port 1851
Listening on proxy address * port 56033
Ready to process requests
From man freeradius:
-p port
Defines which port is used for receiving authentication packets. Accounting packets are received on "port + 1".
When this command-line option is given, all "listen" sections in radiusd.conf are ignored.
This option MUST be used in conjunction with "-i".
So if you'd like to make the changes permanent, it seems that you need to add a "listen" section to your configuration file with the appropriate parameters (didn't have time to look up the exact syntax).
Also note the constraint that the accounting port is always going to be the authentication port plus one. If you really must modify this behavior on freeRADIUS you might have to change the source code and build your own version.
The port number is defined in /etc/freeradius/3.0/sites-enabled/default:
server default {
listen {
type = auth
ipaddr = *
port = 0
limit {
max_connections = 16
lifetime = 0
idle_timeout = 30
}
}
listen {
ipaddr = *
port = 0
type = acct
limit {
}
}
... more configuration
}
As you can see the configured port is 0. This just means it'll use the FreeRADIUS default port which is 1812/1813 (auth/acct).
If you want to change these port numbers, change them in the above file and run systemctl restart freeradius
If you want to run 2 RADIUS sessions in parallel you'd have to cp -rp /etc/freeradius /etc/freeradius2 and start a second RADIUS process with freeradius -X -d /etc/freeradius2
Hope I could help, I also had this issue
Edits:
0 means that it will use the port defined in /etc/services (by default is 1812)
Instead of freeradius -X -c ... use freeradius -X -d ... to use a custom directory
Use cp -rp ... because otherwise the permissions would change and FreeRADIUS wouldn't work anymore

Has anyone ever got a remote JMX JConsole to work?

It seems that I've never got this to work in the past. Currently, I KNOW it doesn't work.
But we start up our Java process:
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=6002
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
I can telnet to the port, and "something is there" (that is, if I don't start the process, nothing answers, but if I do, it does), but I can not get JConsole to work filling in the IP and port.
Seems like it should be so simple, but no errors, no noise, no nothing. Just doesn't work.
Anyone know the hot tip for this?
I have a solution for this:
If your Java process is running on Linux behind a firewall and you want to start JConsole / Java VisualVM / Java Mission Control on Windows on your local machine to connect it to the JMX Port of your Java process.
You need access to your linux machine via SSH login. All Communication will be tunneled over the SSH connection.
TIP: This Solution works no matter if there is a firewall or not.
Disadvantage: Everytime you restart your java process, you will need to do all steps from 4 - 9 again.
1. You need the putty-suite for your Windows machine from here:
http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html
At least the putty.exe
2. Define one free Port on your linux machine:
<jmx-remote-port>
Example:
jmx-remote-port = 15666
3. Add arguments to java process on the linux machine
This must be done exactly like this. If its done like below, it works for linux Machines behind firewalls (It works cause of the -Djava.rmi.server.hostname=localhost argument).
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=<jmx-remote-port>
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.local.only=false
-Djava.rmi.server.hostname=localhost
Example:
java -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=15666 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.local.only=false -Djava.rmi.server.hostname=localhost ch.sushicutta.jmxremote.Main
4. Get Process-Id of your Java Process
ps -ef | grep <java-processname>
result ---> <process-id>
Example:
ps -ef | grep ch.sushicutta.jmxremote.Main
result ---> 24321
5. Find arbitrary Port for RMIServer stubs download
The java process opens a new TCP Port on the linux machine, where the RMI Server-Stubs will be available for download. This port also needs to be available via SSH Tunnel to get a connection to the Java Virtual Machine.
With netstat -lp this port can be found also the lsof -i gives hints what port has been opened form the java process.
NOTE: This port always changes when java process is started.
netstat -lp | grep <process-id>
tcp 0 0 *:<jmx-remote-port> *:* LISTEN 24321/java
tcp 0 0 *:<rmi-server-port> *:* LISTEN 24321/java
result ---> <rmi-server-port>
Example:
netstat -lp | grep 24321
tcp 0 0 *:15666 *:* LISTEN 24321/java
tcp 0 0 *:37123 *:* LISTEN 24321/java
result ---> 37123
6. Enable two SSH-Tunnels from your Windows machine with putty
Source port: <jmx-remote-port>
Destination: localhost:<jmx-remote-port>
[x] Local
[x] Auto
Source port: <rmi-server-port>
Destination: localhost:<rmi-server-port>
[x] Local
[x] Auto
Example:
Source port: 15666
Destination: localhost:15666
[x] Local
[x] Auto
Source port: 37123
Destination: localhost:37123
[x] Local
[x] Auto
7. Login to your Linux machine with Putty with this SSH-Tunnel enabled.
Leave the putty session open.
When you are logged in, Putty will tunnel all TCP-Connections to the linux machine over the SSH port 22.
JMX-Port:
Windows machine: localhost:15666 >>> SSH >>> linux machine: localhost:15666
RMIServer-Stub-Port:
Windows Machine: localhost:37123 >>> SSH >>> linux machine: localhost:37123
8. Start JConsole / Java VisualVM / Java Mission Control to connect to your Java Process using the following URL
This works, cause JConsole / Java VisualVM / Java Mission Control thinks you connect to a Port on your local Windows machine. but Putty send all payload to the port 15666 to your linux machine.
On the linux machine first the java process gives answer and send back the RMIServer Port. In this example 37123.
Then JConsole / Java VisualVM / Java Mission Control thinks it connects to localhost:37123 and putty will send the whole payload forward to the linux machine
The java Process answers and the connection is open.
[x] Remote Process:
service:jmx:rmi:///jndi/rmi://localhost:<jndi-remote-port>/jmxrmi
Example:
[x] Remote Process:
service:jmx:rmi:///jndi/rmi://localhost:15666/jmxrmi
9. ENJOY #8-]
Adding -Djava.rmi.server.hostname='<host ip>' resolved this problem for me.
Tried with Java 8 and newer versions
This solution works well also with firewalls
1. Add this to your java startup script on remote-host:
-Dcom.sun.management.jmxremote.port=1616
-Dcom.sun.management.jmxremote.rmi.port=1616
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.local.only=false
-Djava.rmi.server.hostname=localhost
2. Execute this on your computer.
Windows users:
putty.exe -ssh user#remote-host -L 1616:remote-host:1616
Linux and Mac Users:
ssh user#remote-host -L 1616:remote-host:1616
3. Start jconsole on your computer
jconsole localhost:1616
4. Have fun!
P.S.: during step 2, using ssh and -L you specify that the port 1616 on the local (client) host must be forwarded to the remote side. This is an ssh tunnel and helps to avoids firewalls or various networks problems.
After putting my Google-fu to the test for the last couple of days, I was finally able to get this to work after compiling answers from Stack Overflow and this page http://help.boomi.com/atomsphere/GUID-F787998C-53C8-4662-AA06-8B1D32F9D55B.html.
Reposting from the Dell Boomi page:
To Enable Remote JMX on an Atom
If you want to monitor the status of an Atom, you need to turn on Remote JMX (Java Management Extensions) for the Atom.
Use a text editor to open the <atom_installation_directory>\bin\atom.vmoptions file.
Add the following lines to the file:
-Dcom.sun.management.jmxremote.port=5002
-Dcom.sun.management.jmxremote.rmi.port=5002
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
The one line that I haven't seen any Stack Overflow answer cover is
-Dcom.sun.management.jmxremote.rmi.port=5002
In my case, I was attempting to retrieve Kafka metrics, so I simply changed the above option to match the -Dcom.sun.management.jmxremote.port value. So, without authentication of any kind, the bare minimum config should look like this:
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.port=(jmx remote port)
-Dcom.sun.management.jmxremote.local.only=false
-Dcom.sun.management.jmxremote.rmi.port=(jmx remote port)
-Djava.rmi.server.hostname=(CNAME|IP Address)
You are probably experiencing an issue with a firewall. The 'problem' is that the port you specify is not the only port used, it uses 1 or maybe even 2 more ports for RMI, and those are probably blocked by a firewall.
One of the extra ports will not be know up front if you use the default RMI configuration, so you have to open up a big range of ports - which might not amuse the server administrator.
There is a solution that does not require opening up a lot of ports however, I've gotten it to work using the combined source snippets and tips from
http://forums.sun.com/thread.jspa?threadID=5267091 - link doesn't work anymore
http://blogs.oracle.com/jmxetc/entry/connecting_through_firewall_using_jmx
http://java.sun.com/javase/6/docs/technotes/guides/management/agent.html
It's even possible to setup an ssh tunnel and still get it to work :-)
Are you running on Linux? Perhaps the management agent is binding to localhost:
http://java.sun.com/j2se/1.5.0/docs/guide/management/faq.html#linux1
Sushicutta's steps 4-7 can be skipped by adding the following line to step 3:
-Dcom.sun.management.jmxremote.rmi.port=<same port as jmx-remote-port>
e.g.
Add to start up parameters:
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=12345
-Dcom.sun.management.jmxremote.rmi.port=12345
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.local.only=false
-Djava.rmi.server.hostname=localhost
For the port forwarding, connect using:
ssh -L 12345:localhost:12345 <username>#<host>
if your host is a stepping stone, simply chain the port forward by running the following on the step stone after the above:
ssh -L 12345:localhost:12345 <username>#<host2>
Mind that the hostname=localhost is needed to make sure the jmxremote is telling the rmi connection to use the tunnel. Otherwise it might try to connect directy and hit the firewall.
PROTIP:
The RMI port are opened at arbitrary portnr's. If you have a firewall and don't want to open ports 1024-65535 (or use vpn) then you need to do the following.
You need to fix (as in having a known number) the RMI Registry and JMX/RMI Server ports. You do this by putting a jar-file (catalina-jmx-remote.jar it's in the extra's) in the lib-dir and configuring a special listener under server:
<Listener className="org.apache.catalina.mbeans.JmxRemoteLifecycleListener"
rmiRegistryPortPlatform="10001" rmiServerPortPlatform="10002" />
(And ofcourse the usual flags for activating JMX
-Dcom.sun.management.jmxremote \
-Dcom.sun.management.jmxremote.ssl=false \
-Dcom.sun.management.jmxremote.authenticate=false \
-Djava.rmi.server.hostname=<HOSTNAME> \
See: JMX Remote Lifecycle Listener at http://tomcat.apache.org/tomcat-6.0-doc/config/listeners.html
Then you can connect using this horrific URL:
service:jmx:rmi://<hostname>:10002/jndi/rmi://<hostname>:10001/jmxrmi
Check if your server is behind the firewall. JMX is base on RMI, which open two port when it start. One is the register port, default is 1099, and can be specified by the com.sun.management.jmxremote.port option. The other is for data communication, and is random, which is what cause problem. A good news is that, from JDK6, this random port can be specified by the com.sun.management.jmxremote.rmi.port option.
export CATALINA_OPTS="-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=8991 -Dcom.sun.management.jmxremote.rmi.port=8991 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false"
Getting JMX through the Firewall is really hard. The Problem is that standard RMI uses a second random assigned port (beside the RMI registry).
We have three solution that work, but every case needs a different one:
JMX over SSH Tunnel with Socks proxy, uses standard RMI with SSH magic
http://simplygenius.com/2010/08/jconsole-via-socks-ssh-tunnel.html
JMX MP (alternative to standard RMI), uses only one fixed port, but needs a special jar on server and client
http://meteatamel.wordpress.com/2012/02/13/jmx-rmi-vs-jmxmp/
Start JMX Server form code, there it is possible to use standard RMI and use a fixed second port:
https://issues.apache.org/bugzilla/show_bug.cgi?id=39055
When testing/debugging/diagnosing remote JMX problems, first always try to connect on the same host that contains the MBeanServer (i.e. localhost), to rule out network and other non-JMX specific problems.
There are already some great answers here, but, there is a slightly simpler approach that I think it is worth sharing.
sushicutta's approach is good, but is very manual as you have to get the RMI Port every time. Thankfully, we can work around that by using a SOCKS proxy rather than explicitly opening the port tunnels. The downside of this approach is JMX app you run on your machine needs to be able to be configured to use a Proxy. Most processes you can do this from adding java properties, but, some apps don't support this.
Steps:
Add the JMX options to the startup script for your remote Java service:
-Dcom.sun.management.jmxremote=true
-Dcom.sun.management.jmxremote.port=8090
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false
Set up a SOCKS proxy connection to your remote machine:
ssh -D 9696 user#remotemachine.com
Configure your local Java monitoring app to use the SOCKS proxy (localhost:9696). Note: You can sometimes do this from the command line, i.e.:
jconsole -J-DsocksProxyHost=localhost -J-DsocksProxyPort=9696
The following worked for me (though I think port 2101 did not really contribute to this):
-Dcom.sun.management.jmxremote.port=2100
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.local.only=false
-Dcom.sun.management.jmxremote.rmi.port=2101
-Djava.rmi.server.hostname=<IP_ADDRESS>OR<HOSTNAME>
I am connecting from a remote machine to a server which has Docker running and the process is inside the container. Also, I stopped firewallD but I don't think that was the issue as I could telnet to 2100 even with the firewall open.
Hope it helps.
I am running JConsole/JVisualVm on windows hooking to tomcat running Linux Redhat ES3.
Disabling packet filtering using the following command did the trick for me:
/usr/sbin/iptables -I INPUT -s jconsole-host -p tcp --destination-port jmxremote-port -j ACCEPT
where jconsole-host is either the hostname or the host address on which JConsole runs on and jmxremote-port is the port number set for com.sun.management.jmxremote.port for remote management.
I'm using boot2docker to run docker containers with Tomcat inside and I've got the same problem, the solution was to:
Add -Djava.rmi.server.hostname=192.168.59.103
Use the same JMX port in host and docker container, for instance: docker run ... -p 9999:9999 .... Using different ports does not work.
You need to also make sure that your machine name resolves to the IP that JMX is binding to; NOT localhost nor 127.0.0.1. For me, it has helped to put an entry into hosts that explicitly defines this.
Getting JMX through the firewall isn't that hard at all. There is one small catch. You have to forward both your JMX configured port ie. 9010 and one of dynamic ports its listens to on my machine it was > 30000
These are the steps that worked for me (debian behind firewall on the server side, reached over VPN from my local Mac):
check server ip
hostname -i
use JVM params:
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=[jmx port]
-Dcom.sun.management.jmxremote.local.only=false
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
-Djava.rmi.server.hostname=[server ip from step 1]
run application
find pid of the running java process
check all ports used by JMX/RMI
netstat -lp | grep [pid from step 4]
open all ports from step 5 on the firewall
Voila.
In order to make a contribution, this is what I did on CentOS 6.4 for Tomcat 6.
Shutdown iptables service
service iptables stop
Add the following line to tomcat6.conf
CATALINA_OPTS="${CATALINA_OPTS} -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=8085 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Djava.rmi.server.hostname=[host_ip]"
This way I was able to connect from another PC using JConsole.
I'm trying to JMC to run the Flight Recorder (JFR) to profile NiFi on a remote server that doesn't offer a graphical environment on which to run JMC.
Based on the other answers given here, and upon much trial and error, here is what I'm supplying to the JVM (conf/bootstrap.conf)when I launch NiFi:
java.arg.90=-Dcom.sun.management.jmxremote=true
java.arg.91=-Dcom.sun.management.jmxremote.port=9098
java.arg.92=-Dcom.sun.management.jmxremote.rmi.port=9098
java.arg.93=-Dcom.sun.management.jmxremote.authenticate=false
java.arg.94=-Dcom.sun.management.jmxremote.ssl=false
java.arg.95=-Dcom.sun.management.jmxremote.local.only=false
java.arg.96=-Djava.rmi.server.hostname=10.10.10.92 (the IP address of my server running NiFi)
I did put this in /etc/hosts, though I doubt it's needed:
10.10.10.92 localhost
Then, upon launching JMC, I create a remote connection with these properties:
Host: 10.10.10.92
Port: 9098
User: (nothing)
Password: (ibid)
Incidentally, if I click the Custom JMX service URL, I see:
service:jmx:rmi:///jndi/rmi://10.10.10.92:9098/jmxrmi
This finally did it for me.

Resources