First of all, by nested ssh, I mean the following way of using ssh:

ssh usera@Bob 'ssh usera@C'

suppose A wants to login on server C, but for some reason C is not directly available to A (e.g. C's behind a certain FW or NAT or so). Fortunately, A's friend, Bob has direct connection to C and A can connect to Bob as well. So, in order to login on C, A would actually do the aforementioned thing.

My question here is, will Bob be able to see the communication between A and C in clear, given Bob is the administrator of his server. My guess is yes, but not so sure about my understanding of SSH internals.

The reason I think Bob can see the plaintext is: There are two session keys: kab and kac, for the outer and nested ssh command respectively. kac is unknown to Bob ideally. (Is that true when Bob is the root user?). Anyway, when a message arrives at Bob, it has to be decrypted with kab, then encrypted with kac and send to C. So between the encryption and decryption, the plaintext is somewhere in the memory. Bob should be able to see it, not straightforwardly though.

Any insight?

2 Answers 2


Yes, as deviantfan has explained, if you do it that way, Bob can see your traffic.

A more secure way to achieve your goal is to use the proxy features built into SSH. The simplest way, if you have OpenSSH 7.3 or later:

ssh -J usera@Bob usera@C

For older OpenSSH versions versions, if you have at least OpenSSH 5.4 you can instead add the following to your ~/.ssh/config:

Host C
ProxyCommand ssh -W %h:%p usera@Bob

With even older OpenSSH versions, you'll need to use netcat instead (assuming Bob has it installed):

Host C
ProxyCommand ssh usera@Bob nc %h %p

Now when you connect to C, ssh will first connect to Bob and start up a proxy (either its built-in one or Bob's netcat). The connection from your local machine to C is then forwarded through this proxy. The connection is end-to-end encrypted with your local ssh client at one end and the remote server C at the other. The session key is negotiated between you and C; Bob never sees it.

Of course, Bob as your proxy can still impersonate C; but as long as you've previously verified C's host key fingerprint, you can easily detect this in the usual way.

  • Thanks for pointing the proxy features out. That's really a good point. A lightly off-the-topic question: What if C establishes a reverse ssh channel to Bob firstly. Would forward feature still work?
    – qweruiop
    Jun 26, 2015 at 19:50
  • Sure, just forward to localhost:2222 (or whatever port you reverse-forwarded) instead of %h:%p. You might also want to add a HostKeyAlias to make sure you're verifying the right fingerprint (although I think that should happen anyway). Jun 27, 2015 at 11:41
  • Nice tidbit about ssh -W %h:%p, though I'm not sure how it handles timeouts (e.g. I use ssh bastion nc -w 600 %h %p). OpenSSH 5.4 is quite young still, as it requires RHEL 7+ (RHEL 6 features OpenSSH 5.3 and Red Hat has long periods between releases), but you're probably fine otherwise (supported in Ubuntu 10.10, Debian Squeeze/6.0, and FreeBSD 8.2).
    – Adam Katz
    Jul 7, 2015 at 20:13

Yes, Bob can see the communication if he wants.

Essentially, the second ssh call is executed in a shell on Bob´s computer, similar to someone sitting there and typing on the real keyboard. Bob´s computer must have it (and every input) unencrypted. And the output from the target comes back to Bob, gets "displayed" in the shell of usera, and because of that the SSH server of Bob sends it back to A.

Bob doesn´t even need to bother with raw memory access or anything like that. There are programs (like script) to log every input and output of a shell to files. Bob can change the login shell of every registered user on his computer, so...

  • Thanks! It's good to know that tools like script exist.
    – qweruiop
    Jun 26, 2015 at 19:56

You must log in to answer this question.

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