Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

often I have to download a file that isn't directly accessable via the first SSH connection. For example I'm on a Windows machine and I want to access another machine that is only accessable from lan. That means that I must first connect to a intermediate machine and SSH to the next one.

It would be easy to use pscp to get the file, if it were available for the first machine. Could SSH port forwarding be used in this scenario?

share|improve this question
    
What exactly do you want to do? Just saying "reach them" leaves the obvious answer of ssh from one to the next. Do you want to SFTP instead? Do you want to setup a tunnel? Is it the ports that are blocked or the network that won't route or what are the connection limitations? (Please edit the question to clarify). –  Caleb May 11 '11 at 18:10
    
"I need to reach SERVER-A from the CLIENT with SCP." –  LanceBaynes May 11 '11 at 19:39
add comment

6 Answers

up vote 3 down vote accepted

Yes, SSH port forwarding can be used in this case, but you can also get warnings about invalid or incorrect host keys when attempting this. Some SSH clients like OpenSSH track SSH host keys by domain or IP only and don't include the port number with it. PuTTY appears to record the port number with the host key and should not suffer from this problem as long as your consistent with which port numbers you use for each host. I'd recommend adding the port forwardings to a saved session in PuTTY. You can then also save the additional sessions for the various remote hosts as saved sessions and use that with pscp/psftp. You can start with any high number port for the forwarding such as 2220 and go up by one from there for each host you need to forward through an intermediate host. Add to the saved session for intermediate local port forwards like port 2220 and destination remote1:22 and port 2221 with destination remote2:22 for remote hosts remote1 and remote2 Then create sessions for remote1 with destination localhost and SSH port 2220 and a session for remote2 with destination localhost and SSH port 2221. To use sessions with pcsp/psftp use @session-name for the host.

The problem occurs when either you have somehow associated a SSH host key with localhost and you attempt to connect to a local port that's being forwarded to a different computer. With OpenSSH, I fixed this problem by using HostKeyAlias. I added entries to my ~/.ssh/config like this:

Host intermediate
HostName intermediate.example.org
LocalForward 2220 remote1.example.org:22
LocalForward 2222 remote2.example.org:22

Host remote1
HostName localhost
Port 2220
HostKeyAlias remote1.example.org

Host remote2
HostName localhost
Port 2221
HostKeyAlias remote2.example.org

My preferred fix, though, was when I deployed IPv6 on my home and work network and I no longer had to worry about connecting to an intermediate server first to get to my final destination.

share|improve this answer
    
Thank you both, penguin359 and Gilles for the answers. I'll look into implementing them ASAP. –  Uku Loskit Apr 9 '11 at 10:11
add comment
ssh server1 'ssh server2'

seems a little bit simpler to me. One can even copy files like this:

ssh server1 "ssh server2 'cat myFile'" >myFile

or

ssh server1 "ssh server2 'cat >myFile'" <myFile
share|improve this answer
    
That doesn't work for me; I don't think ssh will redirect stdin to the child process, so ssh server1 just locks up waiting for ssh server2 to complete –  Michael Mrozek May 11 '11 at 19:46
    
+1 It works, but I did not get any prompt. –  Hai Vu May 11 '11 at 19:50
    
If you want prompt you should use such command ssh -t server1 'ssh server2'. But these is not the answer for question. It doesn't allow you to use scp command. –  Lukasz Stelmach May 11 '11 at 19:52
    
that is weird, I do this all the time and it works. Maybe it has something to do with password versus key authentication? –  Kim May 11 '11 at 20:14
    
@Kim I doubt. For me it also work to some moment. I suppose some default behaviour change after package upgrade. –  Lukasz Stelmach May 11 '11 at 20:44
show 1 more comment

I add to the .ssh/config such definition:

Host SERVER-A
    ProxyCommand ssh SERVER-B nc -q0 %h %p 2> /dev/null

and then just use ssh or scp in normal way:

ssh user@SERVER-A

or

scp file.tar.gz user@SERVER-A:~

During setting the connection with SERVER-A the ssh library finds these configuration. It tells that ssh should use some proxy command to connect. The proxy commands connect with SERVER-B and then execute nc command (netcat) wich forward all output from proxy command to given server for given port, its define by %h and %p parameters.

Such construction also allow you to use key authentication. you have just copy your public from client machine on both servers: SERVER-A and SERVER-B.

Such configuration is also compatible with others application which use ssh library, for example rsync, sftp or GUI clients.

share|improve this answer
    
but is it safe? –  LanceBaynes May 11 '11 at 22:45
    
@LanceBaynes Could you be more specific, please? If the connection is safe, authentication or maybe something else? –  Lukasz Stelmach May 12 '11 at 7:05
add comment

Following gelraen's answer.

You can use port forwarding pretty nicely when in conjunction with the .ssh/config. that is, you set a proxy command for a specific imaginary hostname which does nothing but tcp-forward through an already open tunnel:

Host imag
ProxyCommand socat - tcp-connect:localhost:2022

Then you can just use ssh imag to connect to server-b:22 when the tunnel is up.

socat is just what I used, netcat should do es well ;)

One nifty thing about ProxyCommand is that it interpolates environment variables - so... give it a try.

share|improve this answer
add comment

You can use SSH port forwarding:

ssh server-a -L2022:server-b:22

After this you will have port 2022 on client machine forwarded to port 22 of server-b. And you can connect to it with:

ssh 127.0.0.1 -p 2022
share|improve this answer
add comment

You can use the intermediate machine as a proxy. Make sure it has netcat (nc) installed. Put the following lines in your ~/.ssh/config (foo is a nickname for the inaccessible machine, foo.example.com is its name as seen from the intermediate machine, and gateway.example.com is the intermediate machine):

Host foo
HostName foo.example.com
ProxyCommand ssh gateway.example.com nc %h %p

Then ssh foo will connect (in two hops, but that's completely transparent) to the inaccessible machine.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.