Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask

Forced to modify perl telnet script to use both telnet and ssh

by essej1 (Novice)
on Aug 31, 2012 at 20:23 UTC ( #991084=perlquestion: print w/replies, xml ) Need Help??
essej1 has asked for the wisdom of the Perl Monks concerning the following question:

So, I've been tasked with modifying a perl script that currently uses telnet to run certain commands on various types of network devices. My boss refuses to rewrite the existing script or use perl expect. (Or even just plain old expect, which would take me less than a day.) He wants a way to make the connection and use telnet OR ssh, depending on the response from the devices.I've looked at "IO::Pty, Net::Telnet and SSH SOLVED" but it is rather old and sort of vague. Any thoughts on a way to proceed. (Not asking for a specific script, though that would be nice, just some pointers.) Oh, and we use openCSW, which has some differences from true CPAN. (i.e. Net::SSH::Perl not there).

OK, let's take this tact: What my "wonderful" boss really wants is to implement expect without actually using the expect module. I've got the test for SSH part working using Net::SSH2. Now I need to send a command, examine the response for subsequent commands. The responses vary because of the different levels and types of device firmware. I.E. one level for the same vendor responds with 'hostname$' while another responds 'hostname#'. (Note the '$' and '#'.) The different responses require slightly different follow-on commands. I'm a bit stuck on retrieving the responses. (I'm not a Perl guru so please be kind.)

  • Comment on Forced to modify perl telnet script to use both telnet and ssh

Replies are listed 'Best First'.
Re: Forced to modify perl telnet script to use both telnet and ssh
by Tanktalus (Canon) on Aug 31, 2012 at 23:22 UTC

    "depending on the response from the devices." What response? This is probably the most confusing aspect.

    "has some differences from true CPAN" - Yes, even you can use CPAN (I expect CPAN modules to still be installable - we do it all the time with the system perl on AIX, so I don't see why openCSW would be worse).

    Though, honestly, I prefer ssh over telnet anyway. It's just so easy to run "ssh user@host 'my command here'". But if you need to do both, I'm guessing that you can run "ssh user@host" nearly the same way as you telnet to the host. The major differences are at the beginning: the user won't be asked for, and the password prompt might be different (or not exist at all if you have an ssh key set up properly).

    At $work, I use our own ssh wrapper to handle parallelism (using AnyEvent), ssh tunnels, multiple hops (ssh to A, and use that to ssh to B under the ssh key credentials available on A), etc. I didn't find it terribly difficult - at least, not the ssh parts. Unfortunately, your problem description remains a bit vague, so I don't know where to start in sharing.

Re: Forced to modify perl telnet script to use both telnet and ssh
by Illuminatus (Curate) on Aug 31, 2012 at 21:45 UTC
    ...tasked with modifying a perl script...refuses to rewrite existing script...
    Which is it? It isn't clear to me which problem you're trying to solve, and what tools you have available. If you have an ssh-based solution already, then all you need to do is try telnet; if you get 'connection refused', then you have to use ssh. As for openCSW vs CPAN, they aren't mutually exclusive. If the prebuilt module you want isn't on openCSW then you can download and build it from CPAN (unless your boss won't let you do this either). Maybe if you posted what you do now, and where it needs to diverge to support ssh it would be clearer.

    Of course, you *could* just write it in Expect, call the finished product (but with '#! expect' at the top), and he'd be none the wiser...


      I've replied about the ssh/telnet issue. And my boss actually does know how to write perl. He just can't stand changes.
      Paradise: Florida, full tank of gas, no appointments.
Re: Forced to modify perl telnet script to use both telnet and ssh
by philiprbrenan (Monk) on Aug 31, 2012 at 21:42 UTC

    Proceed with Telnet as it is already in the script and you are constrained from rewriting the script. What exactly is the problem you are experiencing with Telnet?

Re: Forced to modify perl telnet script to use both telnet and ssh
by Mr. Muskrat (Canon) on Sep 01, 2012 at 15:23 UTC

    I'll give you a basic example that expands a bit on what Illuminatus said about try one and then the other.

    # in pseudocode no less! get $deviceIP ping $deviceIP or report it as not responding and exit ssh $deviceIP if ssh error then if ssh error is 'connection refused' then telnet $deviceIP or report error and exit do work with telnet connection else report error and exit end if end if do work with ssh connection

    If you already know which devices use telnet and which use ssh then things get even simpler. Just try the correct protocol!

    Update: Oops. I forgot the most important part.

    You will not get any good responses until you can give us some clear information regarding your problem and code that demonstrates said problem.

      ping $deviceIP or report it as not responding and exit

      Just a little, slightly off-topic bean counting. Some devices prefer not to respond to pings, yet they readily serve telnet, ssh, http or other services. Yes, this is stupid behaviour, nevertheless it happens, mostly because some clueless people dictated stupid "firewall" rules.

      I would omit the ping test, because it is generally useless. If you get a ping reply, you still don't know what services are supported, you only know that the device was reachable shortly after you sent the ping package. If you don't get a ping response, you know nothing. The device may be shut down, offline, firewalled, or misconfigured. In both cases, you still have to try ssh and telnet. Omitting ping reduces the amount of code needed and wastes slightly less network resources.

      Another different thing: Because ssh is encrypted and telnet is not, I would prefer to connect via ssh first, and only if that fails fall back to telnet.

      I would only try telnet first if I had to work with a known set of machines where telnet is much more likely enabled than ssh. But then again, if I know the machines, and know that they always respond to pings when they are up and running, a ping test may be faster then failing to establish an ssh connection.


      Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)

        Using ping first has become a habit for me since all of the devices we use at work respond to pings. We have a longer ssh timeout so when devices really are down, we find out sooner if we ping rather than connecting directly. (The longer timeout is due to some devices running Windows which takes longer to setup the initial ssh connection.)

        I did recommend using ssh first.

        Sorry I wasn't clear. We currently do have a working Perl/telnet script. Due to new security requirements we are moving to SSH. So, not all devices support SSH but will sometime in the future. Therefore I have to have a single script to handle both Telnet and SSH. (Lucky me). As stated, my dinosaur of a boss (he refuses to use new technology such as ZFS on Solaris) wants to "simply" modify the current script to handle both connections using the existing commands.
      The base issues are that we are moving to ssh from telnet, but not all at once and my boss refuses to make major changes. So, I've been tasked to implement expect like things without using expect. What I'm after is something like:
      send command read response send another command
      The devices being examined give different prompts or responses, depending on firmware or vendor. Therefore there are different follow-up commands. The following does work, but note the comments about
      #!/opt/csw/bin/perl use strict; use warnings; use Net::SSH2; my $host = "<host name or IP>" my $user = "<user ID>"; my $pass = "<user password>"; my $ssh2 = Net::SSH2->new(); my $ok = 1; print "==> $host\n"; $ssh2->connect($host) or $ok = 0; if (!$ok) { print "Probable telnet\n"; exit(1); } if (!$ssh2->auth_password ($user,$pass)) { print "==> 4 pass fail\n"; exit(1); } my $chan2 = $ssh2->channel(); $chan2 -> shell(); # form some reason the order of the commands matters. # change any one and the prints are blank print $chan2 "dir\n"; sleep (1); # for some reason the sleep is needed to get output print "LINE : $_" while <$chan2>; print $chan2 "sh ver\n\n"; print "LINE : $_" while <$chan2>; print $chan2 "sh clock\n\n"; print "LINE : $_" while <$chan2>; print $chan2 "exit\n"; print "==> END\n"
      Paradise: Florida, full tank of gas, no appointments.
        Hi, I have written a module which integrates both SSH & Telnet; it's an overlay which uses both Net::Telnet and Net:SSH2; it's called Control::CLI. Maybe that might help you. I made it because I needed it to run on Windows systems, where I was not able to get expect to work.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://991084]
Approved by davido
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others rifling through the Monastery: (6)
As of 2018-06-20 04:21 GMT
Find Nodes?
    Voting Booth?
    Should cpanminus be part of the standard Perl release?

    Results (116 votes). Check out past polls.