Mar 12, 2018:
There's now a deep-ssh-like which behaves closer to (open)ssh. It is suitable for wrapping with rsync or sshfs.
EG:
rsync: --rsh /usr/local/bin/deep-ssh-like
sshfs: ssh_command=/usr/local/bin/deep-ssh-like
In both cases, you can then use bang paths for your ssh hops.
If you've ever worked with an unrouted network, one or more
discontinuities (ssh hops, not one-network VPN's) deep, then
you may appreciate "deep-ssh".
Basically, deep-ssh just constructs a bunch of ssh's that call other
ssh's, until you're at your destination, at which point, a command is
run.
Usage is like:
deep-ssh '' host1!host2!host3 'uname -a'
This command will ssh to host1, which in turn will ssh to host2, which
in turn will ssh to host3, and then on host3 the command "uname -a" is
run.
You can also do something like:
deep-ssh '' host1!someuser@host2!host3 'uname -a'
Note the addition of a username specification.
You may want to consider setting up passwordless,
passphraseless ssh, once for each ssh hop. Alternatively, you
can just let ssh run a bunch of
ssh-askpass/x11-ssh-askpass/gnome-ssh-askpass commands to ask for a
password on each host in turn.
deep-ssh will attempt to set up X11 tunneling on each hop. However, if
for some reason one or more of the hosts you are connecting through, or
the host you are initiating the deep-ssh from, has X11 forwarding
problems, then the X11 forwarding will not work. Someday, I may have to
revise this to do ssh -Y instead of ssh -X...
I gave in and revised the quoting style to use exponential backslashing,
instead of trying to get away with alternating ' and ". This is much
more in line with how I really expected things to work.
I've tested deep-ssh as far as:
~/bin/deep-ssh '' host1!root@host2!host3!host4!host5 "uname -a"
Executing: eval ssh -X host1 \" eval ssh -X root@host2 \\\" eval ssh -X host3\\\\\\\" eval ssh -X host4 \\\\\\\\\\\\\\\" eval ssh -X host5 \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"uname -a\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" \\\\\\\\\\\\\\\" \\\\\\\" \\\" \"
It asked me for a lot of passwords (via the GUI each time), but it did
eventually give me "uname -a" output from host5! :)
Shell metacharacters in your command are now escaped quite well,
but here documents aren't attempted. So, for example:
deep-ssh host1!host2 'cat > /tmp/foo' < /tmp/foo
should work fine now.
Note that some shells may require you to escape your !'s. Other shells
may or may not require you to escape them, depending on how they're
configured. Still others may not allow you to escape the !'s at all.
If you're in this latter situation, you might want to use a real
shell :), or modify deep-ssh to use a different delimiter.
Download deep-ssh here. It's going to
need my bashquote python module.
Another approach can be found here. I
must say, it's an interesting way of accomplishing much the same
thing, and even has advantages over deep-ssh. I hope to find time to
look into this eventually. It'll most likely take longer to set up, but
once it's set up, you no longer have a "weak as the weakest link in the
chain" situation. Which of course leads one to consider a deep-ssh -
like program that configures what's needed for the method at the
URL. :)