AllInfo
Main: Info Blog Temp Mail


unix 2015-07-25 16-36-43

Jabber Shell Bot — теперь поддерживает русский


Есть много видов удаленного администрирования. Многие предпочитают граффику (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/

13.58.84.207 / 2024-12-22_20-31-56 UTC.