Обновление времени последнего входа пользователя 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 серверу прошло не больше минуты, то почта отправляется. Если больше или ровно минута - то почта уже не уходит. Получилось такое вот, на мой взгляд, довольно изящное решение.

Написать автору