4 марта 2011 в 13:26

Управляем сервером посредством СМС

Началось все с того, что я откопал в полке с железками USB модем huaweiE1550, купленный мной прошлым летом для организации резервного канала Интернет. Проработал он тогда недолго и за ненадобностью был убран в «закрома» до лучших времен. Первое что сделал, разлочил его для работы с МТС (так уж сложилось исторически, что я предпочитаю именно этого оператора). Изначально в голову пришла идея отправки смс с предупреждениями от Nagios, вместо почты. Бегло пробежавшись по Интернетам, наткнулся на smsd демона для отправки/приемки смс-ок из пакета smstools. После прочтения документации по этому зверю, в голову пришла идея о том, что можно принимать сообщения с нужных телефонов, с командами для сервера. Так и родилась идея «Управлять сервером посредством СМС», которая может применяться для чего угодно: перезагрузить сервер, выключить его, перезапустить демона, сбросить кеш, открыть порт на фаерволе для удаленного подключения по ssh.

Настраиваем модем


Для начала необходимо подружить наш модем и Linux (кстати, я использую Centos 5.5). Втыкаем модем в один из свободных usb-портов. Первое, с чем приходится столкнуться, это то что модем определяется как CD-ROM, а с CD-ROM-а как известно смс-ки не отправишь и тем более не получишь. Для того чтоб это дело нам поправить, необходимо всего лишь скормить модему эту команду: AT^U2DIAG=0 (0 – только modem, 1 – modem + cd-rom, 255 – modem + cd-rom + cardreader, 256 – modem + cardreader). Если у вас есть под рукой компьютер, с установленной Windows, то открывайте HyperTerminal, подключайтесь к модему, вводите команду: AT^U2DIAG=0 и пропускайте следующий шаг.

Итак, заставляем модем быть модемом, а не каким-то CD-ROM-ом под Linux. Для начала необходимо поставить пакеты usb_modeswitch и minicom yum --enablerepo=rpmforge install usb_modeswitch minicom, затем создаем/правим /etc/usb-modeswitch.conf:
DefaultVendor = 0x12d1
DefaultProduct = 0x1446
MessageEndPoint = "0x01"
MessageContent = "55534243000000000000000000000011060000000000000000000000000000"


И перетыкаем модем в другой порт, необходимо подождать 5-10 секунд (необходимо чтоб модем определился как CD-ROM) и от root-а запускаем usb_modeswitch и видим примерно следующие:
Looking for target devices ...
No devices in target mode or class found
Looking for default devices ...
Found default devices (1)
Accessing device 004 on bus 007 ...
Using endpoints 0x01 (out) and 0x81 (in)
Inquiring device details; driver will be detached ...
Looking for active driver ...
OK, driver found ("usb-storage")
OK, driver "usb-storage" detached

SCSI inquiry data (for identification)
-------------------------
Vendor String: HUAWEI
Model String: Mass Storage
Revision String: 2.31
-------------------------

USB description data (for identification)
-------------------------
Manufacturer: HUAWEI Technology
Product: HUAWEI Mobile
Serial No.: not provided
-------------------------
Setting up communication with interface 0 ...
Trying to send the message to endpoint 0x01 ...
OK, message successfully sent
Device is gone, skipping any further commands
-> Run lsusb to note any changes. Bye.


Должны появится новые устройства ttyUSB
ls /dev | grep ttyUSB:
ttyUSB0
ttyUSB1
ttyUSB2


Запускаем minicom –s настраиваем последовательный порт на работу с /dev/ttyUSB0,
Выходим из настроек, запускается терминал, затем необходимо отдать команду AT^U2DIAG=0 и получить в ответ ok

Процедура превращения модема в модем закончена, преступаем к установке/настройке smstools.

Smstools


Как ни странно, в огромных репозитариях rpmforge не нашлось места такому наиполезнейшему пакету как smstools. Но не беда, на просторах Интернета и на сайте производителя её достаточно. Я нашел пакет: smstools-3.0.10-4.el5.i386.rpm и «воспользовался» им rpm –i smstools-3.0.10-4.el5.i386.rpm. Настраиваем smstools, файл /etc/sms.conf:
devices = huaweiE1550
logfile = /var/log/smsd.log
loglevel = 2

[huaweiE1550]
device = /dev/ttyUSB0
baudrate = 115200
rtscts = no
init = at+cpms="sm","sm",""
incoming = yes
incoming = high


настройки примерно понятные, запускаем демона, service smsd start и проверяем сие чудо: smssend 9128141111 ‘test message’ (не понимает кириллицу, необходимо конвертировать в UCS-2BE, в рамках этой статьи рассматривать не буду) и ждать смс-ки на мобильник. Если заветное сообщение не пришло, ставим в конфиге loglevel = 7 и идем за бубном. У меня поднялось все с первого раза.

smsctrl daemon


Итак разговаривать мы умеем, необходимо научиться слушать!
Если отправить смс-ку на номер симки в модеме, через некоторое время smsd создаст файл в /var/spool/sms/incoming/huaweiE1550.* примерно следующего содержания:
From: 79128141111
From_TOA: 91 international, ISDN/telephone
From_SMSC: 79126313431
Sent: 11-03-02 08:05:46
Received: 11-03-02 08:08:09
Subject: huaweiE1550
IMSI: 2500XXXXXXXXXXX
Report: no
Alphabet: ISO
UDH: false

Test message

Соответственно эти файлики мы и будем проверять на наличие команд для управления сервером. Для этого два способа 1-й небольшой демон на bash-е, 2-й встроеный обработчик событий в smsd.

1-й способ

#!/bin/sh
# SMSCtrl
# chkconfig: - 55 45
# description: Sms control, Egor N. Zuskin, 2011, http://www.it2k.ru/projects/smsctrl

. /etc/rc.d/init.d/functions

DAEMON=smsctrl
REFRESH_TIME=15

COMMAND_CHAR="#"
INCOMING_DIR=/var/spool/sms/incoming
ALLOW_PHONES="79128141111 79128141112"
SEND_BACK_REPORT=YES

to_log(){
        text=$1
        export LANG=en_EN
        log_date=`date "+%b %d %H:%M:%S "`
        log_host=`hostname -s`
        echo "$log_date $log_host $DAEMON: $text" >> /var/log/$DAEMON.log
}

start() {
        echo -n "Starting $DAEMON: "
        $0 --daemon && success || failure
        RETVAL=$?
        echo
        [ $RETVAL = 0 ] && touch /var/lock/subsys/$DAEMON
        to_log "Starting ..."
        return $RETVAL
}

stop() {
        # Stop daemon.
        echo -n "Shutting down $DAEMON: "
        killproc $0
        RETVAL=$?
        to_log "Stopping ..."
        echo
        [ $RETVAL = 0 ] && rm -f /var/lock/subsys/$DAEMON
}

run() {
    for File in $(ls $INCOMING_DIR); do
        Allow=0
        for Phone in $ALLOW_PHONES; do
            cat $INCOMING_DIR/$File | grep "From: $Phone" > /dev/null 2>&1
            [ $? -eq 0 ] && Allow=1
        done;
        [ $Allow -eq 0 ] && continue

        cat $INCOMING_DIR/$File | grep "$COMMAND_CHAR"
        [ $? -ne 0 ] && continue

        FromPhone=`cat $INCOMING_DIR/$File | grep "From:" | cut -d " " -f2`

        command=`cat $INCOMING_DIR/$File | grep "$COMMAND_CHAR" | cut -d "$COMMAND_CHAR" -f2`
        to_log "Incoming command: $command from $FromPhone"
        out=`$command`

        if [ "$SEND_BACK_REPORT" = "YES" ]; then
            smssend $FromPhone "$out"
            to_log "Send sms to $FromPhone: $out"
        fi
        rm -f $INCOMING_DIR/$File
        to_log "Deleting file $INCOMING_DIR/$File"
    done
}

daemon() {
        exec >/dev/null
        exec 2>/dev/null
        (
        trap "" TERM
        while [ true ]; do
            run
            sleep $REFRESH_TIME;
        done;
        )&
}


case "$1" in
    --daemon)
          daemon
          ;;
    run)
          run
          ;;
    start)
          start
          ;;
    stop)
          stop
          ;;
    restart)
          $0 stop
          $0 start
          exit $?
          ;;
    status)
          status $DAEMON
          echo
          ;;
    *)
          echo "Usage: $DAEMON {start|stop|restart|status|run}"
          exit 1
  esac

  exit 0


COMMAND_CHAR="#" – Признак команды
INCOMING_DIR=/var/spool/sms/incoming – Директория для входящих смс-ок
ALLOW_PHONES="79128141111 79128141112" – Номера с которых разрешены команды
SEND_BACK_REPORT=YES – Отправлять вывод смс-ой обратно


Чтобы не заморачиваться всякими пас фразами и т.д. было принято решение принимать команды только от определенных номеров (не проверял как будут выглядеть смс-ки от подменных номеров) и делать проверку на наличие спец символа перед командой, дабы отгородить от случайной смс-ки.

Сохраняем демона в /etc/init.d/smsctrl, chkconfig --add smsctrl, service smsctrl start

2-й способ


Дописываем в /etc/smsd.conf:
eventhandler = /root/bin/sms_event.sh
создаем /root/bin/sms_events.sh
#!/bin/bash

COMMAND_CHAR="#"
ALLOW_PHONES="79128141111 79128141112"
SEND_BACK_REPORT=YES

[ "$1" = "RECEIVED" ] || exit 0

to_log(){
    text=$1
    export LANG=en_EN
    log_date=`date "+%b %d %H:%M:%S "`
    log_host=`hostname -s`
    echo "$log_date $log_host $text" >> /var/log/smsctrl.log
}

File=$2

Allow=0
for Phone in $ALLOW_PHONES; do
    cat $File | grep "From: $Phone" > /dev/null 2>&1
    [ $? -eq 0 ] && Allow=1
done;

[ $Allow -eq 0 ] && exit 0

cat $INCOMING_DIR/$File | grep "$COMMAND_CHAR"
[ $? -ne 0 ] && exit 0

FromPhone=`cat $File | grep "From:" | cut -d " " -f2`

command=`cat $File | grep "$COMMAND_CHAR" | cut -d "$COMMAND_CHAR" -f2`
to_log "Incoming command: $command from $FromPhone"
out=`$command`

if [ "$SEND_BACK_REPORT" = "YES" ]; then
    smssend $FromPhone "$out"
    to_log "Send sms to $FromPhone: $out"
fi
rm -f $File
to_log "Deleting file $File"


Проверка


Создаем файлик /root/bin/test.sh следующего содержания:
#!/bin/bash

ls –la /etc | grep $1

Затем берем в руки телефон и посылаем смс с текстом #/root/bin/test.sh sms на заветный номер и смотрим в лог tail –f /var/log/smsctrl.log, если все хорошо — в ответ прилетит смс-ка вида: smsd.conf

Заключение


У меня данное решение, по смс-ке открывает ssh порт для входящих подключений. Я думаю, это не единственное применение, достаточно включить немного воображения.

Полезные ссылки для настройки huaweiE1550 и smsd
1: SMSTools 3 — шлюз для отправки SMS
2: Нужна статья про смс-центр с модемом Huawei E1550?
3: Как «приручить» МТС-модем Huawei E1550

Спасибо за внимание, с нетерпением жду Ваших комментариев.

UPD По замечанию моего хорошего друга, дополнил реализацию обработки водящих смс сообщений средствами smsd.
Егор Зюскин @zuskin
карма
32,0
рейтинг 0,0
Похожие публикации
Самое читаемое Администрирование

Комментарии (33)

  • 0
    Наиполейзнейшее решение.
    • +1
      Я старался.
  • 0
    хорошая тема.
    имея прямой IP можно даже не тратить деньги на СМС, а входить когда угодно и от куда угодно «зная условный стук в дверь» :-).
    Были тоже похожие мысли, но на винде. Подскажите плиз на сколько они практичны…
    с помощью net send отправить текст пароль+команда, на принимающей стороне прога «слушает» порт и по надобности делает переброс портов RDC на роутере, и закрывает их по другой команде. Да и на мобиле можно аналог найти под такую команду.
    • 0
      Кстати, en.wikipedia.org/wiki/Port_knocking

      Тут большой простор для фантазии.
    • +1
      SSH по ключу на роутер. Не надо извращаться)
  • 0
    Спасибо!
  • 0
    Я использую gnokii+MySQL, сейчас допиливаю web интерфей для рассыла СМС, потом добавлю еще perl скрипты для автоматизации работ.
    А потом поделюсь с сообществом.
    Жаль, времени не так много как бы хотелось…
  • 0
    А если отправлять сообщение с подменой номера (тот же websms), будет ли реагировать?)
    Когда настраивал похожую вещь оказалось что меняется строчка From_TOA (насколько я помню) при отправке от оригинального номера и с подменой…
  • +2
    чтобы в лог сыпался баланс и уровень сигнала, в конфиге smstools надо написать (для МТС):
    regular_run_cmd = AT+CUSD=1,"#100#";
    regular_run_cmd = AT+CSQ
    regular_run_interval = 86400
    regular_run_logfile = /var/log/smsd_regular_run.log
  • –1
    мало понятно зачем это нужно, да и не безопасно, особенно в таком виде.
    если хочется админить сервер с мобилки, достаточно купить андроида и поставить на него connectbot, который умеет полноценный ssh, с ключами и много чем еще. а это больше похоже на бэкдор с возможностями руткита, который вы сами себе ставите на сервер.
    • –1
      Не всегда на сервере есть интернет, и он может находится где нибудь за городом. Тут я думаю андройд бессилен.
      • +2
        ок, решение полезно при падении интернета и то полезно оно будет максимум, чтобы поднять этот самый интернет, ну или может перезагрузить серевер. что-то более серьезное делать либо сложно, либо просто невозможно. опять же никакого шифрования и защиты от подмены номера, решение явно для личного использования, но не для продакшена.
        • 0
          Не понятно, что Вы имеете ввиду по словами «что-то более серьезное делать либо сложно, либо просто невозможно», какую логику вы задодите скриптам, так и будет выполнятся, сложно или легко. Понятно что такое решене не заменит подключение по ssh. Но поможе снять много головника при правельной реализации.
          • +1
            я говорю о том, что полезность функционала, доступного в данном решении полностью перечеркивается проблемами безопасности.

            кроме перезагрузки сервера и подъема сети, зачем еще можно использовать такое управление?
            • 0
              Да хоть для чего: узнавать текущюю нагрузку на сервер, выполнение сброса кеша, запрос доступного места на дасках, резервная копия базы данных, управление репликацией, запросы к базе данных, управление оборудованием, узнать температуру в серверной и т.д.
              • 0
                критические данные должен телефонировать мониторинг, а остальное лучше делать через нормальный ssh. вобщем игра не стоит свеч, а так, ради поигратся с перлом/башем, конечно интересное занятие)
                • 0
                  Ну а если наоборот — все уронить по sms? :)
                  • 0
                    Было подобное предложение, только вместо SMS просили настроить «форс-мажор» по телефону. ))) Было озвучено пожелание от одного из клиентов сделать возможность форматирования диска при наборе определенного номера. Пришли люди в штатском изымать сервак, человек говорит: «Мне надо позвонить». Делает звонок и счастлив. Ребята в штатском получают О. )) Не знаю точно, шутил ли клиент или реально так страховался. Но тема была. ))
                    • 0
                      чтобы хорошенько форматнуть диск нужно довольно много времени, то есть сработает только с достаточно удаленным серваком, а в такой ситуации надежнее попросить кого-нибудь подменить диск :)
        • 0
          В качестве поднятия уровня безопасности можно, например, использовать для каждой команды одноразовый пароль, ну и/или для начала командного сеанса?
  • 0
    Делал лет 6 назад такое же, только в качестве транспорта для СМС использовал холявный операторский шлюз sms2email. Фоновый демон дергал раз в 2 минуты почту и при получении команд творил разные черные делишки.
  • +4
    Кстати, очень интересный модемчик, сам такой мучаю сейчас. На нем, как бонус, можно поднять Voip-GSM шлюз.
    Он поддерживает голосовые функции и как вариант можно заставить в случае проблем обзванивать по списку нужные номера и заранее заготовленными фразами сообщать о каких-то критически важных событиях.
    Вот представляю, сидят сисадмины, пьют пиво, и тут один поднимает трубку слушает и говорит коллегам, мол тут мне мой сервак звонил, сказал что его 3 раза пытались заддосить и 2 раза хакнуть, он пока держится, но ждет подмоги. :)
    Можно чтобы сразу на какую-то горячую линию отдела К звонил и жаловался. :) Будущее на за горами. :)
  • 0
    Решение интересное. Особенно, если сервер находится за пределами доступа в internet, либо каким-то ограничениями.
    Не так давно набрёл на интересную статейку «Мониторинг сервера Linux с SMS-оповещением и получением графиков производительности». Софт работает, как SaaS веб-сервис, без установки каких либо клиентов, делюсь ссылкой, кому интересно в довесок к статье автора.
  • +1
    Хм… а у меня вот от МТС валяется MF627. разлочить — не разлочивал пока что…
    Подойдет оно? :)
    • НЛО прилетело и опубликовало эту надпись здесь
      • 0
        спасибо :) голосовые функции это круто конечно было бы… call настроить — мол «сейчас отвалился дефаултроут, нажмите 1 для добавления или 2 для входа в меню» )
        • НЛО прилетело и опубликовало эту надпись здесь
  • 0
    Судя по отзывам из Интернета, пойдет.
    • 0
      Подскажи пожалуйста.
      apt-get install smstools
      ps -ef | grep sms
      smsd 1576 1 0 13:19? 00:00:00 /usr/sbin/smsd -p/var/run/smstools/smsd.pid -i/var/run/smstools/smsd.working -usmsd -gdialout

      но
      sendsms
      -bash: sendsms: command not found

      Нашел скрипт…

      -bash: ./sendsms: Permission denied

      рут я естественно :) к нему ничего крутить не надо? там какой-то параметр =key… как вообще еще привернуть smstools? дебиан. minicom цеплялся на /dev/ звонки проходят, все видит. Модем работает.
      Спасибо.
      • 0
        Поставь детализацию логов loglevel = 7 и загляни /var/log/smsd.log, возможно у smsd нет прав на чтение /dev/ttyUSB*
  • 0
    можно ли таким способом одновременно держать соединение с интернетом и принимать/отправлять смски?
  • 0
    У меня данное решение, по смс-ке открывает ssh порт для входящих подключений.

    Не проще ли настроить knockd?
  • 0
    А зачем миником то?
    echo «AT^U2DIAG=0» > /dev/ttyUSB0

Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.