Perl, SSH und Cisco

maceis

maceis

Aktives Mitglied
Thread Starter
Dabei seit
24.09.2003
Beiträge
16.880
Reaktionspunkte
626
Hallo zusammen,

ich möchte gerne einige Perskripte zur Fernwartung meines Cisco-Routers über eine SSH-Verbindung schreiben.
Dazu habe ich zunächst mal das Modul "Net::SSH::perl" installiert und dann versucht mich schrittweise an die Lösung heranzuarbeiten.

Das Ausführen von Kommandos auf SSH-Servern (2.ter Mac, Cisco Router) funktioniert problemlos.
Was nicht funktioniert ist das Ausführen von Kommandos, die eine interaktive Kommunikation erfordern.

Unter http://search.cpan.org/src/DROLSKY/Net-SSH-Perl-1.25/eg/remoteinteract.pl gibt es ein Beispielskript, das eine Lösung anhand des Kommandos "passwd" demonstrieren soll.
Trotz intensiver Bemühungen ist es mir nicht gelungen, das Skript (die notwendigen Anpassungen habe ich natürlich vorgenommen) erfolgreich auszuführen.
Getestet habe ich das mit zwei Macs (10.3.7).

Hier die Änderungen, die ich durchgeführt habe (mit Zeilennummern):
...
26 my($host, $username, $new_password, $old_password) =qw(<der_hostname> maceis <das neue Passwort> <das alte Passwort>);
...
69 $ssh->register_handler(SSH_SMSG_STDERR_DATA, sub {
70 my($ssh, $packet) = @_;
71 my $str = $packet->get_str;
72
73 if ($str =~ /password/) {
74 print "\n\tmatch 1\n";
75 my $packet = $ssh->packet_start(SSH_CMSG_STDIN_DATA);
76 $packet->put_str($old_password);
77 $packet->send;
78 }
79
80 elsif ($str =~ /New/ ) {
81 print "\n\tmatch 2\n";
82 my $packet = $ssh->packet_start(SSH_CMSG_STDIN_DATA);
83 $packet->put_str($new_password);
84 $packet->send;
85 }
86
87 elsif ($str =~ /Retype/) {
88 print "\n\tmatch 3\n";
89 my $packet = $ssh->packet_start(SSH_CMSG_STDIN_DATA);
90 $packet->put_str($new_password);
91 $packet->send;
92 }
93 });
...
Und hier die Augabe (gekürzt)
...
host.domain.tld: Connecting to voyager, port 22.
host.domain.tld: Remote protocol version 1.99, remote software version OpenSSH_3.6.1p1+CAN-2004-0175
...
host.domain.tld: Connection established.
...
host.domain.tld: Encryption type: DES3
...
host.domain.tld: Trying password authentication.
host.domain.tld: Sending command: passwd
host.domain.tld: Entering interactive session.

match 1
An dieser Stelle bleibt das Skript hängen.
Ich schließe daraus, dass die Übertragung des Kommandos (passwd) und der Empfang der Serverantwort (Changing password for martin. \nOld password:) funktionieren
Der Code wird bis Zeile 74 ordnungsgemäß abgearbeitet.
Ich vermute, dass das Senden des Packets in Zeile 76/77 nicht funktioniert.

Habe schon ziemlich lange im Netz gestöbert und leider bisher keine Lösung gefunden.
Bin für jede Anregung dankbar.
 
Zuletzt bearbeitet:
Ich würde das Expect-Modul benutzen und SSH als externe Anwendung aufrufen - ein ssh-client sollte ja auf dem Rechner, der es aufruft installiert sein.

Hier ein Beispiel, was sich nach Abfrage des Passworts auf einem Rechner per SSH einlogt und den Befehl "uptime" ausführt, sobald in der Ausgabe "marvin" steht (der Rechner heisst marvin, also ist das ein Teil des Prompts)... Am Ende geht das Skript in einen interaktiven Modus, man kann also in der SSH-Session weiterarbeiten (könnte man auch durch absetzten von "exit" beenden)

Ich weiss, daß das Beispiel sinnfrei ist, aber es zeigt eigentlich alles, was man braucht :D

Code:
#!/usr/bin/perl

use Expect;
use Term::ReadPassword;

my $password = read_password('Password: ');

my $exp = new Expect;
$exp->slave->clone_winsize_from(\*STDIN);

$exp->spawn("ssh test@10.0.0.1");
 
if ($exp->expect(undef, 'Password')) {
        $exp->send("$password\n");
}

if ($exp->expect(undef, ' marvin ')) {
        $exp->send("uptime\n");
}

$exp->interact();

HTH
 
absi schrieb:
Ich würde das Expect-Modul benutzen und SSH als externe Anwendung aufrufen - ein ssh-client sollte ja auf dem Rechner, der es aufruft installiert sein.
...
Danke, ich werde das auf jeden Fall testen, obwohl die Kommunikation mit Net::SSH::perl zumindest mit anderen Computern inzwischen klappt.
Probleme hab ich noch mit meinem Cisco-Router.
Vielleicht kann ich die mit Expect lösen - mal seh'n
 
Zurück
Oben Unten