Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

Multilevel SSH

by davidsnt (Novice)
on Oct 16, 2012 at 11:18 UTC ( [id://999287]=perlquestion: print w/replies, xml ) Need Help??

davidsnt has asked for the wisdom of the Perl Monks concerning the following question:

Hello Monks

I need some help in building a multilevel ssh in perl. I am using Net::SSH::Perl

My requirement is that I have to connect to ServerA and from ServerA connect to ServerB and from ServerB connect to ServerC and execute few set of commands and collect the results.

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.

Thanks

Replies are listed 'Best First'.
Re: Multilevel SSH
by zentara (Archbishop) on Oct 16, 2012 at 12:25 UTC
Re: Multilevel SSH
by salva (Canon) on Oct 17, 2012 at 07:49 UTC
    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.
      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.

      I learned recently that the latest versions of OpenSSH support -W host : port to do what historically we've done with socat/netcat.

        I know, I requested it :-)

        Net::OpenSSH::Gateway already supports it but -W requires port forwarding to be enabled on the server and, in my experience, that feature is frequently disabled in ssh gateways for security reasons.

Re: Multilevel SSH
by Tanktalus (Canon) on Oct 16, 2012 at 19:55 UTC

    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 :-)

Re: Multilevel SSH
by grantm (Parson) on Oct 16, 2012 at 19:54 UTC

    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.

Re: Multilevel SSH
by blue_cowdawg (Monsignor) on Oct 16, 2012 at 11:58 UTC
        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

      On ServerC I have few scripts that has to be executed and I collect the output of the script to parse and get some results. Now I do this manually, login to servers one by one to get the things done

        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
Re: Multilevel SSH
by McA (Priest) on Oct 16, 2012 at 11:46 UTC

    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

      ServerB and ServerC are connected and the ssh fingerprints are shared between them so if I login to ServerA(gateway) I get access to Server B and from ServerB I get access to ServerC

        Do you have to type user/password on Server B and C?

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://999287]
Approved by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others lurking in the Monastery: (2)
As of 2024-04-20 06:26 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found