You can use Net::OpenSSH and Net::OpenSSH::Gateway. The later is not on CPAN yet because I am not completely happy with its internals, but otherwise it is completely functional.
Once installed, you can run:
my $ssh = Net::OpenSSH->new($target,
gateway => { proxies => ['ssh://serverA',
'ssh://serverB']
+});
my $output = $ssh->capture('ls');
Under the hood it uses several tricks to find a way to jump from one hop to the next, as creating tunnels or running any of socat, netcat or perl. | [reply] [d/l] [select] |
| [reply] [d/l] |
| [reply] [d/l] |
I know your pain. Server A, for me, might be a hardware monitor. Server B might be a management node. Server C might be the node I care about. In my case, if I need A at all, I set up an ssh tunnel there, and then I ssh "directly" to server B (on a special port on localhost if A was needed), and then from there I ssh to C. Server A always is connected to the corporate network, B might be, C might be as well, but much more rarely. (And sometimes my scripts run directly on server B, which adds some fun to the mix.)
Either one of these solutions may apply.
First, if A is needed, I look for the ssh tunnel process. If it doesn't exist, I create it. If another tunnel (to a different monitor) is already set up, I kill that before creating the new tunnel. (I'll eventually try to work out some smarts to use multiple ports here, but, until then, this is sufficient.) I set some env vars: PROXY_PORT to the port number, and SSH_HOSTNAME to the name I want to associate with this in the known_hosts file.
Then, I take the ssh command I want to run, and shell quote it (this is convoluted), and create the new ssh command around it:
@cmd = ('ssh', @ssh_options, # e.g., -o => 'ForwardX11 no'
$user . '@' . $node, # e.g., root@serverC
quote_cmd(@cmd) # this @cmd is the original command we want to
+ run.
);
@cmd = ('ssh', @ssh_options, # e.g., -o => 'ForwardX11 no'
$ENV{PROXY_PORT} ? (-p => $ENV{PROXY_PORT}) : (),
$ENV{SSH_HOSTNAME} ? ? (-o => "HostKeyAlias $ENV{SSH_HOSTNAME}
+") : (),
$proxy, # localhost if A is needed, otherwise server B
quote_cmd(@cmd)
) if $proxy;
In my case, I need my local ssh key to be valid on servers A (to create the proxy) and B (to log in there), and the ssh key on B to be valid on C.
So, the tricky bit is finding how to quote a command. That is probably best left to another node, and I'm sure it's been answered before here, as I'm sure I couldn't have figured out the edge cases on my own on the first try :-) | [reply] [d/l] |
I use Transparent Multi-hop SSH for the cases where I need to ssh through one host to get to another. I have no idea which/whether Perl SSH modules support the ProxyCommand in the .ssh/config but my needs for using SSH from Perl have been simple enough to be met by backticks and pipes.
| [reply] [d/l] |
I dont have direct access to ServerB or ServerC only from ServerA I can move on to ServerB and then on to ServerC. I have access to ServerA. How can I achieve it.
What is the end game here? What are your trying to accomplish on ServerC?
Peter L. Berghold -- Unix Professional
Peter -at- Berghold -dot- Net; AOL IM redcowdawg Yahoo IM: blue_cowdawg
| [reply] |
| [reply] |
My approach on ServerC would be to run that set of scripts out of cron (or whatever the local equivalent is) and modify the script to send the output to me one way or another.
The "send it to me" methods could be a network share (NFS,CFS,AFS,whatever), an FTP (preferably SFTP) or as a last resort email. If you had an aggregator script on ServerB you could have ServerB pick up the output from a spool directory on ServerC and put it in a local directory. Then ServerA could pick that output up and pull it to its local directory where you could pick it up. Sorta a Rube Goldberg arrangement but I've seen worse.
I make computers work for me... I don't work for them. :-)
Peter L. Berghold -- Unix Professional
Peter -at- Berghold -dot- Net; AOL IM redcowdawg Yahoo IM: blue_cowdawg
| [reply] |
Hi davidsnt,
one important question: How do you authenticate at Server B while being on Server A (same for Server C when being on Server B)?
I'm asking because you can't simply provide passwords and passphrases via stdin to ssh.
Best regards
McA
| [reply] |
| [reply] |
| [reply] |