Скрипт на событие логина по SSH

Пришла идея создания скрипта для логгирования события подключения по 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

Leave a Reply