21

I've been struggling to set up a valid configuration to open a connection with a second machine, passing through another one, and using an id_rsa (which requests me a password) to connect to the third machine.

I've asked this question in another forum, but I've received no answer that could be considered very helpful.

The problem, better described, goes as follows:

Local machine: user1@localhost
Intermediary machine: user1@inter
Remote target: user2@final

I'm able to do the entire connection using pseudo-tty:

ssh -t inter ssh user2@final

(this will ask me the password for the id_rsa file I have in machine "inter")

However, for speeding things up, I'd like to set my .ssh/config file, so that I can simply connect to machine "final" using:

ssh final

What I've got so far -- which does not work -- is, in my .ssh/config file:

Host inter
    User user1
    HostName inter.com
    IdentityFile ~/.ssh/id_rsa

Host final
    User user2
    HostName final.com
    IdentityFile ~/.ssh/id_rsa_2
    ProxyCommand ssh inter nc %h %p

The id_rsa file is used to connect to the middle machine (this requires me no password typing), and id_rsa_2 file is used to connect to machine "final" (this one requests a password).

I've tried mixing up some LocalForward and/or RemoteForward fields, and putting the id_rsa files in both first and second machines, but I could not seem to succeed with no configuration whatsoever.

P.S.: the thread I've tried to get some help from:

http://www.linuxquestions.org/questions/linux-general-1/proxycommand-on-ssh-config-file-4175433750/

Carl B
  • 6,660
  • 16
  • 46
  • 66
Rubens
  • 650
  • 1
  • 6
  • 16

2 Answers2

24

METHOD 1 (use ssh-key on inter)

If you want to retain the authentication flow

local -- authenticate --> inter -- authenticate (ask password) --> final

This cannot be done with .ssh/config proxyhost.

What you need is bash shell alias (I hope you are using bash).

In ~/.bashrc, add following line

alias ssh-final='ssh -t inter ssh user2@final.com'

In command prompt, just type following

ssh-final

final section in ~/.ssh/config is not used.

Connection Details(1)

ssh -t inter ssh user2@final.com can be view as follow

local# ssh inter
inter# ssh user2@final.com

local is only "talking" to inter. There is no direct or indirect ssh connection between local and final. local is just displaying the output of ssh user2@final.com.

METHOD 2 (use ssh-key on local)

Authentication with same ssh-key

Host inter
    User user1
    HostName inter.example.com

Host final
    User user2
    Hostname <final.com / final IP Address>
    Port 22
    ForwardAgent yes
    ProxyCommand ssh inter nc %h %p

Copy local ~/.ssh/id_ras.pub to

/home/user1/.ssh/authorized_keys in `inter`
/home/user2/.ssh/authorized_keys in `final`

Connection Details(2)

ssh tunneling

Before we go into detail of ProxyCommand, lets look at the following example

Step 1, on terminal window 1

local# ssh inter -L 2000:final.com:22

Step 2, on terminal window 2

local# ssh localhost -p 2000

In terminal 1, a tunnel is setup between local port 2000 and final.com port 22. Anything sent to local port 2000 will be forward to final.com port 22 and vice versa.

In terminal 2, ssh connect to local port 2000, but actually is communicating with final.com port 22, which is the sshd.

With tunneling, local ssh client in Step 2 is connected with final.com sshd directly.

The "output" of local port 2000, is "raw" ssh daemon traffic.

Common usage of such tunnel is to access internal web server or email server. Following is example for web server

local# ssh inter -L 2000:final.com:80

In the browser use following URL

http://localhost:2000

The two end points of the tunnel are local port 2000, and final.com port 80.

Traffic coming in and out of tunnel end point "AS IS". Lets call that "raw" traffic.

ProxyCommand

Host final
    User user2
    Hostname <final.com / final IP Address>
    Port 22
    ForwardAgent yes
    ProxyCommand ssh inter nc %h %p

The ProxyCommand take it one step further. It skip the step of creating a local port and connect to it.

A ssh client will execute what ever command given behind ProxyCommand, and treat the output of that command as "raw" traffic. It is holding onto the local end point, and then start a ssh connection with it.

Why one work the other does not?

The following command

ssh inter nc final.com 22

basically means (1) connect to inter, then (2) on inter, run command nc final.com 22.

nc - arbitrary TCP and UDP connections and listens

So nc final.com 22 will connect to final.com port 22, print out all incoming traffic to stdout, and send all stdin to the other side. It is a "tunnel" between nc stdin/out and final.com port 22.

Since nc is ran within the ssh session, all its stdout is passes back to the ssh client, as "raw" traffic. And the ssh client can pass traffic into nc stdin, which will end up at final.com port 22.

Through the above "tunnel", local ssh client will start a ssh session with final.com directly.

The following command

ssh -t inter ssh user2@final.com

does not work with ProxyCommand because the out of it is not "raw" traffic from a ssh daemon. It is the stdout of a ssh client. Client talk to client means no business.

Authentication with different ssh-key (OP original config)

Host inter
    User user1
    HostName inter.com
    IdentityFile ~/.ssh/id_rsa

Host final
    User user2
    HostName final.com
    IdentityFile ~/.ssh/id_rsa_2
    ProxyCommand ssh inter nc %h %p

Copy local ~/.ssh/id_ras.pub to

/home/user1/.ssh/authorized_keys in `inter`

Copy local ~/.ssh/id_ras_2.pub to

/home/user2/.ssh/authorized_keys in `final`

Both of the above will enable the following usage

local# ssh final

Additional Checking

Use verbose

local# ssh -v final

That should help identifying ssh problem.

Check nc

ProxcyCommand is executing nc on inter. Check if nc is actually available on inter.

local# ssh inter
inter# nc final.com 22

Check rsa key is setup properly

If different keys are to be used for inter and final, following files should exist in local machine

local# ls ~/.ssh
id_rsa id_rsa_2 id_rsa.pub id_rsa_2.pub

Since you can ssh to inter already, check key setup on final. From your local machine

local# ssh -t inter ssh user2@final
final# cat .ssh/authorized_keys

You should see content of id_rsa_2.pub there.

John Siu
  • 5,387
  • 2
  • 20
  • 23
  • Sorry, I should've pointed this out; I'm actually able to connect using `ssh -t`, but what I'd like to do is exactly simulate the behavior I have from using `ssh -t` using only the configuration on the `.ssh/config`. – Rubens Dec 29 '12 at 22:50
  • The config file, even the one you post should work. Try go through the `checking` step. There must be something missing/wrong. – John Siu Dec 29 '12 at 22:52
  • 1
    With `ssh -t`, your ssh to `final` is initiated from `inter`, which is "almost" the same as `local# ssh inter` then `inter# ssh final`. The authentication is between `inter` and `final`. With proxy/nc, your ssh to final is initiated from your local machine, through a tunnel, to `final`. The authentication is between `local` and `final`. – John Siu Dec 29 '12 at 22:58
  • @Rubens base on your comment, I think you mistaking that you are still using `inter` ssh-key to authenticate with `final`. Try copy `id_rsa_2` into `local` ~/.ssh/id_rsa_2 (DO NOT OVER WRITE local id_rsa) and your problem maybe gone. – John Siu Dec 29 '12 at 23:13
  • @Rubens check Method 1, I think that is what you looking for. .ssh/config actually cannot do the same thing. – John Siu Dec 30 '12 at 02:19
  • I'm sorry I took so long to answer, but method 1 is exactly what I have now -- prettified with an alias, but what I have now nonetheless. Happens though the second part of this you said is what I've been afraid of: `.ssh/config actually cannot do the same thing.`. If so, if I can't simulate a `$user@first~ ssh -t second ssh third`, then there's nothing else to try. It just cannot be done. I did not read the rest of your post, but if you add these lines saying it's not possible, that's what I'm accepting as answer. Regards, and thank you all for the attention! – Rubens Jan 04 '13 at 22:31
  • Noticed you've made an edit, but, is there any simple explanation you'd mind to include to the statement you've added? – Rubens Jan 04 '13 at 22:41
  • I updated the answer. The reason of proxyhost does not work is ssh expect "raw" network traffic from a tunnel. I will update with longer explaination later tonight as i am using my tiny phone now. – John Siu Jan 04 '13 at 22:42
  • And by "raw" you mean, `ssh` only accepts tunnels that have been created in an "unique command", or "at once"? What is a "raw" network traffic? If it is what I said, would a solution to this be a multiple step connection? Opening `port` in each of the "hops" (machines)? Would this one solution be possible in `.ssh/config`? – Rubens Jan 04 '13 at 22:45
  • That's fine, I'll wait to see your edit; thanks, once again! – Rubens Jan 04 '13 at 22:50
  • @Rubens Please check Connection Details(1) & (2). Hopefully it is clear enough @.@ – John Siu Jan 05 '13 at 01:51
  • Whoa! Amazing, really! Thank you so much, man! It's very clear now; it's even shining (: Wonderful explanation! Don't know how to thank you more, so here is my bounty, as a sign of gratitude. Now I'll get myself poking around with `ssh` with a bit more of confidence! Regards! (: – Rubens Jan 05 '13 at 02:41
  • 2
    Note that ssh2 has `nc` built in. So instead of `ProxyCommand ssh gateway nc %h %p`, you'd write `ProxyCommand ssh inter -W %h:%p`. – user123444555621 Sep 04 '14 at 05:22
2

I didn't see any actually errors listed or ssh -v statements which would help see where it's hanging up.

Hey man you have it almost right--- the best and most secure way is to have both keys on the local machine. You would then use ssh-agent forwarding to connect rather than leaving keys at intermediate steps. You also have the advantage of needing to type your key passphrase only once per logon.

If you have a modern/userfriendly OS like ubuntu (on your local machine) this should work no problem without any *massaging*. I left off the identity file intentionally, you will not need it.

Your config file would look like this:

Host inter
    User user1
    ForwardAgent yes
    HostName inter.com

Host final
    ForwardAgent yes
    User user2
    HostName final.com
    ProxyCommand ssh inter nc %h %p

If it doesn't, then run through these steps to make sure you ssh-agent is running:

'ssh-add -l' (lower case L) will list your private keys if any are loaded, or will be blank, or will say can’t connect to ssh-agent, if so, start ssh-agent.
'eval `ssh-agent`' (those are backticks) starts ssh agent
'ssh-add' will add your key… you can add a path argument if you have a key in a non-default area. At this point you will enter your passphrase.

There is a nice guide explaining how this works, here.

MattPark
  • 1,235
  • 1
  • 8
  • 18