Просмотр исходного кода

bugfix: fixed ssh client for huawei devices

Dmitriev Roman 4 лет назад
Родитель
Сommit
56366939cc
2 измененных файлов с 67 добавлено и 31 удалено
  1. 66 30
      scripts/Rstat/cmd.pm
  2. 1 1
      scripts/Rstat/config.pm

+ 66 - 30
scripts/Rstat/cmd.pm

@@ -284,6 +284,10 @@ if (!$device->{port} and $switch_auth{$device->{vendor_id}}{port}) { $device->{p
 
 
 my $t;
 my $t;
 
 
+#open my $out, '>', "/tmp/debug-$device->{ip}.txt" or warn $!;
+#$Net::OpenSSH::debug_fh = $out;
+#$Net::OpenSSH::debug = -1;
+
 if ($switch_auth{$device->{vendor_id}}{proto} eq 'telnet') {
 if ($switch_auth{$device->{vendor_id}}{proto} eq 'telnet') {
     if (!$device->{port}) { $device->{port} = '23'; }
     if (!$device->{port}) { $device->{port} = '23'; }
     log_info("Try login to $device->{device_name} $device->{ip}:$device->{port} by telnet...");
     log_info("Try login to $device->{device_name} $device->{ip}:$device->{port} by telnet...");
@@ -340,7 +344,6 @@ if ($switch_auth{$device->{vendor_id}}{proto} eq 'telnet') {
 if ($switch_auth{$device->{vendor_id}}{proto} eq 'ssh') {
 if ($switch_auth{$device->{vendor_id}}{proto} eq 'ssh') {
     if (!$device->{port}) { $device->{port} = '22'; }
     if (!$device->{port}) { $device->{port} = '22'; }
     log_info("Try login to $device->{device_name} $device->{ip}:$device->{port} by ssh...");
     log_info("Try login to $device->{device_name} $device->{ip}:$device->{port} by ssh...");
-    eval {
 	$t = Net::OpenSSH->new($device->{ip},
 	$t = Net::OpenSSH->new($device->{ip},
 	    user=>$device->{login},
 	    user=>$device->{login},
 	    password=>$device->{password},
 	    password=>$device->{password},
@@ -356,35 +359,35 @@ if ($switch_auth{$device->{vendor_id}}{proto} eq 'ssh') {
 	    ]
 	    ]
 	    );
 	    );
 
 
-        if (exists $switch_auth{$device->{vendor_id}}{enable}) {
-            $t->system($switch_auth{$device->{vendor_id}}{enable}."\n\r");
-            }
+        if ($t->error) {  log_error("Login to $device->{device_name} ip: $device->{ip} by ssh aborted: ".$t->error); }
+
+        netdev_set_enable($t,$device);
+
         if ($device->{vendor_id} eq '2') {
         if ($device->{vendor_id} eq '2') {
-            $t->system("terminal datadump");
-            $t->system("no logging console");
+            $t->capture("terminal datadump");
+            $t->capture("no logging console");
             }
             }
         if ($device->{vendor_id} eq '5') {
         if ($device->{vendor_id} eq '5') {
-            $t->system("terminal page-break disable");
+            $t->capture("terminal page-break disable");
             }
             }
         if ($device->{vendor_id} eq '6') {
         if ($device->{vendor_id} eq '6') {
-            $t->system("terminal length 0");
+            $t->capture("terminal length 0");
             }
             }
         if ($device->{vendor_id} eq '9') {
         if ($device->{vendor_id} eq '9') {
-            $t->system("/system note set show-at-login=no");
+            $t->capture("/system note set show-at-login=no");
             }
             }
         if ($device->{vendor_id} eq '16') {
         if ($device->{vendor_id} eq '16') {
-            $t->system("terminal width 0");
+            $t->capture("terminal width 0");
             }
             }
         if ($device->{vendor_id} eq '17') {
         if ($device->{vendor_id} eq '17') {
-            $t->system("more displine 50");
-            $t->system("more off");
+            $t->capture("more displine 50");
+            $t->capture("more off");
             }
             }
         if ($device->{vendor_id} eq '38') {
         if ($device->{vendor_id} eq '38') {
-            $t->system("disable cli prompting");
-            $t->system("disable clipaging");
+            $t->capture("disable cli prompting");
+            $t->capture("disable clipaging");
             }
             }
-        };
-    if ($@) { log_error("Login to $device->{device_name} ip: $device->{ip} by ssh aborted: $@"); return; } else { log_info("Login to $device->{device_name} ip: $device->{ip} by ssh success!"); }
+    log_info("Login to $device->{device_name} ip: $device->{ip} by ssh success!");
     }
     }
 
 
 return $t;
 return $t;
@@ -396,11 +399,9 @@ sub netdev_set_enable {
 my $session = shift;
 my $session = shift;
 my $device = shift;
 my $device = shift;
 return if (!exists $switch_auth{$device->{vendor_id}}{enable});
 return if (!exists $switch_auth{$device->{vendor_id}}{enable});
-my $cmd = "$switch_auth{$device->{vendor_id}}{enable}
-SLEEP 5
-$device->{enable_password}
-";
+my $cmd = $switch_auth{$device->{vendor_id}}{enable};
 netdev_cmd($device,$session,$switch_auth{$device->{vendor_id}}{proto},$cmd,3);
 netdev_cmd($device,$session,$switch_auth{$device->{vendor_id}}{proto},$cmd,3);
+if ($device->{enable_password}) { netdev_cmd($device,$session,$switch_auth{$device->{vendor_id}}{proto},$device->{enable_password},3); }
 }
 }
 
 
 #---------------------------------------------------------------------------------
 #---------------------------------------------------------------------------------
@@ -408,9 +409,9 @@ netdev_cmd($device,$session,$switch_auth{$device->{vendor_id}}{proto},$cmd,3);
 sub netdev_cmd {
 sub netdev_cmd {
 my ($device,$session,$proto,$cmd,$telnet_version)=@_;
 my ($device,$session,$proto,$cmd,$telnet_version)=@_;
 my @result=();
 my @result=();
+my @tmp=();
+if (ref($cmd) eq 'ARRAY') { @tmp = @{$cmd}; } else { @tmp = split(/\n/,$cmd); }
 if ($proto eq 'ssh') {
 if ($proto eq 'ssh') {
-    my @tmp=();
-    if (ref($cmd) eq 'ARRAY') { @tmp = @{$cmd}; } else { push(@tmp,$cmd); }
     eval {
     eval {
     foreach my $run_cmd (@tmp) {
     foreach my $run_cmd (@tmp) {
         next if (!$run_cmd);
         next if (!$run_cmd);
@@ -428,10 +429,49 @@ if ($proto eq 'ssh') {
     };
     };
     if ($@) { log_error("Abort: $@"); return 0; };
     if ($@) { log_error("Abort: $@"); return 0; };
     }
     }
+if ($proto eq 'tssh') {
+    my $t = Net::OpenSSH->new($device->{ip},
+	    user=>$device->{login},
+	    password=>$device->{password},
+	    port=>$device->{port},
+	    timeout=>10,
+	    master_opts => [ 
+	    -o => "StrictHostKeyChecking=no", 
+	    -o => "PubkeyAcceptedKeyTypes=+ssh-dss", 
+	    -o => "KexAlgorithms=+diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1",
+	    -o => "HostKeyAlgorithms=+ssh-dss",
+	    -o => "LogLevel=quiet",
+	    -o => "UserKnownHostsFile=/dev/null"
+	    ]
+	    );
+    if ($t->error) {  log_error("Login to $device->{device_name} ip: $device->{ip} by ssh aborted: ".$t->error); }
+    my ($pty, $pid) = $t->open2pty({stderr_to_stdout => 1}) or die "unable to start remote shell: " . $t->error;
+    my $telnet = Net::Telnet->new(-fhopen => $pty, -prompt => "/$switch_auth{$device->{vendor_id}}{prompt}/", -telnetmode => 0,-cmd_remove_mode => 1,-output_record_separator => "\r");
+    $telnet->waitfor(-match => $telnet->prompt, -errmode => "return") or die "login failed: " . $telnet->lastline;
+    if (exists $switch_auth{$device->{vendor_id}}{enable}) {
+            $telnet->print($switch_auth{$device->{vendor_id}}{enable});
+            $telnet->print($device->{enable_password});
+            $telnet->waitfor("/$switch_auth{$device->{vendor_id}}{prompt}/");
+            }
+    if (!$telnet_version) { $telnet_version = 1; }
+    eval {
+    foreach my $run_cmd (@tmp) {
+        next if (!$run_cmd);
+        my @ret=();
+        @ret=log_cmd($telnet,$run_cmd) if ($telnet_version == 1);
+        @ret=log_cmd2($telnet,$run_cmd) if ($telnet_version == 2);
+        @ret=log_cmd3($telnet,$run_cmd) if ($telnet_version == 3);
+        @ret=log_cmd4($telnet,$run_cmd) if ($telnet_version == 4);
+        if (scalar @ret) { push(@result,@ret); }
+        select(undef, undef, undef, 0.25);
+        }
+    };
+    $telnet->close;
+    waitpid($pid, 0);
+    if ($@) { log_error("Abort: $@"); return 0; };
+    }
 if ($proto eq 'telnet') {
 if ($proto eq 'telnet') {
-    my @tmp=();
     if (!$telnet_version) { $telnet_version = 1; }
     if (!$telnet_version) { $telnet_version = 1; }
-    if (ref($cmd) eq 'ARRAY') { @tmp = @{$cmd}; } else { push(@tmp,$cmd); }
     eval {
     eval {
     foreach my $run_cmd (@tmp) {
     foreach my $run_cmd (@tmp) {
         next if (!$run_cmd);
         next if (!$run_cmd);
@@ -467,11 +507,8 @@ if ($device->{vendor_id} eq '2') {
 #huawei
 #huawei
 if ($device->{vendor_id} eq '3') {
 if ($device->{vendor_id} eq '3') {
     eval {
     eval {
-        my $session = netdev_login($device);
-        my $cmd = "quit";
-        netdev_cmd($device,$session,$switch_auth{$device->{vendor_id}}{proto},$cmd,3);
-        $cmd = "tftp $tftp_ip put vrpcfg.zip $device->{device_name}.zip";
-        netdev_cmd($device,$session,$switch_auth{$device->{vendor_id}}{proto},$cmd,3);
+        my $cmd = "quit\ntftp $tftp_ip put vrpcfg.zip $device->{device_name}.zip\nSLEEP 5\n";
+        netdev_cmd($device,undef,$switch_auth{$device->{vendor_id}}{proto},$cmd,3);
         };
         };
     }
     }
 
 
@@ -604,7 +641,6 @@ if ($device->{vendor_id} eq '39') {
         netdev_cmd($device,$session,$switch_auth{$device->{vendor_id}}{proto},$cmd,1);
         netdev_cmd($device,$session,$switch_auth{$device->{vendor_id}}{proto},$cmd,1);
         };
         };
     }
     }
-
 }
 }
 
 
 #---------------------------------------------------------------------------------
 #---------------------------------------------------------------------------------

+ 1 - 1
scripts/Rstat/config.pm

@@ -259,7 +259,7 @@ our $last_refresh_config = time();
 
 
 our %switch_auth = (
 our %switch_auth = (
 '8'=>{'vendor'=>'Allied Telesis','enable'=>'en','proto'=>'telnet','port'=>'23','login'=> '(login|User Name):','password'=>'Password:','prompt'=>qr/(\010\013){0,5}(([-\w]+|[-\w(config)+])\#|[-\w]+\>)/},
 '8'=>{'vendor'=>'Allied Telesis','enable'=>'en','proto'=>'telnet','port'=>'23','login'=> '(login|User Name):','password'=>'Password:','prompt'=>qr/(\010\013){0,5}(([-\w]+|[-\w(config)+])\#|[-\w]+\>)/},
-'3'=>{'vendor'=>'Huawei','proto'=>'ssh','port'=>'22','enable'=>'system-view','login'=> 'login as:','password'=>'Password: ','prompt'=>qr/(\<.*\>|\[.*\])/},
+'3'=>{'vendor'=>'Huawei','proto'=>'tssh','port'=>'22','enable'=>'system-view','login'=> 'login as:','password'=>'Password: ','prompt'=>qr/(\<.*\>|\[.*\])/},
 '16'=>{'vendor'=>'Cisco','proto'=>'telnet','port'=>'23','enable'=>'en','login'=> 'Username:','password'=>'Password:','prompt'=>qr/([-\w]+|[-\w(config)+])\#/},
 '16'=>{'vendor'=>'Cisco','proto'=>'telnet','port'=>'23','enable'=>'en','login'=> 'Username:','password'=>'Password:','prompt'=>qr/([-\w]+|[-\w(config)+])\#/},
 '5'=>{'vendor'=>'Raisecom','proto'=>'telnet','port'=>'23','enable'=>'en','login'=> 'Login:','password'=>'Password:','prompt'=>qr/([-\w]+|[-\w(config)+])\#/},
 '5'=>{'vendor'=>'Raisecom','proto'=>'telnet','port'=>'23','enable'=>'en','login'=> 'Login:','password'=>'Password:','prompt'=>qr/([-\w]+|[-\w(config)+])\#/},
 '6'=>{'vendor'=>'SNR','proto'=>'telnet','port'=>'23','login'=> 'login:','password'=>'Password:','prompt'=>qr/([-\w]+|[-\w(config)+])\#/},
 '6'=>{'vendor'=>'SNR','proto'=>'telnet','port'=>'23','login'=> 'login:','password'=>'Password:','prompt'=>qr/([-\w]+|[-\w(config)+])\#/},