3

I am typically logging in on a network via ssh and then to yet another computer again via ssh to my final destination computer. For instance a home server, and once there to one of my family's computers. That looks something like:

user0@inital:> ssh -P port_number user1@server
user1@server:> ssh -P port_number user2@final
user2@final:>

Once on user2@final I would like to copy (scp) back to user0@inital.

For instance I can do local port forwarding and copy form my local computer to the remote one over the server. On user0@initial

 user0@initial:> ssh -L4321:final:22 -p 443 user1@server

This forwards the local port 4321 form user0@initial via user1@server to port 22 on user2@final. Then on user0@initial by running

  scp -P 4321 some_file  [email protected]:~/

I can copy to user2@final over user1@server.

The question is how to reverse things and copy back from user2@final to user0@initial.

Thank you for your help.

2 Answers 2

1

Assuming you want to run the scp command at the command prompt of final:

# have the local client tell the remote server's sshd to listen on
# port 8765 (randomly chosen) and forward any connection it receives
# to the client which will connect to port 22 locally.
user0@initial:> ssh -R127.0.0.1:8765:127.0.0.1:22 -p 443 user1@intermediate

# On this machine have the client tell this remote server's (final's)
# to listen on port 9876 (randomly chosen) and forward any connection
# that it receives back to this client which will connect it to poirt
# 8765 locally.
user1@intermediate:> ssh -R127.0.0.1:9876:127.0.0.1:8765 user2@final

# Now that you are on the final server (final) you run scp, telling
# it to connect to localhost on port 9876.
# 
# So scp will connec to local (final's) port 9876, which is listened
# to by the local sshd based on our second command above.  That sshd
# will forward the connection to the ssh client that connected to it
# (on intermediate).
# 
# The ssh client on intermediate will connect to localhost:8765 as
# instructed which is a conenction to the sshd on intermediate that
# is listening on that port because it was instructed to do so by the
# ssh client on initial when it connected.
# 
# The sshd on intermediate will forward the conenction back to the
# client on initial which will, as instructed, connect to localhost:22
# on initial.
# 
# All this monkey motion means that now scp on final is "directly"
# connected to port 22 (sshd) on initial and can initiate a login
# and file transfer. to the ssh client that connected to it (on
# intermediate).
user2@final:> scp -P 9876 file_from_final 127.0.0.1:back_at_the_house

Note that I made the ports all on 127.0.0.1, which protects they from exploitation by others on the internet (but not from others on "server" or "final".

3
  • This works as a charm. Thank you so much. Actually you could simplify, say -R127.0.0.1:8765:127.0.0.1:22 becomes -R8765:127.0.0.1:22. What I don't understand is how exactly did you select the port numbers. For instance, when I do remote port forwarding I could choose something like -R12345:127.0.0.1 and this would work fine. Why the system allows me to open this port without sudo? For instance, to run netcat -l -p 12345 I always have to mess up with iptables and explicitly define 12345. Oct 1, 2015 at 15:31
  • 1
    If you lock them to 127.0.0.1 as I did, you should not have to deal with any iptables rules (almost eveyrone just trusts localhost to localhost traffic) Oct 16, 2015 at 16:45
  • 1
    I chose the port numbers essentially at random, assuming they would not already be in use. Oct 16, 2015 at 16:46
2

Yes. You will want to take a look at the ssh_config keyword ProxyCommand

Specifies the command to use to connect to the server. The command string extends to the end of the line, and is executed using the user's shell ‘exec’ directive to avoid a lingering shell process.

In the command string, any occurrence of ‘%h’ will be substituted by the host name to connect, ‘%p’ by the port, and ‘%r’ by the remote user name. The command can be basically anything, and should read from its standard input and write to its standard output. It should eventually connect an sshd(8) server running on some machine, or execute sshd -i somewhere. Host key management will be done using the HostName of the host being connected (defaulting to the name typed by the user). Setting the command to “none” disables this option entirely. Note that CheckHostIP is not available for connects with a proxy command.

This directive is useful in conjunction with nc(1) and its proxy support. For example, the following directive would connect via an HTTP proxy at 192.0.2.0:

ProxyCommand /usr/bin/nc -X connect -x 192.0.2.0:8080 %h %p
3
  • Here's an article explaining how to use ProxyCommand: sshmenu.sourceforge.net/articles/transparent-mulithop.html
    – adam
    Sep 30, 2015 at 17:11
  • I think that this can be done with port forwarding. I am able to copy form the local to the remote machine. Unfortunately, I don't know how to do things in reverse. Sep 30, 2015 at 22:25
  • Using a ProxyCommand (in you .ssh/config especially) will also do what I did above but you will need to understand how port tunneling works to come up with a good Proxy Command Oct 16, 2015 at 17:00

You must log in to answer this question.

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