Q:

Can the root of a system access to unencrypted data when using a double tunnel?

I connect to a DMZ gateway system (B) which is not secured. From this machine (B) I can connect to the final destination (C).
A-->B-->C
I created a ssh tunnel from A to B and forwarding the port 22 of C:
ssh -L 2222:C:22 user@B

and then I can connect from A to C using
ssh -p 2222 user@localhost

This is safe but it's not very efficient in overhead added as I have a tunnel inside a tunnel.
An alternative is to run ssh as a ssh command:
ssh user@B ssh user@C

Like this there is less overhead, but is this the same safe?
If somebody has root access to B, can he access to any of the information?
I understand that the information is unencrypted at the kernel level?
And if I did't have the public key of C?
Any idea or suggestion where I could find information about this?
Many thanks!

A:

Before trying to trade performance for security, I suggest actually measuring the performance. The overhead for SSH encryption is slight; it increases data size by less than 1%, and CPU usage is low unless you have a pretty weak CPU or a pretty fast network (a Core2 CPU can keep up with 10 MBytes/s SSH by using less than 15% of a single core). So chances are that the safe method, with the double tunnel, is not that expensive.
Moreover, in your second suggestion, you have less size overhead, and also less CPU overhead on your desktop system (A), but more CPU overhead on the gateway (B), since that gateway would have to decrypt the data from A and reencrypt it to send it to C. Since a gateway tends to be a shared resource, chances are that free CPU is scarcer on B than A. Therefore, if performance matters at all (I don't think so, and it should be measured anyway), then the safe method is also the best method for performance.
As @Iszi points out, your second method is also insecure, since it would allow the gateway to make a MitM attack. I would like to point out that it also makes scp usage harder. Therefore, you should use the tunnel-in-tunnel method: it is safer, more flexible, and might even be faster.

A:

If someone has access to B in the given scenario, they could set up a proxy to perform a man-in-the-middle attack on the connection from A to C.  This would allow them to decrypt any traffic between A and C, if it is not otherwise encrypted at a higher level.
The attacker would configure B to present itself to A as C while using the attacker's key pair.  Then he would similarly impersonate A to C, so that information can be passed through B as if nothing unusual was happening except that the attacker can now sniff the traffic at B.
The only way to detect this would be for A and/or C to have pre-existing, verified copies of each others' public keys.  Then, when the attacker jumps in the middle using his keys, the untrusted entity can be recognized and the connection refused.

A:

Yes, it's possible for the root user on B to snoop your traffic,  although you don't say exactly what OS it is. On Linux, that might include the ttysnoop program or using a debugger against sshd.
I've used tunnel-in-a-tunnel a lot (as well as SSH over PPP over SSH, which is yet another layer), and it doesn't necessarily have a serious performance or latency burden.  Of course, there is some overhead, but not more than the usual variability of a connection.
Consider the worst case for a single character.  In Telnet that would be sent as an Ethernet frame with a payload of 46 bytes (20 bytes IP header, 20 bytes TCP header, 1 byte data, but the Ethernet standard requires 46 bytes minimum payload, 42 in a VLAN environment).  In SSH it would be a payload of 68 bytes ("The minimum size of a packet is 16 (or the cipher block size, whichever is larger) bytes (plus 'mac').", RFC 4253); I see 92 bytes watching an actual connection with Wireshark.  In SSH-over-SSH there's the overhead of SSH framing; I see a payload of 140 bytes.
Sending a lot of data, SSH uses frames (over TCP, hence not limited by packet-size) of up to 32k bytes, so the overhead of double-tunneling is negligible.  It takes me 20s to transfer a 2M file to a VM that I can access either through an SSH tunnel or via SSH directly.  If I dd a 36k text file, it takes about 84 packets almost all 1380 bytes long to send from a "simple" ssh session.
Lastly,  the exact command you gave,
ssh user@B ssh user@C

probably won't do what you expect; this second "ssh" will probably give the message "Pseudo-terminal will not be allocated because stdin is not a terminal", and you'll get a shell that does not prompt you for input or support command-line editing.  Instead try
ssh user@B -t ssh user@C

Also note that this could actually result in more small packets (= TCP header overhead and real delay) if the B host can't keep up with the data coming into it.

