2017-12-15 21 views
0

私たちのネットワーク上の300を超える無線デバイスに、POE :: Component :: OpenSSHと各デバイスの別々のPOE :: Sessionを使用して、ノンブロッキングsshを実行しています。私が持っているスクリプトは動作していますが、いくつかのデバイスは正しいパスワードで構成されていません(簡単にするためにすべてのデバイスに同じパスワードを保存していますので、すべてのデバイスに同じパスワードを使用してください)。エンジニアが間違いを犯して、標準以外のsshパスワードでデバイスをインストールすることがあります。この場合、OpenSSHが認証に失敗した場合、POE :: Sessionは停止します(_stopは呼び出されず、スクリプトは終了しません)。私は純粋なプログラム上の問題ではないことを知っています。私たちはネットワーク上に毎日少数のデバイスをインストールしています。私たちはエンジニアに毎回正しいパスワードを入力させることはできません。だから私が私たちの既存のデバイスでパスワードを修正しても、私のプロセスがハングする原因となる間違ったパスワードで今後デバイスを持つことは避けられません。OpenSSH POEセッションが終了しました

私は$ kernel-> stopを行うことができますが、私はそのようにはしません。セッションをクリアしたいと思います。ウォッチャーセッションを使用してセッション内でPOE :: Component :: OpenSSHが使用するリソース/サービスをクリアする方法はありますか?どんな助けもありがとうございます。以下の私のコードを見てください。

use strict; 
use warnings; 
use POE; 
use POE::Component::OpenSSH; 
use POE::Component::Client::Ping; 
use Data::Dumper; 

my $domain = shift; 
my @args = ($domain); 
my $session = POE::Session->create(
     args => \@args, 
     inline_states => { 
       _start => \&start, 
       configcapture => \&configcapture, 
       activecapture => \&activecapture, 
       detectdfs => \&dfs, 
       pong => \&pingresult, 
       handlerror => \&handlerror, 
       _stop => \&stop, 
     }, 
); 

POE::Kernel->run(); 
exit; 

sub start { 
     $_[KERNEL]->sig(DIE => 'sig_DIE'); 
     print "STARTING ... for $_[ARG0] \n"; 
     $_[HEAP]{'domain'} = $domain; 

     my $ssh = POE::Component::OpenSSH->new(
       args => ['[email protected]'.$domain.':6022', passwd => '123' ], 
     ); 

     $ssh->capture({event => 'configcapture', timeout => 2}, 
         'cat /tmp/system.cfg | grep radio.1.freq'); 
     $ssh->capture({event => 'activecapture', timeout => 2}, 
         '/usr/www/status.cgi'); 
     $_[KERNEL]->delay(detectdfs => 5); 
} 

sub configcapture { 
     $_[HEAP]{'configfreq'} = $_[ARG0]{'result'}[0]; 
} 

sub activecapture { 
     $_[HEAP]{'activefreq'} = $_[ARG0]{'result'}[0]; 
} 

sub dfs { 
     if(defined($_[HEAP]{'configfreq'}) && 
      defined($_[HEAP]{'activefreq'})) { 
       print "CONFIG: $_[HEAP]{'configfreq'}\n"; 
       print "ACTIVE: $_[HEAP]{'activefreq'}\n"; 
     } 
} 

sub stop { 
     my ($self, $output) = @_; 
     print "Ending Session Here \n"; 
} 
+0

を間違ったパスワードを使用しているマシンの1台に対抗して、ここに出力を追加します。また、[POE :: Component :: OpenSSH](https://metacpan.org/pod/POE::Component::OpenSSH)を使用する代わりに、[Net :: OpenSSH](https: //metacpan.org/pod/Net::OpenSSH)docs [イベント指向のフレームワークからの使用方法](https://metacpan.org/pod/Net::OpenSSH#AnyEvent-(and-similar-frameworks ))。 – salva

+0

おそらく、 'timeout'と' kill_ssh_on_timeout'引数をNet :: OpenSSH 'args'に渡すことができますか? – NetMage

答えて

0

ありがとうございます。解決策を自分で見つけました。 POE :: Component :: OpenSSHを構築するときに、すべてのセッションに対して_stopイベントを呼び出すように、timeoutを追加する必要がありました。しかし、スクリプトはまだ終了していませんでした。

POE :: Component :: OpenSSHはPOE :: Component :: Genericを使用してPOEセッションとしてNet :: OpenSSHプロセスをブロックするため、POE :: Component :: Genericのメソッドをshutdown opensshコンポーネントオブジェクトが間違ったパスワード(何か間違っているかどうかなど)を確認し、すべてのセッションがきれいに終了し、スクリプトが終了しました。

以下のソリューションを参照してください。

$_[HEAP]{'ssh'} = POE::Component::OpenSSH->new(
       args => [[email protected], passwd => '123', timeout => 180, async => 1, master_opts => [-o => "StrictHostKeyChecking=no"]], 
     ); 

、その後、 `$ネット:: OpenSSHの::デバッグ= -1`スクリプトの先頭に、実行設定し_stopで

my ($kernel, $session, $heap) = @_[KERNEL, SESSION, HEAP]; 
delete $heap->{wheel}; 
$kernel->alias_remove($heap->{alias}); 
$kernel->alarm_remove_all(); 
$_[HEAP]{'ssh'}->object->shutdown; 
delete($_[HEAP]{'ssh'}); 
関連する問題