Оповещение при подключении к SSH

    По результатам этого вопроса.

    Как правило, при стандартных настройках во время установки соединения по SSH никаких оповещений на стороне сервера не появляется. Этим может воспользоваться злоумышленник — пока вы сейчас спокойно читаете хабр, возможно, с вашего компьютера уже передаются конфиденциальные данные. Описанную проблему можно легко исправить.

    image

    При установке соединения выполняется скрипт /etc/ssh/sshrc, причём помешать этому со стороны клиента невозможно. Создадим ещё один скрипт для оповещения и поместим команду для его запуска в /etc/ssh/sshrc:

    /usr/local/alert/start.sh
    

    Скрипт будет выводить сообщение с важной информацией через пакет notify-osd и включать привлекающую внимание сирену:

    #!/bin/bash
    
    export DISPLAY=:0
    notify-send "Security Warning" "SSH Connection Established with \"$USER\" $(echo $SSH_CONNECTION | sed 's/\(.*\) \(.*\) \(.*\) \(.*\)/from \1:\2 to \3:\4/')" -u critical -i /usr/local/alert/icon.png
    play /usr/local/alert/sound.wav > /dev/null 2>&1
    

    Здесь сначала мы устанавливаем текущий дисплей для правильной работы notify-osd, далее выводим сообщение с иконкой и пометкой критической важности, используя системные переменные $USER (текущий пользователь) и $SSH_CONNECTION (данные о соединении, которые мы преобразуем в хорошо читаемый вид с помощью регулярных выражений утилитой sed). После этого мы проигрываем сирену.

    Сюда же можно добавить и отправку сообщения на e-mail (с помощью sendmail) или Jabber (с помощью sendxmpp).

    Для установки вы можете просто распаковать содержимое этого архива в корень файловой системы (эта операция сотрёт предыдущее содержимое sshrc!).

    Не забудьте также установить нужные библиотеки, в Ubuntu это делается так:

    sudo apt-get install libnotify-bin sox
    

    UPD #1: По предложениям пользователей bliznezz и Inflame скрипт можно модифицировать:

    #!/bin/sh
    
    export DISPLAY=:0
    notify-send "Security Warning" "Occured Login as user \"$USER\" $(echo $SSH_CONNECTION $SSH_TTY | sed 's/\(.*\) \(.*\) \(.*\) \(.*\) \(.*\)/using SSH connection at \5 from \1:\2 to \3:\4/')" -u critical -i /usr/local/alert/icon.png
    aplay -q /usr/local/alert/sound.wav
    

    А также добавить в /root/.bashrc код:

    unset SSH_CONNECTION
    /usr/local/alert/start.sh
    

    Теперь скрипт будет ещё и сигнализировать при запуске оболочки от пользователя root.

    UPD #2: Пользователь neperap также заметил, что если в домашней директории пользователя на сервере есть файл ~/.ssh/rc, то выполнится именно он, и система оповещения работать не будет. Также, для корректного выполнения эти скрипты не должны выводить текст в консоль.
    Поделиться публикацией
    Комментарии 85
      0
      # who
        +2
        Либо в ручную, либо в cron, что менее правильно чем в приведоном методе.
          +5
          Это когда Вы вспомните и решите посмотреть кто сидит уже в системе. А автор предлагает вариант оповещения в случае установления соединения.

          Идея, по-моему, интересна.
            0
            tail -f /var/log/auth.log
              +6
              Внимательнее читайте статью. "… пока Вы сейчас спокойно читаете хабр, возможно с Вашего компьютера уже передаются конфиденциальные данные..."

              Суть в том, что не требуется личного участия — о событии будет извещено.
                0
                | grep Accept
                  +4
                  # last
                    +3
                    Вы серьезно не поняли о чем статья или просто решили похвастаться знанием команд tail и last?
                      0
                      Конечно понял, просто задели слова
                      … и Вы никак об этом не узнаете.
                        +1
                        И Вы никак об этом не узнаете, если не будете с параноидальной периодичностью проверять логи :)
                        Но зачем это делать, если можно настроить авто-оповещалку?
                +3
                # w
                +1
                может проще запретить авторизацию по паролю?
                  0
                  А как это поможет? Что, если обойдут авторизацию по ключам?
                    +1
                    Ну… не то что бы «обойдут», а сумеют за ранее подсунуть ключ каком-либо методом (например оставил ПК не заблокированным на минутку)
                      +2
                      Ключ на обладание, пароль — на знание. Частенько ключи могут быть и скомпрометированы.
                  +13
                  Спасибо! Этого мне не хватало как параноику:)
                  • НЛО прилетело и опубликовало эту надпись здесь
                      +11
                      как параноику, вам не хватало отключенного ssh  : )
                        +1
                        Имеет место параноидальный мазохизм :)
                      0
                      На сервере у меня стоит отправка сообщение на email.
                      Наверняка, можно сделать, чтобы с сервера запускался скрипт на десктопе.
                        0
                        ssh с ключом и спецлогином, спецскрипт для вывода, nopasswd в sudo для спецлогина.
                        +7
                        а еще бы кнопку — отрубить соединение :)
                          +2
                          Кстати да, мне кажется в этой статье еще кое-чего не хватает. Научите пожалуйста кто-нибудь «выкидывать» пользователя, который на данный момент каким-либо образом залогинен на машину (локально или удаленно). Какой командой это можно сделать?
                            +1
                            sudo ifconfig eth0 down точно помогает ;)
                              0
                              Не всем, некоторым ещё нужно sudo ifconfig eth1 down && sudo ifconfig eth2 down и т.д.
                                0
                                Не в рамках статьи, но все-таки — на сервере такая штука не пройдет, ибо потом ехать далеко придется ;)
                                  +2
                                  sudo ifconfig eth0 down; sleep 2h; sudo ifconfig eth0 up
                                +2
                                находите нужный pid командой ps ax | grep 'sshd: username'
                                убиваете командой kill
                                  0
                                  Если вы не против, то сразу поинтересуюсь: А как можно локального пользователя (с запущенными иксами) выгрузить, желательно корректно — что-то вроде «выход из системы», logout. Т.е. идея прибить процесс понятна и для ssh-подключений вполне годится, а как быть с графическим режимом?
                                    0
                                    Скорее всего, команда gnome-session-save --force-logout с корректно установленной переменной окружения DISPLAY выполнит logout нужного пользователя. Но, возможно, придется запустить ее от нужного пользователя через sudo.
                                  0
                                  reboot -n now
                                0
                                Хоть и велосипед, но идея отличная! Можно как вариант парсить логи, но это лишнии процессы в памяти.
                                  +1
                                  Надо помнить, что notify-send выполняется с правами вошедшего пользователя и может стоять не во всех системах. Ставится в Debian вместе с либой libnotify-bin.
                                  Стоит ли наделять такого пользователя достаточными правами для таких действий? И уж не стоит повторять, что возможность входа под рутом по SSH — моветон.
                                  +2
                                  Выглядит конечно здорово и устрашающе, вот только сценарий реального использования представить себе не могу, даже для параноиков.

                                  Если есть ssh доступ, значит возможны и легитимные подключения. И для них орать «ужас-ужас, нас ломают!» как-то глупо и будет только мешать. А если ssh только для себя самого, то и предупреждать-то некого :)
                                    +2
                                    Есть компьютер дома. Подключаемся сами с работы — пищит, ну и ладно. Подключается злоумышленник, а мы дома — пищит, слышим, волнуемся.
                                      +7
                                      Подключается злоумышленник, а мы вышли за хлебом — не слышим, не волнуемся, все пропустили.

                                      Без пользы это IMHO. Это то, что называют security theater. От кражи данных не спасет, только нервы попортит, может быть.
                                        +8
                                        Ну так никто же не мешает добавить отправку SMS и многое другое. Главное начать и указать направление.
                                    +8
                                    Отлично работает, если коннект происходит под текущим юзером. Но при коннекте под другим аккаунтом, например, root(знаю, что плохо разрешать, но всё же) или pupkin, 'notify-send' ничего не показывает, т.к. не имеет доступа к X, только слышена сирена. Система Ubuntu 10.10. Конечно же, помогает команда добавления юзера в список доступа к X:

                                    xhost local:pupkin

                                    Но такой вариант неприемлем по причинам безопасности.
                                      0
                                      Так же Вы можете поставить такие оповещения и просто на подключение к порту или запросу к HTTP-серверу.

                                      а какой при этом скрипт срабатывает? или парсить логи на предмет активности?
                                        0
                                        Парсить логи я думаю.
                                          0
                                          Чтобы особо не заморачиваться можно fail2ban взять. Им можно не только банить, но и просто выполнять какие-нибудь интересные действия по появлению в логах интересующих строчек.
                                          +2
                                          Спасибо за статью.

                                          P.S. стерёт -> сотрёт
                                            –2
                                            Проще не включать демон или закрыться фаерволом.
                                              +4
                                              Проще не вылазить из кровати и укрыться одеялом.
                                                +6
                                                Ты такой забавный.
                                                +2
                                                Или вообще компьютер не включать.
                                                +2
                                                У меня похожая фигня давно прописалась в ~root/.bashrc:
                                                test $(logname) != $(whoami) && ( DISPLAY=:0 notify-send -u critical "I got the power" "IP: $SSH_CLIENT \nlogin: `logname`" )

                                                Суть такова: Если какой-то из юзеров (изначально не root) получил root-овые права ( sudo, su, через exploit, или выиграл в карты), и запустил оболочку — то об этом подается сигнал. Но, к сожалению, через sudo -s или su - — переменная SSH_CLIENT херится.
                                                  0
                                                  Интересное решение! Спасибо!)
                                                    +6
                                                    $ su -s /bin/bash -- --rcfile /dev/null
                                                    и bashrc выполняться не будет
                                                      0
                                                      sudo -E
                                                      0
                                                      Кстати, интересно, что если $SSH_CONNECTION не установлено, а скрипт запускается (например, по другим причинам), то from и to не выводятся, что не нарушает красоты сообщения и работу скрипта.
                                                        0
                                                        для Ubuntu понадобилось ещё поставить пакет sox для проигрывания звука, не стоял по дефолту.
                                                        В итоге все дополнительные команды, учитывая упомянутый libnotify:

                                                        sudo apt-get install libnotify-bin
                                                        sudo apt-get install sox

                                                        спасибо автору!
                                                          0
                                                          Думал sox стандартно стоит, ну ладно, добавил в топик, спасибо!
                                                            0
                                                            Можно вместо play использовать aplay, который по умолчанию в Ubuntu присутствует.
                                                            0
                                                            Автор, допишите, пожалуйста, что если есть ~/.ssh/rc, то выполнится он, и /etc/ssh/sshrc выполняться *не будет*, плюс данный скрипт не должен ничего выводить в stdout, но эта часть нужна тем, кто использует x11 forwarding через ssh.

                                                            man sshd
                                                            /SSHRC

                                                            И спасибо за статью :)
                                                              0
                                                              Сейчас добавлю, только я не понял о чём Вы пытались сказать про stdout?
                                                                0
                                                                В man-е пишут, что [данный скрипт, ~/.ssh/rc или /etc/ssh/sshrc ]…

                                                                «must not produce any output on stdout; stderr must be used instead. If X11 forwarding is in use, it will receive the „proto cookie“ pair in its standardinput (and DISPLAY in its environment).»

                                                                Касается не многих, но у кого-то может поломаться :)
                                                              0
                                                              Может, вместо play использовать aplay -q, потому что, например в Ubuntu, play по умолчанию не установлен, зато есть aplay.
                                                                0
                                                                Тоже можно…
                                                                +3
                                                                1. aptitude install pam-dbus-notify
                                                                2. /usr/share/pam_dbus/pam-dbus-notify &
                                                                3. sed -i 's/@include common-auth/auth required pam_dbus.so/' /etc/pam.d/sshd
                                                                4. ssh localhost
                                                                  +2
                                                                  Ну, тогда можно и pam_script с onauth=/path/to/script для большей конфигурабельности. Я вот только не знаю, дополнительную информацию (как то адрес удаленного хоста) откуда брать.

                                                                  Ну и да, кликать на экране «разрешить-запретить» все-таки не всегда возможно/удобно/хочется.
                                                                  +1
                                                                  Появилась идея повесить в комнате красную лампу и включать ее в подобных случаях.
                                                                    +4
                                                                    Автор — молодец, идея интересная, хоть и мне не нужная, но есть замечание.

                                                                    Вот вы зачем свой скрипт прогоняете через bash? В нём же не используются никакие специфично башевские вещи, ни массивы, ни parameter expansion с pattern substitution. Такие простые скрипты надо начинать с
                                                                    #!/bin/sh
                                                                    и на той же бубунте они будут скармливаться dash'у, который использует в 3 раза меньше памяти и стартует в 10 раз быстрее.
                                                                      0
                                                                      Исправил.)
                                                                      +1
                                                                      Спасибо, интересный способ.
                                                                      Правда я настроил conky на показ входящих подключений по 21 и 22 портами, и всегда вижу на десктопе входящие соединения по ftp и ssh, мне этого достаточно.
                                                                      • НЛО прилетело и опубликовало эту надпись здесь
                                                                        +1
                                                                        «export DISPLAY=:0» — по идее это не должно работать, если войти по ssh используя учётную запись отличную от той, которая в данный момент используется в X-ах, т.к. пользователь не сможет в X-ах авторизоваться.
                                                                          +6
                                                                          Удивительно, что никто еще не написал про sendxmpp в связи с этим.

                                                                          echo -e "SSH Login on $(hostname -f)\n\nDate:\t\t$(date +%d.%m.%Y\ %H:%M:%S)\nRemote Host:\t$SSH_CONNECTION\nUser:\t\t$USER\nShell:\t\t$SSH_TTY" |\
                                                                          sendxmpp -u user -p password -j server -s "SSH Login on $(hostname -f)" -r "$(hostname -f)" my@jabber.id 2>/dev/null

                                                                            0
                                                                            Добавил про sendmail и sendxmpp. Про последний услышал только от Вас — оказывается очень удобно!
                                                                              0
                                                                              Да, он почему-то малоизвестен, хотя очень полезен как realtime-оповещалка.
                                                                            0
                                                                            Немного поэкспериментировал. Похоже, уведомление notify-send работает, только если по ssh входит тот же пользователь, от которого запущен X-сервер. Тогда уведомление отображается нормально. Если же по ssh входит, например, root, то notify-send от root ничего не выводит на экран пользователя:
                                                                            Также если просто запустить из консоли от root:

                                                                            wiselord ~ # notify-send test
                                                                            X11 connection rejected because of wrong authentication.

                                                                            Аварийный останов

                                                                            Можно видеть, что дело не в ssh, а именно в том, что вывод на DISPLAY возможен только от того же пользователя.
                                                                            По крайней мере, в KDE4 так, а делать `xhost +` для доступа всех — это поступиться одной безопасностью ради другой.
                                                                              0
                                                                              Много написал, но только сейчас заметил комментарий выше: habrahabr.ru/blogs/linux/117834/#comment_3837428
                                                                                0
                                                                                «xhost +» делать не очень хорошо с точки зрения безопасности. Правильнее будет сделать так, как это делается, например, в скриптах ACPI.
                                                                                см. /usr/share/acpi-support/power-funcs, функция getXuser()
                                                                                +1
                                                                                Спасибо автору за статью. Очень и очень полезно. Только возникает вопрос. В чем смысл запущенного ssh, пока вы читаете хабр? Как показывает горький опыт, данные и функционал лучше разносить по машинам.

                                                                                А в целях безопасности, можно просматривать весь исходящий трафик на уровне TCP, и закрывать соединение при появлении подозрительных строк. Наверняка это можно сделать с помощью Snord или c tcpdump (ручками). Парсить логи для этого, на мой взгляд вредно, лучше в режиме реального времени. Узнаем, что у нас что-то тащат — рвем соединение и посылаем владельцу sms, как писали выше.
                                                                                Если мы очень вредные, то при появлении подозрительных строк, можно не рвать соединение, а подменять данные на заведомо ложные. При посылке опасных команд — рвать, ничего эдакого тут не придумаешь.
                                                                                Главное, самому не попасть в свои же капканы.

                                                                                Но автору еще раз спасибо за познавательную статью.
                                                                                  +2
                                                                                  >В чем смысл запущенного ssh, пока вы читаете хабр?

                                                                                  Реальный пример: на моей тачке на работе есть пишущий DVD, а у другана рядом нет и он иногда пишет на моем DVD… по ssh.
                                                                                    0
                                                                                    Может я не прав, но это своего рода костыль. Безопаснее\полезнее\удобнее поставить ему еще один DVD, или хотя бы выносной купить, если это вообще возможно в силу инфраструктуры\бюрократических ограничений. Но как реальный пример — очень хорош. Спасибо.
                                                                                      +3
                                                                                      А, например, у меня файлопомойка и гейтвей на машине подключенной только к сети и розетке.
                                                                                      Как ей рулить? Только по ssh, и делать нотифай при коннекте по ssh — отличныая идея ^_^
                                                                                    +1
                                                                                    >В чем смысл запущенного ssh, пока вы читаете хабр?

                                                                                    Когда паранойя заставляла включать ssh только когда уезжаю, но пару раз забыл включить и не смог получить доступ когда он очень нужен был, с тех пор работает постоянно.
                                                                                    0
                                                                                    А можно ли в Убунте реализовать отправку уведомлений по сети типа как в маковском Growl? Я бы хотел чтобы домашний сервер мог посылать уведомления мне на ноутбук. Для винды есть Growl for Windows, для линукс нету?
                                                                                      0
                                                                                      Про Grovi не знаю, но сами уведомления по сети сделать довольно просто.
                                                                                        –1
                                                                                        Что-то подобное есть. Подробности тут: goo.gl/mmlX2 :)
                                                                                      • НЛО прилетело и опубликовало эту надпись здесь
                                                                                        • НЛО прилетело и опубликовало эту надпись здесь
                                                                                          0
                                                                                          А как быть с
                                                                                          > libnotify-Message: Unable to get session bus: /bin/dbus-launch terminated abnormally with the following error: No protocol specified
                                                                                          > Autolaunch error: X11 initialization failed.


                                                                                          При установленных DBUS_SESSION_BUS_ADDRESS и DBUS_SESSION_BUS_PID работает нормально, но их ведь где-то надо взять предварительно…
                                                                                            –1
                                                                                            такое ощущение, что про syslog никто и близко не слышал.

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

                                                                                            Самое читаемое