Управляем удаленной машиной с помощью Google Talk, Twitter, Dropbox и Google+
Сегодня социальные сервисы окружают нас со всех сторон. Мы чатимся в Jabber, читаем новости в Twitter, выкладываем фотки в Google+. Мы делаем это с домашних компов, смартфонов и планшетов ежедневно в почти автоматическом режиме. Для многих из нас Twitter или Facebook давно стал заменой электронной почты и IRC-чатов. Так почему бы не использовать те же сервисы для мониторинга удаленной машины и даже управления ей?
Постановка задачи
В этой статье мы рассмотрим несколько интересных приемов, с помощью которых можно настроить:
- Мониторинг удаленной машины средствами Twitter. Мы создадим специального твиттер-юзера, от лица которого наш сервер/медиацентр/ПК будет слать сообщения о своем состоянии, мы сможем читать их через веб или с помощью твиттер-клиента.
- Управление через Jabber. Мы сделаем Jabber-бот, который будет выступать посредником между нами и консолью удаленной машины. Все написанные ему сообщения будут интерпретироваться как консольные команды, ответ на которые будет выслан в ответном сообщении.
- Управление через Dropbox. Мы создадим простой демон, который будет выполнять команды по мере их появления в указанном файле внутри диска Dropbox.
- Камеру слежения с отчетом в Google+. Мы сделаем простой бот, который будет выкладывать в Google+ фотографии, сделанные веб-камерой. Так мы сможем следить за чем угодно удаленно без необходимости организовывать специальный сервис.
- Видео по запросу. Мы сделаем бот, который будет по нашему запросу снимать видео определенной длительности, а затем выкладывать его в наш приватный канал YouTube.
Все это делается Just for fun, поэтому я заранее соглашусь с теми, кто скажет, что подобные вещи нужно делать с помощью SSH и специальных веб-панелей управления. В то же время хочу заметить, что некоторые из приведенных приемов могут быть удобнее классических подходов. Но обо всем, как обычно, по порядку.
Twitter и отчеты о состоянии
Для многих людей Твиттер уже давно превратился в источник «быстрых новостей». Если ты тоже привык использовать его с этой целью, то включение в общий поток сводок с информацией о твоем сервере или домашней машине может быть очень удачной идеей.
Как это сделать? Для этого понадобятся: новый аккаунт в Твиттере, консольный твиттер-клиент и простой скрипт, который будет генерировать нужные нам сводки информации. С первым все просто. Регистрируем новый e-mail, создаем аккаунт, делаем его приватным и добавляем свой основной аккаунт в список подписчиков. Таким образом доступ к информации о состоянии сервера сможешь получить только ты.
Далее нам понадобится клиент, с помощью которого мы будем отправлять отчеты. Популярный TTYtter справится с этой задачей на отлично. Устанавливаем:
$ sudo apt-get install ttytter
Запускаем клиент, видим сообщение, что необходимо получить OAuth-токен, соглашаемся нажатием . Видим на экране ссылку, открываем ее в браузере и нажимаем кнопку «Авторизовать». На экране появится PIN-код, который следует скопировать и ввести в ответ на приглашение TTYtter. Теперь можно отправить тестовый твит вот так:
$ echo "Привет из консоли!" | ttytter -script
А еще лучше так:
$ free | grep Mem | ttytter -script
Другими словами, теперь мы можем отправить вывод абсолютно любой команды на нашу страницу в твиттере, просто перенаправив ее вывод в TTYtter. Написав же небольшой скрипт и прописав его в расписание cron, мы можем сделать так, чтобы машина отправляла любую указанную информацию через определенные промежутки времени. Для примера возьмем следующий скрипт (фактически это сильно урезанная и доработанная версия скрипта, опубликованного в блоге fak3r.com):
$ vi ~/bin/twitter-monitor.sh #!/bin/bash # Формируем твит # Имя хоста HOST=`hostname -s` # Аптайм машины UP=`uptime | cut -d" " -f4,5 | cut -d"," -f1` # Средняя нагрузка LOAD=`uptime | cut -d":" -f5,6` # Скорость пинга PING=`ping -q -c 3 google.com | tail -n1 | cut -d"/" -f5 | cut -d"." -f1` # Количество занятой памяти MEM=`ps aux | awk '{ sum += $4 }; END { print sum }'` # Нагрузка на процессор CPU=`ps aux | awk '{ sum += $3 }; END { print sum }'` # Собираем инфу вместе TWEET="(HOST) ${HOST} (UP) ${UP} (CPU) ${CPU}% (MEM) ${MEM}% (LOAD) ${LOAD} (PING) ${PING}ms" # Отправляем твит echo $TWEET | ttytter -script
Он собирает такую информацию, как имя хоста, аптайм, пинг до гугла, количество памяти, нагрузка на процессор, и отправляет все это одним твитом. Скрипт больше подходит для мониторинга сервера, но ты можешь изменять его как вздумается, главное — проверить, чтобы в итоге вся инфа умещалась в 140 символов, что можно сделать, заменив последнюю команду скрипта на «echo $TWEET | wc -c» и запустив его.
Теперь осталось лишь добавить скрипт в crontab, чтобы он запускался, например, каждый час:
$ crontab -e 0 * * * * /путь/до/скрипта.sh
Сделать это необходимо от имени того пользователя, от которого ты получил токен для TTYtter.
Хакер #172. Спецвыпуск о Raspberry Pi!
Управление через Twitter
Утилиту TTYtter можно использовать не только для автоматической отправки твитов, но и для автоматического получения твитов от других пользователей и личных сообщений. Учитывая то, что он привязан к приватному аккаунту, в друзьях у которого будешь только ты, мы можем организовать удаленное управление сервером с помощью отправки приватных сообщений.
Последнее приватное сообщение с помощью TTYtter можно получить так:
$ echo "/dma +1" | ttytter -script [DM da0][ezobnin/Tue Mar 26 09:59:59 +0000 2013] test test
Соответственно, чтобы создать систему, которая будет выполнять команды, отправленные в приватных сообщениях, мы должны написать небольшой скрипт, который будет в цикле читать приватные сообщения, обрезать всю лишнюю инфу из вывода (все, что находится между квадратными скобками) и выполнять сообщение как одну команду. Выглядеть это будет примерно так:
$ vi ~/bin/twitter-command.sh #!/bin/sh while true; do CMD=`echo "/dma +1" | ttytter -script | sed 's/[.*] //'` sh $CMD sleep 60 done
Это самый примитивный вариант решения проблемы, страдающий от двух недостатков: во-первых, скрипт не знает, выполнил ли он уже команду, и будет делать это при каждой итерации цикла, даже если новых сообщений не поступало; во-вторых, у скрипта нет обратной связи, что хоть и не очень полезно в случае с Twitter, но может быть хорошим дополнением. Поэтому мы доработаем скрипт до приемлемого состояния:
$ vi ~/bin/twitter-command.sh #!/usr/bin/bash # Имя твиттер-юзера для ответов USER="user" while true; do # Получаем личное сообщение (команду) CMD=`echo "/dma +1" | ttytter -script | sed 's/[.*] //' # Проверяем, выполняли ли такую команду в прошлый раз if [ $CMD != $OLD_CMD ]; then # Если нет — выполняем REPL=`$CMD` # и отправляем ответ команды юзеру echo "/dm $USER ${REPL:0:140}" | ttytter -script # Сохраняем команду, чтобы не выполнять ее снова CMD = $OLD_CMD fi # Спим минуту sleep 60 done
Этот скрипт ведет себя гораздо умнее. Он отправляет результат выполнения команды юзеру, автоматически сокращая его до 140 символов, и запоминает последнюю выполненную команду, чтобы не запускать ее снова. С другой стороны, при запуске скрипт все равно выполнит последнюю отправленную ему команду, но я не думаю, что в этом есть большая проблема.
Управление через Jabber/GTalk
Twitter может быть отличным инструментом для мониторинга машины, но использовать его для того, чтобы отдавать удаленные команды, довольно неудобно. Гораздо лучше для этого подходит Jabber, который изначально был придуман для ведения текстового диалога между двумя сторонами.
В Linux есть несколько инструментов, позволяющих отсылать и принимать Jabber-сообщения из консоли (например, CJC: cjc.jajcus.net), но для реализации нашей задачи гораздо лучше подойдет Ruby-библиотека xmpp4r-simple, позволяющая реализовать Jabber-клиент, написав буквально три строки. Библиотека есть в репозитории Ruby Gems, поэтому для ее установки, например, в Ubuntu следует набирать такие команды:
$ sudo apt-get install ruby $ sudo apt-get install rubygems $ gem install xmpp4r-simple $ gem install session
Чтобы убедиться в ее работоспособности, можно использовать такой скрипт:
$ vi send-message.rb #!/usr/bin/env ruby require 'rubygems' require 'xmpp4r-simple' jabber = Jabber::Simple.new('юзер@gmail.com', 'пароль') jabber.deliver("адресат@gmail.com", "Привет, Gmail!")
Для решения нашей задачи такой скрипт бесполезен, но, дописав в него каких-то десять строк, мы реализуем полноценный бот:
$ vi jabber-bot.rb #!/usr/bin/env ruby require 'rubygems' require 'xmpp4r-simple' require 'session' # Запускаем сеанс sh, в котором будет происходить выполнение команд @sh = Session::new # Коннектимся к Jabber-серверу bot = Jabber::Simple.new(логин@gmail.com, пароль) while true # Ожидаем сообщение bot.received_messages do |msg| # Проверяем, что сообщение пришло от юзер@gmail.com if msg && msg.from.to_s.include?(юзер@gmail.com) # Выполняем команды в сеансе sh stdout, stderr = @sh.execute(msg.body) if msg.body # Отправляем в ответном сообщении вывод команды bot.deliver(msg.from, "n" + stdout.chomp) unless stdout.empty? # Отправляем поток ошибок bot.deliver(msg.from, "n" + stderr.chomp) unless stderr.empty? end end
Приведенный бот прост, но отлично справляется со своей работой. Все, что нужно сделать, — это завести юзера для бота, прописать его логин и пароль, а также адрес своего основного Jabber-аккаунта в скрипт, затем запустить скрипт и написать на адрес бота нужную команду. Результат запуска придет в ответном сообщении. Это действительно удобно, особенно когда нет возможности или времени выполнять полноценный логин по SSH (например, с телефона).
Для тех, кто говорит, что это жутко небезопасно, скажу, что бот будет выполнять только команды, пришедшие с указанного адреса, а так как в протоколе XMPP за проверку обратного адреса отвечает сам XMPP-сервер, то спуфинг адреса с целью захвата управления будет возможен только в случае захвата самого сервера. Проблемой остается то, что шифрование на уровне протокола отсутствует, но при использовании VPN риски сведутся к минимуму.
Управление с помощью Dropbox
Ты можешь удивиться, но рулить машиной можно даже с помощью Dropbox. По сути, это такой же грязный хак, не претендующий на роль нормального решения, но даже он может быть полезен в определенных ситуациях. В основе его работы лежит идея записи команд в файл. Клиент создает текстовый файл внутри каталога Dropbox и помещает в него строку, содержащую команду. На стороне сервера работает скрипт, который в цикле проверяет существование файла и, если такой существует, выполняет содержащуюся в нем команду и записывает ответ в другой файл. Серверный скрипт выглядит следующим образом:
$ vi ~/Dropbox/server.sh #!/bin/bash # Входим в бесконечный цикл while true; do # Файл существует? if [ -f input.txt ]; then # Читаем файл, выполняем команду и записываем ответ в другой файл OUTCOM=$(cat input.txt) $OUTCOM > output.txt # Удаляем входной файл rm input.txt > /dev/null 2>&1 else # Если файла нет, уходим в сон sleep 10 fi done
После запуска скрипта любой, кто подключит тот же том Dropbox (зайдет с того же аккаунта), сможет выполнить команду на сервере, просто записав ее в файл input.txt. Так, например, можно управлять серверной машиной через веб-интерфейс, со смартфона или любого устройства, на котором есть клиент Dropbox. Для удобства управления с другой Linux-машины можно использовать такой скрипт:
$ vi ~/Dropbox/client.sh #!/bin/bash # Создаем входной и выходной файлы touch input.txt touch output.txt # Читаем команду echo -n "Enter Command: " read INCOM # Записываем команду в файл и ждем, пока клиент ее не прочитает, сигналом о чем для нас станет удаление файла echo "$INCOM" > input.txt while [ -f input.txt ];do sleep 10 done # Выводим на экран ответ сервера cat output.txt
При запуске скрипт выводит приглашение к вводу команды, после чего записывает ее в файл и ждет ответа. Все просто, к тому же такой способ коммуникации довольно безопасен. Никто не знает точно, могут ли сотрудники Dropbox на самом деле читать наши данные, но соединение между клиентом и сервером всегда зашифровано, что защищает от перехвата данных. А это, на мой взгляд, гораздо важнее.
Автозагрузка фото с камеры в Picasa/Google+
Аккаунт Google сегодня есть у всех, а значит, есть доступ к Google+, Picasa и куче других полезных и не очень сервисов. Большинство из них можно заскриптовать с помощью утилиты командной строки GoogleCL, которая позволяет работать с такими сервисами, как Picasa, Календарь, Blogger, Контакты, Документы и YouTube прямо из командной строки. С помощью этого инструмента можно делать множество интересных вещей, однако я покажу только два его применения: автоматическая публикация фоток с веб-камеры в альбом Picasa (Google+) и снятие видео с той же камеры и публикация в YouTube по запросу.
Чтобы реализовать такое, понадобится сам GoogleCL, который есть в любом дистрибутиве, а также в репозитории Python:
$ sudo apt-get install googlecl $ sudo pip install googlecl
Далее мы должны создать новый альбом в Picasa, куда будут автоматически загружаться фотографии с веб-камеры:
$ google picasa create WebCamera
При первом обращении к сервису Picasa автоматически откроется страница в веб-браузере, в которой следует нажать кнопку «Разрешить», чтобы предоставить GoogleCL права на управление сервисом. После этого можно вернуться в терминал и нажать Enter.
Теперь нам нужно научиться делать сам снимок. Для этого можно использовать mplayer. Сначала запускаем в тестовом режиме:
$ mplayer tv://
Если получили на экран картинку с другого подключенного видеоустройства (TV-тюнер, например) или с другой камеры, перебираем все устройства в поисках нужного, меняя video0 на video1, video2 и так далее:
$ mplayer tv:// -tv device=/dev/video0
Если картинка перевернута, применяем фильтр:
$ mplayer tv:// -vf flip
Пробуем сделать снимок:
$ mplayer tv:// -frames 3 -vo jpeg
Получаем три снимка: 00000001.jpg, 00000002.jpg и 00000003.jpg. Это три последовательных кадра. Такое количество нужно потому, что многие дешевые камеры просто не успевают инициализироваться и вместо нормального изображения поначалу выдают кашу (у меня первый кадр — зеленый экран, второй — съехавшая картинка, третий — нормальный снимок). Теперь все, что нужно, — это написать скрипт, который будет делать снимок и загружать его в Picasa. У меня получилось вот что:
$ vi ~/bin/webcamera-picasa.sh #!/bin/sh mplayer tv:// -frames 3 -vf flip -vo jpeg DATE=`date +%F-%H-%M` mv 00000003.jpg ${DATE}.jpg google picasa post WebCamera ${DATE.jpg} --title ${DATE} rm -f 0000*.jpg ${DATE}.jpg
Это все, теперь на скрипт можно поставить бит исполнения и использовать его для каких угодно целей. Например, добавить в cron задание, которое будет запускать его каждый час или каждый день. Все снимки будут иметь имя в виде времени съемки, и ты в любой момент сможешь посмотреть их в Google+, где бы ты ни находился. Таким же образом, кстати, можно организовать загрузку фотографий в Dropbox, просто заменив предпоследнюю строку на «mv ${DATE}.jpg ~/Dropbox/».
Автозагрузка видео в YouTube
Таким же образом можно организовать автоматическую съемку и загрузку видео в YouTube. Для этого сначала разрешим GoogleCL работать с сервисом:
$ google youtube list
Как в случае с Picasa, вводим адрес своей электронной почты и нажимаем «Разрешить» в открывшемся окне. Далее можно попробовать загрузить тестовое видео для проверки работоспособности:
$ google youtube post video.avi --access=private --category Education
Видео будет загружено в раздел Education (YouTube требует указания имени раздела) и сделано приватным, так что никто, кроме тебя, его не увидит. В случае успешной загрузки ты получишь ссылку на видео. Если все ОK, можно приступать к реализации скрипта. Выглядеть он будет так:
$ vi ~/bin/webcamera-youtube.sh #!/bin/sh TIME='1:00' DATE=`date +%F-%H-%M` mencoder tv:// -fps 15 -vf flip -ovc lavc -lavcopts vcodec=mpeg4 -nosound -endpos $TIME -o ${DATE}.mpg google youtube post ${DATE}.mpg --access=private --category Education rm -f ${DATE}.mpg
Для съемки здесь использован mencoder с преобразованием в формат MPEG4. Длительность съемки указана в переменной TIME и по умолчанию составляет одну минуту. Сразу после окончания съемки видео будет загружено в YouTube показанным выше способом. Как и в случае с Picasa, вместо публикации в YouTube видео можно просто скопировать в Dropbox: «cp ${DATE}.mpg ~/Dropbox».
Такой скрипт можно использовать разными способами, включая запуск съемки по запросу через SSH или какой-нибудь Google Talk, либо добавить в задание cron и регулярно получать сводки с места событий в свой аккаунт в YouTube.
Выводы
Несмотря на нелюбовь многих из нас к социальным сервисам, они могут сослужить нам хорошую службу как средство для достижения собственных целей. В конце концов, хакерство — это и есть поиск обходных путей и нахождение нетривиальных решений проблемы. Так почему бы с его помощью не превратить бесполезные для некоторых из нас инструменты в полезные?
Евгений Зобнин, execbit.ru