Пришла идея создания скрипта для логгирования события подключения по SSH в таблицу SQL и уведомления о подключении определенных пользователей определенным пользователям:
- писать всем пользователям о подключении их самих – сами пользователи знают, когда заходят и заход тогда, когда ты это делать не мог – есть повод обеспокоиться
- админу писать о подключении всех пользователей, имеющих права на sudo
В целом логгирование в linux встроено по умолчанию – утилита last показывает полный лог авторизаций с момента создания файла /var/log/wtmp и продолжительность pts, а в lastlog есть информация о последнем подключении. Удалить и видоизменить файл wtmp нельзя без sudo, но для избыточности (что с точки зрения безопасности всегда неплохо) и прикрепления доп. фишек, описанных выше, нужно делать что-то свое.
Есть много способов решения задачи автозапуска скрипта по логину пользователя, например:
- скрипт в pam.d – я остановился на нем. pam_tty_audit, кстати, может использоваться для логгирования не только подключения, но и всех введенных команд
- скрипт в bashrc
- скрипт в profile.d
Добиваем в файл /etc/pam.d/sshd строку с путем до нашего скрипта. Обязательно делаем параметр Optional, чтобы не произошло такого, что неотработка скрипта по логгированию приводит к недоступности по ssh.
session optional pam_exec.so /usr/local/bin/<script>
Далее делаем простеший скрипт на bash (типо tty + who – получить номер текущей tty) или любом другом языке. Тут пример на .sh с логгированием в файл. Я сделал на ruby с логгированием в базу – забрал переменные pam из системных переменных и положил их в базу. Так же сделан ассоциированный массив – каждому номеру задается перечень учетных записей, при подключении которых приходит смс. Как хотели, тут можем сделать так, чтобы обычным пользователям сопоставлялась только их учетная запись, а админу все учетные записи с правами на sudo.
#!/usr/bin/env ruby #coding: utf-8 require 'oci8' user = ENV['PAM_USER'] host = ENV['PAM_RHOST'] optype = ENV['PAM_TYPE'] timenow = "#{Time.now}".split(" ") datetime = "#{timenow[0]} #{timenow[1]}" alarmusernumhash = { "79651112233" => [ "user1" ], "79641112233" => [ "user2" ], "79631112233" => [ "user1", "user2", "user3" ] } # write to bd conn = OCI8.new('ora-user','ora-pass','ora-sid') conn.exec("INSERT INTO <SERVER_SSH_LOG> (usr,hst,optype,cdate) VALUES (\'#{user}\',\'#{host}\',\'#{optype}\',to_date(\'#{datetime}\','yyyy-mm-dd HH24:MI:SS'))") conn.exec("COMMIT") conn.logoff # send sms alarmusernumhash.keys.each do |number| alarmusernumhash["#{number}"].each do |aluser| if "#{user}" == "#{aluser}" && optype == "open_session" send_sms_to_number("#{number}","#{datetime}\nuser #{user} from host #{host} logged to <SERVER>") end end end