Приветствую сообщество. Это первая публикация, далеко не профи-администратора, но просто захотелось поделиться короткой и простой наработкой, которая может оказаться полезной для такого же новичка как я сам.

Сложилось так, что потребовалось контролировать около 30 VDS-ок на Debian, которые мне благополучно «передали» под надзор (а я как бы больше программист, чем *nix-администратор). И первая мысль, что пришла в голову после базовых операций по смене и проверке доступов, была «Если я что-то упустил, хочу оперативно знать о подключениях». Есть рецепты (в том числе на Хабре) связывания события авторизации по SSH и почтовых уведомлений, которые я использовал как базу, но мне хотелось все-таки оперативности и некоторой информативности. В общем получил я в итоге вот такую «систему», которая в течение месяца вполне успешно работает и сообщает мне о любом факте авторизации.

  1. С помощью мануалов по API-телеграм получен токен и чат-ид для бота уведомлений (тут распространяться не буду, это все легко и просто находится в 1-2 строке поисковика).
  2. Создано два скрипта, код от которых будет размещен ниже. В принципе можно все сунуть и в один файл, но т.к. я хотел модульности, то я вынес в отдельный скрипт функцию отправки уведомления в телеграм-бота.
  3. В два файла настроек добавил вызов скрипта регистрации события входа на сервер и перезапустил службу SSH.

На все про все уходит минут 5-10, не больше. Ну а теперь собственно техничка.

PS. Все выполнялось на Debian9 x 64 (если это важно).

/sbin/onlogged

#!/bin/sh

if [ "$1" = "ssh" ] && [ -z "$TERM" ] ; then
    MESS="USER USE SSH AUTH [not console]"
elif [ "$1" = "bash" ] && [ ! -z "$TERM" ] ; then
    if [ ! -z "$SUDO_USER" ] && [ "$TERM" = "linux" ] ; then
	MESS="USER USE SUDO DISPLAY CONSOLE [terminal]"
    elif [ ! -z "$SUDO_USER" ] && [ ! "$TERM" = "linux" ] ; then
	MESS="USER USE SUDO SSH CONSOLE [ssh session]"
    elif [ "$TERM" = "linux" ] ; then
	MESS="USER USE DISPLAY CONSOLE [terminal]"
    elif [ ! -z "$SSH_TTY" ] ; then
	MESS="USER USE SSH CONSOLE [ssh session]"
    else
	MESS="USER LOGGED [unknown]"
    fi
fi

if [ ! -z "$MESS" ] ; then
    if [ ! -z "$SSH_TTY" ] ; then
	M_TTY=" TTY = $SSH_TTY |"
    fi
    if [ ! -z "$SUDO_USER" ] ; then
	M_SUDO=" SUDO = $SUDO_USER |"
    fi
    if [ ! -z "$TERM" ] ; then
	M_TERM=" TERM = $TERM |"
    fi

    SEND="$MESS | USER = $USER |$M_TTY$M_SUDO$M_TERM"
    /sbin/telegram "$SEND" "ALERT" > /dev/null
fi

/sbin/telegram

#!/bin/sh

if [ $# -gt 0 ]
then
	text="[$2] `cat /etc/hostname` : $1"
	url="https://api.telegram.org/bot{TOKEN}/sendMessage"

	curl 		--data-urlencode "chat_id={CHAT_ID}" 		--data-urlencode "text=$text" 		--connect-timeout 10 		--max-time 10 		$url > /dev/null 2>&1
else
	echo "Text is empty"
fi

/etc/ssh/sshrc

/sbin/onlogged ssh

/etc/bash.bashrc

... тут весь текущий код ...
/sbin/onlogged bash

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

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


  1. amarao
    26.02.2019 13:51
    +1

    Не надо это делать в таких конфигах. Лучше, посмотрите на pam_exec. Позволяет запустить свой скрипт на этапе логина пользователя любым методом (точнее, всеми, которым этот pam_exec подключен). Невозможно отключить без рута, точно отработает при логине.


  1. ximik666
    26.02.2019 13:54

    Вопрос: api.telegram.org из России не доступен, но в вашем скрипте подключается к серверу telegram напрямую. Как обходите или сервера не в России ?


    1. il_da_r
      26.02.2019 14:52

      Можно заиметь socks-сервер.
      Curl имеет опцию -socks5-hostname ip:port


    1. Ghool
      26.02.2019 14:52

      Гудбайдипиай не помогает в этом?


    1. Angel2S2
      26.02.2019 15:33

      Можно через socks5 прокси пустить (curl умеет). Можно через какой-либо внешний сервис, я, например, через ifttt сделал через webhook. Да, это как-бы тоже «прокси» по сути получается. И, да, это дополнительная точка отказа.


  1. il_da_r
    26.02.2019 15:13
    +3

    Все решается более просто
    Как писал amarao используя pam_exec

    скрипт /usr/bin/login-notify:

    #!/bin/bash
    PATH=/bin:/usr/bin
    token='токен бота телеграм'
    chat=ваш id
    subj="$PAM_TYPE  on  ${HOSTNAME} from ${PAM_USER}"
    message="Service: $PAM_SERVICE. Login {$PAM_USER} from ${PAM_RHOST} - `date`"
    /usr/bin/curl  --header 'Content-Type:  'Content-Type: application/json' --request 'POST' --data "{\"chat_id\":\"${chat}\",\"text\":\"${subj}\n${message}\"}" "https://api.telegram.org/bot${token}/sendMessage"
    

    в /etc/pam.d/login добавляем:
    session    optional     pam_exec.so /usr/bin/login-notify


    1. bcmob
      26.02.2019 17:57

      Чтоб фиксировать начало и конец сессии через ssh, нужно строку добавить в /etc/pam.d/sshd а не /etc/pam.d/login.
      Во всяком случае в ubuntu 18.04 /etc/pam.d/login действует только для локальных авторизаций.


  1. denaspireone
    26.02.2019 15:18

    Нужно выдать права на выполнение скриптов

    chmod +x /sbin/onlogged
    chmod +x /sbin/telegram


  1. iig
    26.02.2019 18:40

    Чего только не придумают, лишь бы не использовать, к примеру, ossec.
    И зачем нужны сообщения в телеграм о каждом событии? Их кто-то читает 24/7 365 дней в году?


    1. shushu
      27.02.2019 06:08

      Не обязательно постоянно следить за этим. В случае необходимости можно будет просто пролистать до нужного дня


      1. iig
        27.02.2019 12:31

        И что с этим знанием потом делать?
        Вот, припустим, в 02:00 приходит сообщение, что на один из серверов осуществлен вход. Допустим, это китайцы наконец сбрутили пароль и подключают сервер к ботнету. Или сливают базу данных. Пока админ спит — они все успеют.


    1. amakhrov
      28.02.2019 04:58

      Для ossec нужен еще отдельный ossec-server = +1 сущность.
      И на нем потом все так же настраивать транспорт в телеграм (если считать, что автору нужно именно логгирование в телеграм, а не на имейл, который в ossec из коробки)


      1. iig
        28.02.2019 15:46

        Для ossec нужен еще отдельный ossec-server = +1 сущность


        Среди 30 серверов нет ни одного для обслуживания всей этой инфраструктуры? Ни мониторинга, ни централизованного управления? Тогда ок, не нужен ossec уведомления в телегу — это именно то, чего не хватает. ;)