logo

nixscript

Keep it simple, stupid !

Ссылка на статью в формате MarkDown для Curl, кодировка RU.UTF-8

watch-srv - Скрипт уведомлений о входе на сервер.

Адрес статьи: https://nixscript.ru/watch-srv

Git с исходниками: https://git.nixscript.ru/nixscript/watch-srv

Я арендую виртуалки, для этого сайта и для других, для гит-сервера. Кроме того, занимаюсь веб-сервером на работе. Соответственно я должен быть в курсе, кто логинится на сервер и что там делает. Это давно натолкнуло меня на мысль о том, что нужно сделать какое-то оповещение, что кто-то вошёл на сервер. И первым вариантом была отправка e-mail скриптом bash.

Но стало надёжнее и лучше, когда я понял как работает termux. Он позволяет делать сисадминскую работу со смартфона и предоставляет ограниченную, но достаточную возможность работать с интерфейсом смартфона. Для моей задачи требуются, как минимум, уведомления. Но по ходу пьессы, я ещё задействовал открытые лога встроенным браузером... хотя можно использовать любую другую программу просто выбрав предпочтение по-умолчанию.

Для того, чтобы можно было взаимодействовать с системным интерфейсом смартфона нужен дополнительный apk termux-api. Он позволяет:

Возможно я что-то ещё упустил, но не суть будет интересно ихучите wiki.termux.com. Но вернусь к тому, с чего начал.

Скрипт для termux (только Android), следит за указанными серверами. Если кто-то залогинился на сервер, скрипт выдаёт уведомление в смартфонефоне.

ScreenShot

Требования

Вся суть скрипта сводится к выполнению команды w на сервере через ssh, и в зависимости от результата её выполнения выводится уведомление.

Для реализации требуется:

  1. termux, termux-api
  2. Разрешения termux и termux-api на доступ к сети и файлам.
  3. Сгенерировать ssh-key, для доступа к серверу без пароля.

Установка

  1. Устанавливаем termux
  2. Устанавливаем termux-api
  3. Заходим в termux, делаем следующее:
     apt update apt upgrade apt install termux-api

    Это установит обновления, если они имеются, и установит связь termux с termux-api.

  4. Устанавливаем git
     apt install git
  5. Клонируем watch-srv
     git clone https://git.nixscript.ru/nixscript/watch-srv

Всё готово для реализации.

Примечание: по-умолчанию в termux есть только vi, так что если не дружите с ним, установите предпочтительный. К примеру я использую Midnight Commander ( mc ), в котором есть mcedit, но больше мне нравится micro. И mc, и micro доступны, так что думаю и другие редакторы тоже есть.

Начинаем возню со скриптом

Для реализации я выбрал вариант уведомления, поскольку сообщения выскакива.т в область уведомления, и можно задействовать от одной до трёх кнопок, которые могут выполнять команды bash. Само управление уведомлениями через termux-api выглядит сложно и запутанно, но на самом деле всё просто и примитивно. Вот пример вывода самого простого уведомления:

termux-notification \
    --title "Тестовое уведомление" \
    --id 0 \
    --button1 "Закрыть" \
    --button1-action "termux-notification-remove 0" \
    --content "Проверка работы уведомлений termux-api."

По логике это должно быть записано в одну строку, но тогда получается неинформативно и непонятно. Поэтому разделяем слешем \ и легко всё понимаем.

На wiki.termux.com подробно описано как управлять уведомлением и как задействовать кнопки. Всё на английском, но translate.google.com вам в помощь. Тем не менее, здесь я перечислю хелп:

 --action action          действие при нажатии на уведомление
 --button1 text           текст первой (слева) кнопки
 --button1-action action  действие при нажатии первой кнопки
 --button2 text           текст второй (средней) кнопки
 --button2-action action  действие при нажатии второй кнопки
 --button3 text           текст третьей (правой) кнопки
 --button3-action action  действие при нажатии третьей кнопки
 --content content        текст уведомления.
                          Чтение из стандартного
                          вывода не поддерживается.
                          Текст должен быть готовы
                          ДО вывода уведомления.
 --id id                  id уведомления (если будет
                          вызвано новое уведомление с тем же id,
                          новое заменит старое)
 --led-color rrggbb       цвет светового индикатора. На Xiaomi Mi6 только
                          белый цвет. Возможно я что-то не понял...
 --led-on milliseconds    длительность свечения светового индикатора
                          в миллисекундах (по-умолчанию 800)
 --led-off milliseconds   время выключения светового индикатора
                          (по-умолчанию 800)
 --on-delete action       действие при удалении уведомления
 --priority prio          приоритет уведомления (high/low/max/min/default)
 --sound                  проигрывать звук при уведомлении
 --title title            заголовок уведомления
 --vibrate pattern        шаблон вибрации в миллисекундах, через
                          запятую, типа такого: 500,1000,200

Как видите, если понимать о чём речь, всё становится очень просто. Должен заметить, что многие опции должны быть разрешены, чтобы работали. Разрешается просто, в настройках системы смартфона найдите Уведомления -> Уведомления приложений, найдите Termux и дайте ему все необходимые разрешения.

Можно приступать к самому скрипту

В скрипте я решил использовать функцию. Так проще и меньше код.

#!/bin/bash
# Author: Grigruss <grigruss@ya.ru>
# Git: https://git.nixscript.ru/nixscript/watch-srv
# Group VK: https://vk.com/nixscript
#
# Раскомментируйте последнюю строку и замените параметры на свои.

# Преджде всего создаём функцию для
# вывода уведомлений
function check(){
    # Это условие выполняет запрос на
    # сервер для получения информации о
    # вошедших пользователях через команду
    # 'w'.
    if ! srv=$(ssh -p "$3" "$1@$2" w -h 2>/dev/null) then
        # Если запрос не удался, выводим
        # уведомление о проблемах связи
        termux-notification \
            --title "Нет доступа к $2" \
            --id "$4" \
            --button1 "Закрыть" \
            --button1-action
        "termux-notification-remove $4" \
            --priority high \
            --led-on 800 \
            --led-color FF0000 \
            --content "Проверьте подключение интернет."
    elif [ -n "$srv" ]; then
        # Если запрос успешен, выводим
        # уведомление с выводом команды 'w'.

        # Но так же необходимо сделать
        # механизм отключения уведомлений. К
        # примеру, зашёл пользователь на
        # сервер, вы по логину поняли кто
        # это, но если не будет механизма
        # отключения, уведомления будут
        # постоянно выскакивать. Поэтому, при
        # нажатии кнопки "Свои", в уведомлении,
        # я сделал сохранение "флага" в логах
        # и задал проверку этого флага перед
        # следующим уведомлением. Если
        # флаг=1, значит всё в порядке, 0 -
        # посмотри, может тебя грабят. :-)
        # Здесь, в переменную 'F', как раз и
        # записывается текущее значение
        # флага. Если флаг=1, уведомлений
        # не будет, пока с сервера не
        # выйдут и снова не войдут.
        F=$(cat "/data/data/com.termux/files/usr/var/log/srvlgn$4.log")
        if [ -n "$F" ]; then exit; fi

        # Ну а если флаг=0, тогда выводим
        # уведомление. Обратите внимание на
        # значения '--buttonN-action'. Это команды
        # bash. Простые, незамысловатые
        # команды. Но всегда держите в
        # голове, что все данные, переданные
        # этим командам, должны быть
        # константами (неизменные), либо
        # должны формироваться другими
        # переданными командами в момент
        # выполнения. Тут не работает
        # такое: "Укажу переменную, а когда
        # уведомление будет вылазить, запишу
        # в неё данные.". Переменная как была
        # пустой, так и останется.
        termux-notification \
            --title "Залогинились на \"$2\"" \
            --id "$4" \
            --button1 "Свои" \
            --button1-action "termux-notification-remove $4
                echo 1 >/data/data/com.termux/files/usr/var/log/srvlgn$4.log" \
            --button2 "Скопировать" \
            --button2-action "termux-notification-remove $4
                termux-clipboard-set \"$srv\"" \
            --button3 "Получить весь лог" \
            --button3-action "ssh -p $3 $1@$2 last >/data/data/com.termux/files/home/storage/downloads/server-login.log
                termux-notification \
                    --id $4 \
                    --priority high \
                    --content \"Лог загружен в Downloads/server-login.log\" \
                    --button1 \"Закрыть\" \
                    --button1-action \"termux-notification-remove $4\"" \
            --content "$srv" \
            --priority high \
            --sound

        # Обратите внимание, '--id'
        # присваивается значение
        # переменной, а не указывается
        # конкретный ИД. Это для того,
        # чтобы можно было получать
        # уведомления от нескольких
        # серверов одновременно, и они
        # не перезаписывали друг друга.
        # На кнопку 3 задан почти новый
        # скрипт. То есть выполняются
        # две команды по-порядку. Простой
        # перевод строки без `\` работает
        # как нажатие кнопки Enter.

        # И видно ещё одну команду termux-api
        # - 'termux-notification-remove'. Она просто
        # удаляет уведомление с экрана и
        # из оперативной памяти по его ИД.

        # Для весёлости можно добавить
        # оповещение голосом, благодаря
        # специальным возможностям
        # text to speach. Когда кто-то
        # войдёт на сервер, смартфон
        # голосом проговорит заданную
        # фразу.
        termux-tts-speak -l ru "Кто-то залогинился на сервер $4 !"
    else

        # Ну и если на сервере никого нет,
        # то флаг в логе просто обнуляется.
        echo >"/data/data/com.termux/files/usr/var/log/srvlgn$4.log"
    fi
}
# Функция готова. Конечно, когда идёт
# процесс разработки таких, вроде бы
# несложных функций, они рождаются
# не одним махом. Проходит несколько
# десятков, сотен проб и ошибок. И когда
# всё получилось, начинается процесс
# оптимизации. Приходят мысли, как
# упростить, сократить код, сделать
# правильнее и эффективнее... Короче,
# я придумал и реализовал за час, но
# дорабатывал 3 дня. :-)

# Раскомментируйте последнюю строку,
# укажите свои параметры после  слова
# "check" # Если вы используете скрипт для
# мониторинга нескольких серверов,
# указывайте уникальный "notification-id"
# для каждого сервера.
#       login   host/ip    port notification-id

#check "login" "server.ru" 22 0
#check "login1" "server1.ru" 22 1

Если убрать все комментарии, то будет видно, что скрипт довольно небольшой и достаточно простой. Посмотрите исходник: watch-srv.sh.

CRON

Ну и конечно, чтобы получать уведомления вовремя, а не когда уже "поздно пить Боржоми", надо запланировать выполнение скрипта через промежутки времени.

Добавляем задачу в cron. Помните, редактор по-умолчанию - vi. Если хотите использовать другой, вот вам пример:

export EDITOR="mcedit"; crontab -e
# или так
export EDITOR="micro"; crontab -e

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

 * * * * * ~/bin/watch-srv.sh

Я решил сделать проверку каждые 30 секунд, поэтому пришлось использовать hack:

 * * * * * ~/bin/watch-srv.sh * * * * * (sleep 30; ~/bin/watch-srv.sh)

Здесь два вызова скрипта, оба действуют через минуту, но первый сразу срабатывает, а другой с задержкой в 30 секунд.

Сохраняем и выходим.

Осталось лишь запустить cron

crond

Теперь, если кто-то залогинится на сервере, в телефоне появится уведомление такого вида:

ScreenShot

Как видно на скриншоте, имеется три кнопки:

  1. Свои - предотвращает постоянное появление уведомление до тех пор, пока на сервере не разлогинится пользователь. После выхода всех пользователей скрипт отрабатывает в стандартном режиме.
  2. Скопировать - помещает текст уведомления в ситемный буфер обмена смартфона.
  3. Получить весь лог - получает весь лог и сохраняет его в Downloads/srv-login.log

Заключение

Всё достаточно просто. Если есть пожелания, предложения, идеи, пишите в VK/Nixscript или мне VK/grigruss.

Автор: Grigruss 25.04.2019


Статья написана в формате MarkDown и сконвертирована в HTML с помощью скрипта Parsedown.

Вверх 🡑