Блог заядлого линуксоида

Противостояние opensource

Jabber Shell Bot – теперь поддерживает русский Январь 12, 2010

Filed under: Bash scripts,Utilities — pomatu @ 20:13
Tags: , , ,

Есть много видов удаленного администрирования. Многие предпочитают граффику (vnc, rdp), многие старую добрую тру-консоль (sshd, telnetd). Но а если все эти навороченные сервера удаленного управления упали? Ничего не работает, никак не поднять, а файлы получить срочно нужно. Тогда спасает jabber shell bot. Казалось бы что за ненужная вещь по сравнению с теме ssh? Да вот только именно через него бородатые сисадмины зачастую и перезапускают ssh.

Теперь к делу:

jabber shell bot требует устанновленного perl’а.

Устанавливаем perl:

pacman -Sy perl

Скрипт требует библиотеки  Net::XMPP, Net::Jabber, utf8 и Encode. Устанавливаем их через cpan:

cpan

install Net::XMPP

install Net::Jabber

install utf8

install Encode

Вот сам скрипт: http://dpaste.org/E9np/

#!/usr/bin/perl
use strict;
use warnings;
use diagnostics;
use Net::XMPP;
use Net::Jabber;
use utf8;
use Encode;
# Список файлов конфигурации для перебора
my @configs = (
$ENV{'HOME'}.'/.jabber-shell', # Пользовательский файл конфигурации
'/etc/jabber-shell.conf', # Системный конфиг
);
# Хэш для хранения настроек
my %settings;
# Перебираем все файлы конфигурации
foreach my $config (@configs) {
# Если файл существует и доступен для чтения
if ( ( -e $config ) && ( -r $config) ) {
# Читаем конфигурацию
open(CONFIG, '<'.$config);
local $/ = undef;
my $config_data = <CONFIG>;
close(CONFIG);
%settings = eval($config_data);
# Выходим из цикла
last;
}
}
# Если не удалось прочитать настройки - завершаем работу
if (!%settings) {
die("Can't read settings!");
}
# Массив, в котором будут JID админов
my @admins = split(' ', $settings{'admins'});
# Определяем основные перменные
my $client = new Net::Jabber::Client();
my $presense = Net::Jabber::Presence->new();
# Определяем обработчики событий
$client->SetCallBacks(
'message' => \&on_message,
);
# Подключаемся к сети
# TODO: Обрабатывать ошибки подключения
$client->Connect(
'hostname' => $settings{'server'},
'port' => $settings{'port'},
);
my @connect = $client->AuthSend(
'username' => $settings{'username'},
'password' => $settings{'password'},
'resource' => $settings{'resource'},
);
# Устанавливаем статус
$presense->SetType("available");
$presense->SetStatus("");
$client->Send($presense);
# Функция обработки команд
sub process_command {
my $command = shift;
my $message = '';
# Если команда cd - пытаемся сменить директорию
if ($command =~ s/^cd([ ]+)//) {
if (chdir($command)) {
$message = 'Directory changed';
}
else {
$message = 'Directory NOT changed';
}
}
# Если какая-то другая - выполняем её и возвращаем результат
else {
# open(COMMAND, $command." 2>&1 |");
# local $/ = undef;
# $message = <COMMAND>;
# close(COMMAND);
$message = `$command 2>&1`;
$message = decode('utf-8', $message);
}
return $message;
}
# Функция обработки сообщений
sub on_message {
my $mid = shift || return;
my $msg = shift || return;
# Команда, которую будем выполнять
my $command = $msg->GetBody;
# Получаем JID отправителя
my $jid = new Net::XMPP::JID($msg->GetFrom)->GetJID("base");
# Перебираем админов
foreach my $admin (@admins) {
# Если сообщение от одного из них
if ($jid eq $admin) {
# Обрабатываем сообщение и посылаем ответ
my $reply = Net::Jabber::Message->new();
$reply->SetMessage(
'to' => $msg->GetFrom,
'body' => process_command($command),
);
$client->Send($reply);
}
}
}
# Цикл обработки сообщений
while (defined($client->Process)) {
}
# На всякий случай закрываем соединение
$client->Disconnect();

Скрипт настроен на работу с русским языком. Единственная проблемма, что он валится при любых бинарных символах, например: fl.

Конфиг для него должен находиться в пути /etc/jabber-shell.conf и выглядеть так: http://dpaste.org/z1Fu/

(
‘server’   => ‘jabber.org’,       # Сервер для бота
‘port’     => ’5222′,            # Порт сервера для бота
‘username’ => ‘username’,    # Имя пользователя на сервере
‘password’ => ‘password’,          # Пароль аккаунта бота
‘resource’ => ‘jabber-shell’,    # Ресур бота
‘admins’   => ‘pomatu@jabber.org’, # JID админов
)

Бот заканчивает работу, при первом вылете или дисконнекте, поэтому лучше сделать скрипт такого вида:

#!/bin/bash

while true

do

perl /path/to/perl/file/that/is/written/upper.pl

done

Согласен – это извращенно. Зато практично :)

Оффициальный сайт бота (без поддержки русского): http://jabber-shell.ylsoftware.com/

Вот и все на сегодня. Спасибо за чтение. Если вам понравилась статья – прошу оставить коментарий :)

 

 
Follow

Get every new post delivered to your Inbox.