четверг, 17 ноября 2011 г.

Обновление времени последнего входа пользователя dovecot и авторизация POP before SMTP

Захотел сделать так, чтобы Dovecot, при подключении пользователя по протоколу POP3, отмечал в базе данных текущее время. Нужно это для того, чтобы определить, какими ящиками давно не пользуются. Нашёл такую вот страницу в wiki Dovecot: http://wiki.dovecot.org/PostLoginScripting.

Для начала нужно узнать текущее значение mail_executable. Для этого воспользуемся командой:
# dovecot -a | grep mail_executable
У меня это значение равно /usr/lib/dovecot/pop3. Именно это значение мы и заменим, так чтобы наш скрипт вызывался до этой программы, обновлял информацию в базе данных, а затем запускал первоначальную программу.

Скрипт /etc/dovecot/pop-update-lastlog.sh, обновляющий информацию в базе данных:
#!/bin/sh

mysql -uuser -ppassword -h127.0.0.1 mail <<END
UPDATE users SET lasttime = NOW(), lastip='$IP' WHERE login = '$USER';
END
exec /usr/lib/dovecot/pop3 "$@"
Установил на него права доступа чтобы простые пользователи не смогли узнать пароль от базы данных и чтобы этот скрипт мог выполняться:
# chmod +x,o= pop-update-lastlog.sh
Затем этот скрипт я прописал в /etc/dovecot.conf:
protocol pop3 {
  mail_executable = /etc/dovecot/pop-update-lastlog.sh
}
Затем добавил пару столбцов в базу данных (структура базы данных - самодельная, не взята от какого-либо веб-интерфейса администрирования):
$ mail -uuser -ppassword mail <<END
ALTER TABLE users ADD COLUMN lasttime datetime DEFAULT '1900-01-01 00:00:00';
ALTER TABLE users ADD COLUMN lastip varchar(32) DEFAULT '0.0.0.0';
END
И перезапустил dovecot:
# /etc/init.d/dovecot restart
В базе данных начали появляться отметки о времени последнего входа и об IP-адресе клиента, с которого входили последний раз.

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

Дополнение от 18 ноября 2011 года. Информацию из таблиц можно использовать для авторизации POP before SMTP в Postfix (перед отправкой почты по SMTP нужно авторизоваться на POP-сервере).

В /etc/postfix/main.cf можно прописать следующее:
mynetworks = 127.0.0.1/8, mysql:/etc/postfix/sql/pop-before-smtp.cf
А в файле /etc/postfix/sql/pop-before-smtp.cf указать запрос и параметры подключения к базе данных:
user = user
password = password
dbname = mail
hosts = 127.0.0.1
query = SELECT DISTINCT lastip
        FROM users
        WHERE lastip = '%s'
          AND ADDTIME(lasttime, '0:1:0') > NOW()
Запрос возвращает IP-адрес только в том случае, если этот IP-адрес аутентифицировался на POP-сервере в течение последней минуты. В случае, если этот IP-адрес в течение последней минуты аутентифицировался на нескольких учётных записях POP-сервера, то возвращается только один IP-адрес.

Не забудьте защитить прописанные в файле пароли доступа к базе данных почтового сервера от обычных пользователей:
# chmod o= pop-before-smtp.cf
Попробовал - POP before SMTP действительно работает. Если с момента последнего подключения к POP серверу прошло не больше минуты, то почта отправляется. Если больше или ровно минута - то почта уже не уходит. Получилось такое вот, на мой взгляд, довольно изящное решение.

Комментариев нет: