Zabbix оповещения на jabber

Сейчас будем разбираться с оповещениями zabbix на jabber. В ранних статьях мы уже устанавливали jabber сервер Openfire и будем использовать его на примере.

Для начала, в opebfire необходимо создать пользователя для zabbix сервера с которого будем отправлять сообщения и добавляем его в группу.

С коробки zabbix я не смог отправлять оповещения, поэтому будем использовать скрипт.

создаем файл jabber в /etc/zabbix/alert.d:

nano /etc/zabbix/alert.d/jabber
#!/usr/bin/perl

use common::sense;
use Net::XMPP;

use constant {
SERVER => 'jabber.domain.ru',
PORT => 5222,
USER => 'server',
PASSWORD => 'password',
RESOURCE => 'company',
TLS => 0,
DEBUG => 0,
};

$0 =~ s{.*/}{};
my ($to, $subj, $body, $type) = @ARGV;
$type ||= 'headline';

die << "EOF" unless @ARGV == 3 or @ARGV == 4;
Usage: $0 <jid> <subject> <body> [type]
EOF

utf8::decode($subj);
utf8::decode($body);

my $bot = new Net::XMPP::Client( debuglevel => DEBUG );

$bot->SetCallBacks(
    onconnect => sub{},
        onauth => sub{
        $bot->PresenceSend;
        $bot->MessageSend( to => $to, subject => $subj, body => $body, type => $type );
        $bot->Disconnect();
        },
            ondisconnect => sub{}
            );
            $bot->Execute(
            hostname => SERVER,
            port => PORT,
            tls => TLS,
            username => USER,
            password => PASSWORD,
            resource => RESOURCE,
            register => 0,
            connectiontype => 'tcpip'
            );

Делаем его запускающимся:

chmod +x /etc/zabbix/alert.d/jabber
cd /etc/zabbix/alert.d

Пробуем запустить:

./jabber

Получаем вот такую ошибку, а все из-за того что скрипт использует модули perl common::sense; Net::XMPP;

Can't locate common/sense.pm in @INC (@INC contains: /etc/perl /usr/local/lib/perl/5.10.1 /usr/local/share/perl/5.10.1 /usr/lib/perl5 /usr/share/perl5 /usr/lib/perl/5.10 /usr/share/perl/5.10 /usr/local/lib/site_perl .) at ./jabber line 3.
BEGIN failed--compilation aborted at ./jabber line 3.

perl -MCPAN -e 'install +common::sense'
perl -MCPAN -e 'install +Net::XMPP'

Пробуем отправить сообщение с помощью скрипта:

./jabber admin@domain.ru test test

сообщения также не доходят (тишина).

Добавлено из комментарий (спасибо Андрею):

Необходимо найти и закомментировать строку в

/usr/local/share/perl/5.14.2/Net/XMPP/Protocol.pm

return $self->AuthSASL (%args);

Кстати, в скрипте можно включить debug для просмотра где у нас ошибка:

DEBUG => 1,

Так же смотрим логи openfire в /var/log/openfire/warn.log

Важный момент:

Если у вас Openfire заведен на поддомене, например jabber.domain.ru, то и отправлять сообщения пользователю нужно с указанием с доменом третьего уровня:

./jabber admin@jabber.domain.ru test test

Теперь остается в Вебморде zabbix добавить скрипт:

Администрирование -> Типы средств передачи -> Jabber — где Тип: выбрать Сценарий, Название скрипта — jabber

 

Комментарии (16) - “Zabbix оповещения на jabber

  1. Андрей

    Спасибо за статью.

    В процессе настройки столкнулся с ошибкой XMPP::Conn: AuthSASL: Authentication failed.

    Нашел решение вот здесь community.igniterealtime.org/thread/20551

    This is a known problem.

    At the moment the best you can do is comment out line 1772 in Net/XMPP/Protocol.pm.

    The line:

    return $self->AuthSASL (%args);

    becomes

    return $self->AuthSASL (%args);

    Not pretty but it works.

    Номер строки отличается от описанной в форуме так, что нужно искать строку return $self->AuthSASL (%args); и просто ремить после чего все заработало

    Может кому пригодится в процессе настройки.

  2. magomed

    Добрый день! как в openfire включить sasl аутетнтификацию? а то из за этого у меня некоторые клиенты не подключаются и с заббикса письма не уходят

  3. chezeer

    @magomed

    Советую смотреть логи openfire и смотреть что показывает при подключении:

    # tail -f /var/log/openfire/warn.log

    Возможно, что это та же ошибка, что комментарием выше...

  4. magomed

    извеняюсь что так долго не отвечал... у меня заработало без скрипта... на стороннем сервере где openfire установлен небыл включен sasl... но теперь другая проблема... письма приходят, но содержание непонятное... инфо что коммутатор выключен или включен нет в содержании. как то можно ее исправить

  5. Zuasit

    Спасибо! Очень полезная статья. Но у меня возникла проблема со скриптом. При отправке сообщений из zabbix'a на 4 разичных аккаунта сообщения доходили не всем. В процессе тестирования обнаружилось, что если отправлять из командной строки друг за другом сообщения, часть из них не доходит. Также не доходят сообщения если клиент оффлайн... Может, кто-нибудь сталкивался с такой проблемой?

    {{Hider|Лог отправки, если клиент оффлайн

    XML::Stream: new: hostname = (openfire)

    XML::Stream: SetCallBacks: tag (node) func (CODE (0x204ef18))

    XMPP::Conn: xmppCallbackInit: start

    XMPP::Conn: SetCallBacks: tag (message) func (CODE (0×2369850))

    XMPP::Conn: SetCallBacks: tag (presence) func (CODE (0x2364fb8))

    XMPP::Conn: SetCallBacks: tag (iq) func (CODE (0x2364e08))

    XMPP::Conn: SetPresenceCallBacks: type (subscribe) func (CODE (0x2364fe8))

    XMPP::Conn: SetPresenceCallBacks: type (subscribed) func (CODE (0x2369d90))

    XMPP::Conn: SetPresenceCallBacks: type (unsubscribe) func (CODE (0x2369c10))

    XMPP::Conn: SetPresenceCallBacks: type (unsubscribed) func (CODE (0x2369f10))

    XMPP::Conn: SetDirectXPathCallBacks: xpath (/[@xmlns="urn:ietf:params:xml:ns:xmpp-tls"]) func (CODE (0x2369dc0))

    XMPP::Conn: SetDirectXPathCallBacks: xpath (/[@xmlns="urn:ietf:params:xml:ns:xmpp-sasl"]) func (CODE (0x236a180))

    XMPP::Conn: xmppCallbackInit: stop

    XMPP::Conn: SetCallBacks: tag (ondisconnect) func (CODE (0x23a5f68))

    XMPP::Conn: SetCallBacks: tag (onauth) func (CODE (0x236a780))

    XMPP::Conn: SetCallBacks: tag (onconnect) func (CODE (0×2318740))

    XMPP::Conn: Execute: begin

    XMPP::Conn: Execute: Attempt to connect (-1)

    XMPP::Conn: Connect: host (server:5222) namespace (jabber:client)

    XMPP::Conn: Connect: timeout (10)

    XML::Stream: Connect: type (tcpip)

    XML::Stream: Connect: Got a connection

    XML::Stream: Send: ()

    XML::Stream: Read: buff (PLAINANONYMOUSzlib)

    XMPP::Conn: Connect: connection made

    XML::Stream: SetCallBacks: tag (node) func (CODE (0×2370258))

    XMPP::Conn: Execute: Connected...

    XMPP::Conn: AuthSASL: shiney new auth

    XML::Stream: Send: (emFiYml4QGJhbmstcGVyZXN2ZXQucnUAemFiYml4ADEyMw==)

    XMPP::Conn: AuthSASL: haven't authed yet... let's wait.

    XMPP::Conn: Process: timeout (1)

    XML::Stream: Read: buff ()

    XMPP::Conn: AuthSASL: We authed!

    XML::Stream: Send: ()

    XML::Stream: Read: buff (zlib)

    XMPP::Conn: AuthSASL: We got a new session. sid (b74d0583)

    XMPP::Conn: AuthSASL: Binding to resource

    XMPP::Conn: SendAndReceiveWithID: object (Net::XMPP::IQ=HASH (0x23522d8))

    XMPP::Conn: SendWithID: id (netjabber-0)

    XMPP::Conn: SendWithID: in (script)

    XMPP::Conn: RegisterID: tag (iq) id (netjabber-0)

    XMPP::Conn: SendWithID: out (script)

    XMPP::Conn: SendXML: sent (script)

    XML::Stream: Send: (script)

    XMPP::Conn: SendAndReceiveWithID: sent with id (netjabber-0)

    XMPP::Conn: WaitForID: id (netjabber-0)

    XMPP::Conn: ReceivedID: id (netjabber-0)

    XMPP::Conn: ReceivedID: nope...

    XMPP::Conn: WaitForID: haven't gotten it yet... let's wait for more packets

    XMPP::Conn: Process: timeout (1)

    XML::Stream: Read: buff (zabbix@server/script)

    XMPP::Conn: CallBack: sid (b74d0583) received (zabbix@server/script)

    XMPP::Conn: CallBack: tag (iq)

    XMPP::Conn: CallBack: id (netjabber-0)

    XMPP::Conn: CallBack: we either want it or were waiting for it.

    XMPP::Conn: CallBack: check directxpath

    XMPP::Conn: CallBack: check directxpath (/[@xmlns="urn:ietf:params:xml:ns:xmpp-sasl"])

    XMPP::Conn: CallBack: check directxpath (/[@xmlns="urn:ietf:params:xml:ns:xmpp-tls"])

    XMPP::Conn: BuildObject: tag (iq) package (Net::XMPP::IQ)

    XMPP::Conn: CheckID: tag (iq) id (netjabber-0)

    XMPP::Conn: CheckID: we have that here somewhere...

    XMPP::Conn: CallBack: found registry entry: tag (iq) id (netjabber-0)

    XMPP::Conn: DeregisterID: tag (iq) id (netjabber-0)

    XMPP::Conn: CallBack: they still want it... we still got it...

    XMPP::Conn: GotID: id (netjabber-0) xml (zabbix@server.ru/script)

    XMPP::Conn: ReceivedID: id (netjabber-0)

    XMPP::Conn: ReceivedID: id (netjabber-0)

    XMPP::Conn: WaitForID: we got it!

    XMPP::Conn: GetID: id (netjabber-0)

    XMPP::Conn: ReceivedID: id (netjabber-0)

    XMPP::Conn: CleanID: id (netjabber-0)

    XMPP::Conn: AuthSASL: Starting session

    XMPP::Conn: SendAndReceiveWithID: object (Net::XMPP::IQ=HASH (0x1db2b20))

    XMPP::Conn: SendWithID: id (netjabber-1)

    XMPP::Conn: SendWithID: in ()

    XMPP::Conn: RegisterID: tag (iq) id (netjabber-1)

    XMPP::Conn: SendWithID: out ()

    XMPP::Conn: SendXML: sent ()

    XML::Stream: Send: ()

    XMPP::Conn: SendAndReceiveWithID: sent with id (netjabber-1)

    XMPP::Conn: WaitForID: id (netjabber-1)

    XMPP::Conn: ReceivedID: id (netjabber-1)

    XMPP::Conn: ReceivedID: nope...

    XMPP::Conn: WaitForID: haven't gotten it yet... let's wait for more packets

    XMPP::Conn: Process: timeout (1)

    XML::Stream: Read: buff ()

    XMPP::Conn: CallBack: sid (b74d0583) received ()

    XMPP::Conn: CallBack: tag (iq)

    XMPP::Conn: CallBack: id (netjabber-1)

    XMPP::Conn: CallBack: we either want it or were waiting for it.

    XMPP::Conn: CallBack: check directxpath

    XMPP::Conn: CallBack: check directxpath (/[@xmlns="urn:ietf:params:xml:ns:xmpp-sasl"])

    XMPP::Conn: CallBack: check directxpath (/[@xmlns="urn:ietf:params:xml:ns:xmpp-tls"])

    XMPP::Conn: BuildObject: tag (iq) package (Net::XMPP::IQ)

    XMPP::Conn: CheckID: tag (iq) id (netjabber-1)

    XMPP::Conn: CheckID: we have that here somewhere...

    XMPP::Conn: CallBack: found registry entry: tag (iq) id (netjabber-1)

    XMPP::Conn: DeregisterID: tag (iq) id (netjabber-1)

    XMPP::Conn: CallBack: they still want it... we still got it...

    XMPP::Conn: GotID: id (netjabber-1) xml ()

    XMPP::Conn: ReceivedID: id (netjabber-1)

    XMPP::Conn: ReceivedID: id (netjabber-1)

    XMPP::Conn: WaitForID: we got it!

    XMPP::Conn: GetID: id (netjabber-1)

    XMPP::Conn: ReceivedID: id (netjabber-1)

    XMPP::Conn: CleanID: id (netjabber-1)

    XMPP::Conn: SendXML: sent ()

    XML::Stream: Send: ()

    XMPP::Conn: SendXML: sent (88123)

    XML::Stream: Send: (88123)

    XML::Stream: Send: ()

    XML::Stream: SetCallBacks: tag (node) func (CODE (0x237b838))

    XMPP::Conn: Disconnect: bye bye

    XMPP::Conn: Connected: (0)

    XMPP::Conn: Execute: end

    }}

    В сущности, он такой же, как и если клиент онлайн, но привожу на всякий случай...

  6. Zuasit

    Если у кого была такая же проблема, то все решается просто: сообщению по-умолчанию делается тип «chat» и еще нужна задержка между выполнением команд. Вот мой код:

    #!/usr/bin/perl

    use common::sense;

    use Net::XMPP;

    use constant {

    SERVER => 'server',

    PORT => 5222,

    USER => 'zabbix',

    PASSWORD => 'pass',

    RESOURCE => 'script',

    TLS => 0,

    DEBUG => 1,

    };

    my $lock_file = './.lock';

    # Ждем отсутствия файла lock

    while (-f $lock_file)

    {

    sleep (10);

    }

    #Создаем lock файл

    open (FILE, «> $lock_file»);

    close (FILE);

    $0 =~ s{.*/}{};

    my ($to, $subj, $body, $type) = @ARGV;

    $type ||= 'chat';

    #Если косяк в аргументах lock все равно удаляем

    unless (@ARGV == 3 or @ARGV == 4)

    {

    unlink $lock_file;

    }

    die << "EOF" unless @ARGV == 3 or @ARGV == 4;

    Usage: $0 [type]

    EOF

    utf8::decode ($subj);

    utf8::decode ($body);

    my $bot = new Net::XMPP::Client ( debuglevel => DEBUG, debugfile =>"/usr/local/share/zabbix/alertscripts/jabber_log.log");

    $bot->SetCallBacks (

    onconnect => sub{},

    onauth => sub{

    $bot->PresenceSend;

    $bot->MessageSend ( to => $to, subject => $subj, body => $body, type => $type );

    $bot->Disconnect ();

    },

    ondisconnect => sub{}

    );

    $bot->Execute (

    hostname => SERVER,

    port => PORT,

    tls => TLS,

    username => USER,

    password => PASSWORD,

    resource => RESOURCE,

    register => 0,

    connectiontype => 'tcpip'

    );

    sleep (10);

    #Удаляем lock файл

    unlink $lock_file;

  7. Дмитрий

    Если использовать готовый дистр zabbix на базе SuSE, то в нем отсутствует make и perl -MCPAN -e 'install +common::sense' не завершится.

    Выполняем yast -i make и продолжаем...

  8. Валера

    А как из скрипта отправить сообщение в конференцию?

    Если просто указать в качестве получателя адрес конференции — не канает.

  9. Pride

    Использую готовое решние Zabbix 3.0, возникла проблема при подключении модулей, т.е. они просто ни в какую не ставятся, хотя на обычной машине все норм

    • Alex

      Zabbix 3.0.0alpha5

      Скрипт устанавливается нормально

      Тестовый запуск /usr/local/share/zabbix/alertscripts/jabber user@openfire test test срабатывает нормально, сообщение приходит

      Zabbix пишет что отправил сообщение

      Но я сообщений не вижу в jabber-клиенте (spark)

        • titan

          Нашлось. При добавлении «способа оповещений» в zabbix указываем 3 параметра запуска отдельно

          • Alex

            Разобрался. Начиная с 3.0 версии в параметрах нужно использовать макросы {ALERT.SENDTO}, {ALERT.SUBJECT} {ALERT.MESSAGE}, вместо старых $1 $2 $3.

            Заработало!

  10. Alec

    Еще добавлю. На голой системе нет модулей perl common::sense; Net::XMP.

    Порядок установки:

    sudo apt-get install perl build-essential libssl-dev

    sudo perl -MCPAN -e 'install O::Socket::SSL'

    sudo perl -MCPAN -e 'install Net::SSLeay'

    sudo perl -MCPAN -e 'install common::sense'

    sudo perl -MCPAN -e 'install Net::XMPP'

  11. Vladimir

    после запуска скрипта не приходит сообщение в дэбаге постоянно пишет

    XMPP::Conn: SendAndReceiveWithID: sent with id (netjabber-0)

    XMPP::Conn: WaitForID: id (netjabber-0)

    XMPP::Conn: ReceivedID: id (netjabber-0)

    XMPP::Conn: ReceivedID: nope...

    XMPP::Conn: WaitForID: haven't gotten it yet... let's wait for more packets

    XMPP::Conn: Process: timeout (1)

Оставить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

This blog is kept spam free by WP-SpamFree.