67

I have my local.machine, the proxy.machine and target.machine. local.machine doesn't have direct contact with target.machine, but needs to go through proxy.machine.

I want to scp a file from target.machine to local.machine. Is this possible to do with just one command from local.machine?

13 Answers 13

75

You can do this with ProxyJump. put this in your ~/.ssh/config file (creating the file if it does not exist):

Host target.machine
User targetuser
HostName target.machine
ProxyJump [email protected]

After saving the file, you can just use

ssh target.machine

any time you want to connect. Scp also will work as it also respects the ssh config file. So will Nautilus, if you're using GNOME and want to use a GUI.

Old Answer (for older versions of OpenSSH)

Host target.machine
User targetuser
HostName target.machine
ProxyCommand ssh [email protected] nc %h %p 2> /dev/null
4
  • 6
    Just a quick note. If you are using an alternative identity file via the -i command line option for ssh, you need to specify that option for both the ProxyCommand configuration and the ssh command line.
    – BillMan
    May 15, 2013 at 18:32
  • 7
    3 things that might help, 1) it would help if you also showed the Host proxy.machine lines in the same ~/.ssh/config file, 2) Mention whether these commands can be nested (ie. client connects to proxy host 1 which connects to proxy host 2 which connects to...target) and 3) what nc %h %p means
    – puk
    Nov 14, 2013 at 6:00
  • How can we copy from local machine to target machine with proxy?
    – Mulagala
    Nov 16, 2017 at 11:34
  • 1
    Newer versions of OpenSSH have acquired the ProxyJump option for specifying the [email protected]. Apr 14, 2020 at 10:14
34

You can now* do this as a one-liner, without requiring nc anywhere:

scp -o "ProxyCommand ssh [email protected] -W %h:%p" [email protected]:file .

Explanation

pcreds and tcreds represent your proxy and target credentials if required (username, username:password, etc.).

This is possible because of a built-in netcat-like ability, removing the requirement for nc on the intermediate host. Using ssh -W host:port sets up a tunnel to the specified host and port and connects it to stdin/stdout, and then scp runs over the tunnel.

The %h and %p in the ProxyCommand are replaced with the target host and port from the outer scp command, to save you having to repeat them.

For even more convenience, you can configure the proxy in your ssh configuration:

Host target.machine
    ProxyCommand ssh [email protected] -W %h:%p

and from then on just do

scp [email protected]:file .

* since OpenSSH 5.4 - released March 2010

4
  • 1
    Verified this indeed works well, and does not leave stale NC processes laying around on the proxy machine.
    – LaXDragon
    May 6, 2016 at 15:01
  • 1
    Where can I specify the port of the proxy ?
    – Marged
    Dec 7, 2017 at 18:01
  • 1
    @Marged I'm not in a position to try it here at the moment, but I think you should be able to include -p <portnum> before the -W in either method to specify the proxy port
    – CupawnTae
    Dec 10, 2017 at 21:04
  • 1
    It took me a while to figure out that the -i option (if you need it) goes inside the quotes. The proxy ssh does not by default use the same private key specified by any -i option supplied directly to scp. I guess that is obvious when you think about it.
    – Keeely
    Nov 24, 2018 at 21:30
22

If you don't mind using rsync instead of scp, you can use the following one-liner:

rsync -v --rsh "ssh proxy.machine ssh" target.machine:/remote/file /local/dir/

(you'll need passwordless access to the proxy machine)

22

You can do it in one command, but you need netcat (nc) installed on the proxy machine:

ssh -o "ProxyCommand ssh [email protected] nc -w 1 %h 22" [email protected]
2
  • Nice try, but where should I add the username for proxy and for login?
    – grm
    Apr 13, 2011 at 11:49
  • Jzst before the machine names, with an @. I edited my answer to reflect that. Apr 13, 2011 at 18:37
9
$ ssh -f -N -L <localport>:<target.machine:port> [email protected]
$ scp [email protected]:/remote/file -P <localport> .

OK, actually two commands...

2
  • 1
    How can I specify the port of my proxy ? In my case 8080
    – Marged
    Dec 7, 2017 at 18:00
  • @Marged add -p <portnumber> to your ssh command
    – weeheavy
    Jan 21, 2018 at 20:51
8

A one-liner? Not off the top of my head. You need to establish a proxy first and you can't do that with scp by itself.

When doing it manually, I open up a screen session for my tunnel:

screen -S tunnel

Screen is used to keep the tunnel going in a background shell. Use any technique you want to keep the tunnel open in the background (@weeheavy's answer is probably the simplest). Once in the screen session I start my tunnel like so

ssh -L 2222:target.machine:22 [user@]proxy.machine

To break that down, that basically says "On my local machine, open port 2222 and any connetion hitting localhost:2222 is proxied through proxy.machine to target.machine:22"

Once you've got the ssh connection and tunnel established, detach from the screen session with "C-a d". To get back to that screen session, type screen -raAd tunnel

Once you are back in your original shell your scp command will look like

scp -P 2222 localhost:your/file/on/target.machine local/path

Remember that localhost port 2222 is really just a tunnel going to target.machine.

4

Appears that scp supports the -o option just like ssh does, though I'm not sure how to pass it a proxy username/password:

scp -o "ProxyCommand=nc -X connect -x proxyhost:proxyport %h %p" remote_user@remote_host:remote_path local_path

If you get nc: invalid option -- X see my stackoverflow answer

1
2

How about:

scp -o "ProxyCommand ssh [email protected] nc %h %p" your.filename [email protected]:/whatever_location
1
  • or possibly username:password here?
    – rogerdpack
    Sep 11, 2015 at 19:44
1

You could try something like:

ssh [email protected] "ssh [email protected] 'cat > file'" < file

But it won't work if your proxy.machine needs to ask you password (that SSH is not in a TTY, so askpass will fail).

If you have more than one file, you could use tar like this (untested, I usually use a netcat that way):

tar cf - file1 file2 folder1/ | ssh [email protected] "ssh [email protected] 'tar xvf -'"
1

Another simple solution to transfer a source_file from the source_host to a destination_host via a proxy_host:

Log in on the proxy_server:

ssh login@proxy_host

From the proxy server, transfer the source_file from the source_host to the destination_host (you can type this as one line, omitting the \, or as two lines, as shown below):

scp login@source_host:/path_to_source_file \
  login@destination_host:/path_to_destination_directory

This requires that the login on the source_host to the proxy_host uses an rsa_key.

1

I followed this article and found an answer which works for me. (Because the answers above don't work for me).

How to scp a file through an intermediate host (a.k.a. jump host) http://mperdikeas.github.io/networking.html.files/scp-a-file-through-jump-host.html

And my answer is as below:

scp -oProxyCommand="ssh -W %h:%p {username}@{proxy_IP}" \
        {source_file} {remote_username}@{remote_IP}:{remote_file_path}

Example:

scp -oProxyCommand="ssh -W %h:%p [email protected]" \
        archive.gz [email protected]:/home/wise/archive.gz

I hope this answer could help you.

0

In case you need to use public keys you will need something like this.

Host target-machine
  User          target-user
  HostName      target.example.com
  IdentityFile  /path/to/file.pem
  ProxyCommand  ssh bastion -W %h:%p

Host bastion
  User         bastion-user
  HostName     bastion.example.com
  IdentityFile /path/to/file.pem
0

You can use ProxyJump on the command line as well:

scp -o "ProxyJump [email protected]" src dest

The sintax is the same as for scp, just add -o option with ProxyJump command. The same works for SSH as well.

NOTE: you need to have access without password to [email protected].

In order to achieve this use this command:

ssh-copy-id [email protected]

confirm, insert the password and the job is done.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .