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