Ad Widget

Collapse

Zabbix+Perl_script+SSH

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • rick_rian
    Junior Member
    • Jul 2014
    • 14

    #1

    Zabbix+Perl_script+SSH

    Приветствую!
    Хочу провернуть схему опроса удаленных устройств на предмет наличия конкретного usb-устройства.
    Делаю так - написал на Perl скрипт:

    #!/usr/bin/perl
    use strict;
    use Net::SSH::Perl;
    my $hostname = $ARGV[0];
    my $username = $ARGV[1];
    my $password = $ARGV[2];
    my $cmd = "lsusb | grep -e 'имя_железки'";
    my $ssh = Net::SSH::Perl->new("$hostname", debug=>0);
    $ssh->login("$username","$password");
    #my ($stdout,$stderr,$exit) = $ssh->cmd("$cmd");
    #print "$stdout";

    он работает.
    Далее помещаю его в папку для внешних скриптов zabbix.
    Создаю в zabbix шаблон с item как внешнюю проверку:
    имя_скрипта.pl[{$HOSTNAME},{$LOGIN},{$PASS}]
    Далее создаю хост, в котором прописываю макросы.
    Короче говоря не работает на этапе
    $ssh->login("$username","$password");
    Если до этой строчки написать, например print "$hostname"; и закомментить все остальное, то это отработает и в latest data это значение появится.
    Не могу понять, почему ssh не исполняется.
    Ошибок zabbix не пишет, но и данных не поступает.
    Посмотрите свежим глазом, пожалуйста, я что-то уже и не знаю, где копнуть.
  • Jimson
    Senior Member
    • Jan 2008
    • 1327

    #2
    Выведете $ssh вместо $hostname перед логином, подозреваю что там окажется undef.
    И в не зависимости от того что вы получите в $ssh, каким бы небольшим не был скрипт, я бы добавил в него и верификацию параметров и проверки того что бы получаете в $ssh и того как прошел логин, при этом критические ошибки логировал бы через Unix::Syslog.
    Last edited by Jimson; 22-07-2014, 09:54.

    Comment

    • Zentarim
      Senior Member
      • Mar 2012
      • 526

      #3
      Originally posted by rick_rian
      Приветствую!
      Хочу провернуть схему опроса удаленных устройств на предмет наличия конкретного usb-устройства.
      Делаю так - написал на Perl скрипт:

      #!/usr/bin/perl
      use strict;
      use Net::SSH::Perl;
      my $hostname = $ARGV[0];
      my $username = $ARGV[1];
      my $password = $ARGV[2];
      my $cmd = "lsusb | grep -e 'имя_железки'";
      my $ssh = Net::SSH::Perl->new("$hostname", debug=>0);
      $ssh->login("$username","$password");
      #my ($stdout,$stderr,$exit) = $ssh->cmd("$cmd");
      #print "$stdout";

      он работает.
      Далее помещаю его в папку для внешних скриптов zabbix.
      Создаю в zabbix шаблон с item как внешнюю проверку:
      имя_скрипта.pl[{$HOSTNAME},{$LOGIN},{$PASS}]
      Далее создаю хост, в котором прописываю макросы.
      Короче говоря не работает на этапе
      $ssh->login("$username","$password");
      Если до этой строчки написать, например print "$hostname"; и закомментить все остальное, то это отработает и в latest data это значение появится.
      Не могу понять, почему ssh не исполняется.
      Ошибок zabbix не пишет, но и данных не поступает.
      Посмотрите свежим глазом, пожалуйста, я что-то уже и не знаю, где копнуть.
      stderr скрипта выведите куда-нибудь в файл и изучите. Вероятнее всего вам скажут - что неверно.
      Выполните скрипт через sudo -u zabbix. Возможно у вас что-то с правами, или пользователю zabbix недоступен модуль Net::SSH::Perl.

      Мое предположение состоит в том, что при выполнении скрипта от имени агента неправильно задается массив @INC (содержит не все пути поиска модулей). Вам надо сравнить @INC при выполнении скрипта из-под sudo и @INC при выполнении скрипта из-под агента.

      Comment

      • yukra
        Senior Member
        • Apr 2013
        • 1359

        #4
        Про таймаут не забудьте, по умолчанию он всего 3 секунды.

        Comment

        • Jimson
          Senior Member
          • Jan 2008
          • 1327

          #5
          Если следовать принципу что правильное решение всегда самое простое, то дело как раз в таймауте Как то не подумалось сразу про эти грабли.

          Comment

          • rick_rian
            Junior Member
            • Jul 2014
            • 14

            #6
            Всем спасибо за ответы, решить пока не удается.
            Что сделал:
            Увеличил таймаут до 20сек, не помогло.
            Выставил права на модули, не помогло, но от zabbix скрипт исполняется нормально.
            Далее вывел переменную $ssh, получил такое: Net::SSH::Perl::SSH2=HASH(0x159eba0)

            Что еще можно посмотреть? Я, к сожалению, не ахти какой линуксоид, поэтому буду рад подробным ответам.
            Кстати меня еще смущает то, что у пользователя zabbix нет домашней папки, и когда заходишь под ним, то не работает история команд. Это нормальное поведение или это стоит поправить?

            ПС. Еще добавил такой параметр
            strict_host_key_checking no
            в строчку
            my $ssh = Net::SSH::Perl->new("$hostname", debug=>0 , options=> ["strict_host_key_checking no"]);
            тоже не помогло.
            Last edited by rick_rian; 23-07-2014, 08:33.

            Comment

            • Zentarim
              Senior Member
              • Mar 2012
              • 526

              #7
              В посте выше я указывал вам вывести stderr в отдельный файл, а затем изучить то, что туда насыплется. Попробуйте это сделать.

              Comment

              • Jimson
                Senior Member
                • Jan 2008
                • 1327

                #8
                добавляйте
                open(LOG, '>>', '/var/tmp/myssh_debug.log');
                и затем print LOG "..." вставляйте "отладку" после каждой строки
                что бы добавить время в вывод man POSIX, man strftime, perldoc -f localtime
                или
                use Unix::Syslog qw(:subs :macros);
                openlog('mysshscript', LOG_PID, LOG_LOCAL0);
                и вместо принта syslog(LOG_WARNING, "message");

                P.S. Cудя по коду метод login() вообще ничего не делает, он только сохраняет аргументы (username, password, suppress_shell). И еще проверьте что бы на сервере куда вы конектитесь в sshd был выключен dns-checking (man sshd_config, UseDNS) либо удостоверьтесь что и сервер и компьютер с которого вы конектитесь имеют валидный прямой и обратный резолвинг).

                add. у Net::SSH:Perl есть отладка на сколько я вижу в описании, метод debug(). Что бы вывести STDERR нужно его переоткрыть: close(STDERR); open(STDERR, '>>', '/var/tmp/myssh_stderr.log'); в начале скрипта.
                Last edited by Jimson; 23-07-2014, 09:11.

                Comment

                • Zentarim
                  Senior Member
                  • Mar 2012
                  • 526

                  #9
                  Originally posted by Jimson
                  add. у Net::SSH:Perl есть отладка на сколько я вижу в описании, метод debug(). Что бы вывести STDERR нужно его переоткрыть: close(STDERR); open(STDERR, '>>', '/var/tmp/myssh_stderr.log'); в начале скрипта.
                  А не проще прямо вот так и записать в UserParameter:

                  Code:
                  ./perl.plx > /tmp/err.log 2&>1

                  Comment

                  • Jimson
                    Senior Member
                    • Jan 2008
                    • 1327

                    #10
                    Originally posted by Zentarim
                    А не проще прямо вот так и записать в UserParameter:
                    Нет. Во первых это внешняя проверка, а не UserParamater. Во вторых многострочную ругань zabbix просто не покажет, в случае с UserParamater надо тогда перенаправлять в файл, а не в stdout.

                    P.S. Еще не забывайте что использование глобов и перенаправлений приведет к неявному запуску шелла, в случае если запускается бинарь это меняет условия теста.

                    Comment

                    • aib
                      Senior Member
                      • Jan 2014
                      • 1615

                      #11
                      Извините, что вмешиваюсь - но вы не пробовали использовать тип проверки SSH agent?

                      Там все работает так, как вам надо: задается имя-пароль, можно использовать скрипты...
                      Sincerely yours,
                      Aleksey

                      Comment

                      • Egor4ik
                        Member
                        • May 2012
                        • 68

                        #12
                        Originally posted by rick_rian
                        Всем спасибо за ответы, решить пока не удается.
                        Что сделал:
                        Увеличил таймаут до 20сек, не помогло.
                        Выставил права на модули, не помогло, но от zabbix скрипт исполняется нормально.
                        Далее вывел переменную $ssh, получил такое: Net::SSH::Perl::SSH2=HASH(0x159eba0)

                        Что еще можно посмотреть? Я, к сожалению, не ахти какой линуксоид, поэтому буду рад подробным ответам.
                        Кстати меня еще смущает то, что у пользователя zabbix нет домашней папки, и когда заходишь под ним, то не работает история команд. Это нормальное поведение или это стоит поправить?

                        ПС. Еще добавил такой параметр
                        strict_host_key_checking no
                        в строчку
                        my $ssh = Net::SSH::Perl->new("$hostname", debug=>0 , options=> ["strict_host_key_checking no"]);
                        тоже не помогло.
                        Полуфабрикат:

                        Code:
                        # apt-get install libnet-ssh2-perl
                        Code:
                        #!/usr/bin/perl
                        
                        use strict;
                        use Net::SSH2;
                        
                        my $hostname = shift || "localhost";
                        my $username = shift || "zabbix";
                        my $password = shift || "someharddefaultpassword";
                        my $device = shift || "046d:c52f";
                        
                        my $cmd = "/usr/sbin/lsusb |grep \"$device\"";
                        my $ssh2 = Net::SSH2->new();
                        $ssh2->connect($hostname) or die "Unable to connect Host $@ \n";
                        $ssh2->auth_password($username,$password) or die "Unable to login $@ \n";
                        my $chan1 = $ssh2->channel();
                        $chan1->exec($cmd);
                        
                        while (<$chan1>){
                         print $_;
                        }
                        root@zabbix-office:/tmp# ./perl.plx 172.27.102.140 testlogin MyP@SS "046d:c52f"
                        Bus 002 Device 002: ID 046d:c52f Logitech, Inc. Wireless Mouse M305

                        Comment

                        • rick_rian
                          Junior Member
                          • Jul 2014
                          • 14

                          #13
                          Egor4ik, скрипт, написанный вами, у меня ничего не выдает даже от root.
                          aib, у меня вроде скомпилировано без поддержки таких проверок.
                          Zentarim, Jimson, я вывел stderr в отдельный лог, увидел там такое:

                          Code:
                          mkdir /root/.ssh: Permission denied at /etc/perl/Net/SSH/Perl/Util/Hosts.pm line 92
                          Как я понимаю, модуль Hosts.pm пытается создать папку /root/.ssh и у него это не выходит. Что означает эта операция, для чего это делается и как лучше поправить?

                          Кстати, я наврал, от zabbix из консоли скрипт не исполняется (что и подтверждается выводом stderr), я, видимо, не туда глянул.
                          Last edited by rick_rian; 24-07-2014, 02:56.

                          Comment

                          • Jimson
                            Senior Member
                            • Jan 2008
                            • 1327

                            #14
                            Originally posted by rick_rian
                            Как я понимаю, модуль Hosts.pm пытается создать папку /root/.ssh и у него это не выходит. Что означает эта операция, для чего это делается и как лучше поправить?
                            Это означает две вещи
                            1) скрипту нужен home dir где он, как и обычный ssh клиент хочет создать .ssh/ и поискать там всякие authorized* known_hosts и тп.
                            2) либо вы пользователю (zabbix?) указали /root в качестве home dir, либо выходит так что у вас скрипт запускается под UID рута, а EUID не рутовый, поэтому он лезет в /root

                            P.S. Какой то мутный модуль вы выбрали для работы через SSH, втихую создавать каталоги это по меньшей мере дряно.

                            Comment

                            • Egor4ik
                              Member
                              • May 2012
                              • 68

                              #15
                              Originally posted by rick_rian
                              Egor4ik, скрипт, написанный вами, у меня ничего не выдает даже от root.
                              aib, у меня вроде скомпилировано без поддержки таких проверок.
                              Zentarim, Jimson, я вывел stderr в отдельный лог, увидел там такое:

                              Code:
                              mkdir /root/.ssh: Permission denied at /etc/perl/Net/SSH/Perl/Util/Hosts.pm line 92
                              Как я понимаю, модуль Hosts.pm пытается создать папку /root/.ssh и у него это не выходит. Что означает эта операция, для чего это делается и как лучше поправить?

                              Кстати, я наврал, от zabbix из консоли скрипт не исполняется (что и подтверждается выводом stderr), я, видимо, не туда глянул.
                              Похоже что тема уходит в сторону програмирования на Perl.

                              В вашем случае: скрипты агента запускаются от имени zabbix пользователя, у zabbix пользователя нету домашней папки, немного не ясно почему он пытается использовать /root/.ssh для обновления файла known_hosts.

                              попробуйте:
                              my $ssh = Net::SSH::Perl->new(
                              "$hostname",
                              debug=>0 ,
                              options=> ["strict_host_key_checking no", "UserKnownHostsFile /dev/null"]
                              );

                              Comment

                              Working...