Чужой опыт экономит время и увеличивает шансы для удачи

Dovecot 2 - описание настроек, в контексте рассматриваемой конфигурации

В заметке описаны выборочно некоторые части официальной документации Dovecot (вольный перевод). Разобраны отдельные механизмы работы, рассмотрены некоторые параметры настроек конфигурационных файлов и пр.
Затронуты только самые ключевые моменты, - минимум необходимый для "вхождения в тему".

ВАЖНО! Эта страница является частью списка заметок о настройке почтовой системы (Postfix+Dovecot и пр.).
Родительская страница - обязательна к просмотру: Установка и настройка почтового сервера

Подробнее о конфигурации к которой относятся примеры в этой статье - см. ссылку выше.
Тем же - коротко об основных терминах (MTA, MDA, MUA и т.п.).

Эта заметка имеет характер исследования. Все упомянутые в заметке эксперименты проводились на ОС Debian. Пожалуйста не используйте слепое копирование примеров. Автор не гарантирует, что применение изложенной здесь информации не приведет к потере данных.

Это скорее конспект-шпаргалка, чем достоверный справочник. Кроме ответов здесь могут присутствовать вопросы.

Содержание

Здесь частями вставлен вольный перевод официальной документации, без предупреждений разбавленный отсебятиной!

Dovecot - общие моменты

Dovecot выполняет две основные функции - предоставляет интерфейс для доступа MUA через POP или IMAP, и выполняет окончательную доставку почты, от MTA в ящики (в папки). Эту функцию доставки может выполнять и сам Postfix с помощью своей LDA, а может и сторонний LDA.

Но в рассматриваемой конфигурации этим все же занимается Dovecot. Причем в процессе доставки задействован механизм lmtp.

ВАЖНО! Для поддержки протокола lmtp, должен быть установлен пакет dovecot-lmtp.

В рассматриваемом варианте почта физически хранится в формате Maildir (каждое сообщение в отдельном файле). Но у Dovecot, кроме поддержки еще одного стандартного формата "Mbox" (хранение сообщений в одном файле; здесь не рассматривается), есть еще поддержка двух собственных форматов "sdbox" и "mdbox" (здесь так же не рассматриваются).

Версии.
Dovecot постоянно модифицируется и пакеты в репозитариях Debian стабильной версии конечно отстают. В новых версиях встречаются существенные изменения, которые могут быть очень интересны. Из последнего, что мне, например очень понравилось - доработка инструмента командной строки doveadm новой командой "deduplicate", которая позволяет из консоли просканировать указанные виртуальные папки пользователей и уничтожить дубликаты писем (вылавливая их по Message-ID). К сожалению в стабильной версии такого функционала нет.

Если захочется рискнуть поставить последнюю версию, то сначала нужно добавить строку с указанием на последнюю версию (на момент написания заметки это версия 2.2)

/etc/apt/sources.list :

deb http://xi.rename-it.nl/debian/ testing-auto/dovecot-2.2 main

После чего обновить репозитарии и установить самые свежие пакеты.

Родную документацию, после установки, можно найти здесь: /usr/share/doc/dovecot-core/dovecot/wiki/ .

Поддерживаемые протоколы:

  • IMAP (включая TLS/STARTTLS)
  • IMAP+SSL ("imaps")
  • POP3 (including TLS/STLS)
  • POP3+SSL ("pops")
  • LMTP
  • Sieve

Методы аутентификации:

  • plain
  • digest-md5
  • cram-md5
  • apop (только для POP3)
  • anonymous

Базы User/Password:

  • PAM
  • "passwd" и "shadow" файлы
  • Password Executable
  • MySQL, с возможностью использования в разных случаях, разных хостов и разных баз
  • PostgreSQL
  • LDAP
  • vpopmail
  • Linuxconf

Некоторые внутренние переменные:

  • %u - имя пользователя
  • %n - имя в user@domain.tld ("user")
  • %d - доменная часть в user@domain.tld ("domain.tld")
  • %h - домашний каталог
  • Пример настройки конфигурации
    /etc/dovecot/conf.d/10-mail.conf :

    mail_location = maildir:/var/mail/%1u/%u/Maildir

    %1u - первый символ имени пользователя.

    Подробнее о переменных см. ниже.

Здесь описываются примеры для одного конкретного частного случая конфигурации почтовой системы.

Как указывать параметры

В Dovecot настройки, которые не указаны - применяются по умолчанию. Это может приводить к интересным последствиям.

Например, если в файле /etc/dovecot/conf.d/10-master.conf закомментирован listener, то это не значит, что он не работает. А может быть так, что если он описан в форме, отличающейся от той, что принята по умолчанию, то получим два слушателя.

Рассмотрим такой пример

/etc/dovecot/conf.d/10-master.conf :

...
service lmtp {
...
  #unix_listener lmtp {
    #mode = 0666
  #}
 
 unix_listener /var/spool/postfix/private/dovecot-lmtp {
   group = postfix
   mode = 0600
   user = postfix
  }
...
}
...

В этом случае имеем два слушателя (listener) - один описанный явно в не совсем стандартной форме:
unix_listener /var/spool/postfix/private/dovecot-lmtp {...}
и второй - принятый по умолчанию (хотя и закомментированный):
unix_listener lmtp {...} .

# netstat -l -p | grep lmtp
...
unix  2      [ ACC ]     STREAM     LISTENING     ...     .../dovecot        /var/run/dovecot/lmtp
unix  2      [ ACC ]     STREAM     LISTENING     ...     .../dovecot        /var/spool/postfix/private/dovecot-lmtp
...

При этом в большинстве примеров встречается именно такое "не совсем стандартное" описание слушателя. Если слушатель по умолчанию не нужен, то можно просто использовать стандартную форму и почему-то редко встречающийся в примерах параметр: path

/etc/dovecot/conf.d/10-master.conf :

...
service lmtp {
...
  unix_listener lmtp {
   path = /var/spool/postfix/private/dovecot-lmtp
   group = postfix
   mode = 0600
   user = postfix
  }
 
 #unix_listener /var/spool/postfix/private/dovecot-lmtp {
 # ...
 # }
...
}
...

Проверяем:

# netstat -l -p | grep lmtp
...
unix  2      [ ACC ]     STREAM     LISTENING     ...     .../dovecot        /var/spool/postfix/private/dovecot-lmtp
...

Слушатель по умолчанию исчез.

LMTP

Для начала нужно установить пакет dovecot-lmtp.

Проверить, и, если нужно - включить поддержку протокола

/etc/dovecot/conf.d/dovecot-sql.conf.ext :

# !include_try /usr/share/dovecot/protocols.d/*.protocol
protocols = imap lmtp
!include conf.d/*.conf

"# !include_try /usr/share/dovecot/protocols.d/*.protocol" автоматическая загрузка всех установленных протоколов здесь закомментирована, поскольку файлы в папке, которые он включает просто дублируют следующую строку. Кроме того нет смысла инклудить все установленные протоколы, если они не нужны (напр. "pop3").


Далее нужно сконфигурировать "слушателя" lmtp и авторизацию

/etc/dovecot/conf.d/10-master.conf :

service lmtp {
 unix_listener /var/spool/postfix/private/dovecot-lmtp {
   group = postfix
   mode = 0600
   user = postfix
  }
service auth {
  unix_listener /var/spool/postfix/private/auth {
    mode = 0660
    user = postfix
    group = postfix
  }
  user = $default_internal_user
}
service auth-worker {
 user = $default_internal_user
}
#  process_min_avail = 5
#  executable = lmtp -L
}

"process_min_avail = 5" - Количество процессов. Для высоконагруженных сайтов имеет смысл увеличить количество процессов. Можно поэкспериментировать в диапазоне от 5 до 20.
"executable = lmtp -L" - логгирование (необходимо указать файл лога - см. ниже).


Настроить плагины и пр.

/etc/dovecot/conf.d/20-lmtp.conf :

protocol lmtp {
  postmaster_address = postmaster@domain.tld   # required
  mail_plugins = quota sieve
# info_log_path = /var/log/dovecot-lmtp.log
}

"info_log_path = /var/log/dovecot-lmtp.log" - файл лога.


И сконфигурировать транспорт в Postfix

/etc/postfix/conf.d/main.cf :

virtual_transport = lmtp:unix:private/dovecot-lmtp
#mailbox_transport = lmtp:unix:private/dovecot-lmtp

Вторая строка скорее всего понадобится только если Postfix полностью заменил Sendamil. Она предназначена для не виртуальных (а системных) пользователей.


SASL

SASL расшифровывается как "Simple Authentication and Security Layer". SASL - это список требований к механизмам аутентификации и протоколам, для их совместимости с SASL, как описано в RFC 4422. IMAP, POP3 и SMTP протоколы имеют поддержку SASL.

Многие люди путают SASL с одной конкретной реализацией SASL: библиотекой Cyrus SASL. Dovecot имеет свою собственную реализацию SASL, которая может рассматриваться отдельно от Dovecot и "конкурировать" с Cyrus SASL.

Postfix версии 2.3 и выше поддерживает два типа SASL: "dovecot" и "cyrus".

Соответственно в настройке Postfix нужно указывать smtpd_sasl_type = dovecot. Это только тип SASL, т.е. стандарт инициированный Dovecot.

При использовании в Postfix только LMTP, упоминаний о Dovecot в конфигурационных файлах в Postfix больше нигде не должно встречаться (за исключением имен сокетов и собственно упомянутого выше типа SASL).

Namespace

Dovecot поддерживает настраиваемые пространства имен (namespace), в соответствие со спецификацией "RFC 2342" (к сожалению, не все клиенты ее поддерживают), содержащей указания IMAP-клиенту: где находятся почтовые ящики, являются ли они частными (private), публичными (public) или общедоступными (shared). При конфигурировании "namespace" может быть настроен разделитель, префикс и пр. т.п., а также настроен доступ к нескольким местам хранения почты, в различных форматах.

Названия секций (напр.: namespace sectionname {...} ), не имеют особого значения, но позволяют обновлять существующее пространство имен (напр. как в "15-mailboxes.conf") или переопределять "UserDB"-настройки конкретных пользователей (namespace/sectionname/prefix=foo/).
См. ниже пример.

Примеры:

Параметр: mail_location Реальный
разделитель
Namespace
разделитель
Имя папки Реальный путь к папке
maildir:~/Maildir . . foo.bar ~/Maildir/.foo.bar/
maildir:~/Maildir . / foo/bar ~/Maildir/.foo.bar/
maildir:~/Maildir:LAYOUT=fs / . foo.bar ~/Maildir/foo/bar/
maildir:~/Maildir:LAYOUT=fs / / foo/bar ~/Maildir/foo/bar/

Как видно, разделитель пространства имен (namespace separator) влияет только на имя IMAP-папки, но не влияет на реальный путь папки. Реальный разделитель (layout separator) влияет на реальную структуру папок в родительском каталоге (см. о нем в разделе: Maildir). Существует плагин listescape для более гибкой настройки разделителя.

Пример смешения mbox и Maildir namespace

/etc/dovecot/conf.d/10-mail.conf :

namespace {
  separator = /
  prefix = "#mbox/"
  location = mbox:~/mail:INBOX=/var/mail/%u
  inbox = yes
  hidden = yes
  list = no
}
namespace {
  separator = /
  prefix =
  location = maildir:~/Maildir
}

Более интересный пример (не из доков) - смешение двух Maildir. Подключаем каждому пользователю - ящик пользователя "user2"

/etc/dovecot/conf.d/10-mail.conf :

mail_location = maildir:/home/vmail/%d/%n
 
namespace inbox {
  type = private
  separator = /
  prefix = 
  inbox = yes
  hidden = no
  list = yes
  subscriptions = yes
}
namespace inbox2 {
  type = private
  separator = /
  prefix = "user2/"
 
  location = maildir:/home/vmail/%d/user2/
 
  inbox = no
  hidden = no
  list = yes
  subscriptions = yes
}

Здесь папка пользователя "user2" появится в списке папок каждого ящика и будет содержать все дочерние подпапки, хотя сама она (INBOX) будет недоступна (изменения требуют рестарта dovecot).


Еще один небольшой пример из официальной документации.
Нужно дать имя namespace, например "docs".

/etc/dovecot/conf.d/10-mail.conf :

namespace docs {
  type = public
  separator = /
  prefix = Public/
}

Создаем в SQL-базе таблицу

CREATE TABLE Namespaces (
..
  Location varchar(255) NOT NULL,
..
)

Теперь каждому пользователю можно определять свою "location" в namespace "docs"

/etc/dovecot/conf.d/dovecot-sql.conf.ext :

user_query = SELECT location as 'namespace/docs/location' FROM Namespaces WHERE ..

Мой комментарий к официальному примеру.
Здесь поле "namespace/docs/location" может быть конечно подключено в числе прочих нужных полей в том же запросе ("home", "uid", "gid", "quota_rule" и т.п.). Видимо здесь, так же как и в других подобных случаях можно использовать механизм "prefetch" для "userdb", и получать те же поля в запросе "password_query" с использованием префикса "userdb_" ("userdb_namespace/docs/location", "userdb_home", "userdb_uid", "userdb_gid", "userdb_quota_rule" и т.п.).
Кроме того, наверное можно любую опцию получать и назначать таким же образом. Например, что-то вроде:

password_query = SELECT IF(username = 'admin@domain.tld', 'yes', 'no') AS 'userdb_namespace/docs/list' ... FROM mailbox WHERE username='%u' AND active = '1'

См. также комментарий под примером ниже.

Maildir

Maildir хранит каждое сообщение в отдельном файле, и требует, чтобы у каждого был уникальный ID. Список файлов и соответствующих им ID хранится в файле "dovecot-uidlist".

Этот файл не должен быть заблокирован на чтение. Новые строки добавляются в конец файла. Данные в нем не могут быть изменены - только заменены. Сообщения после окончательной доставки так же не могут быть изменены, а могут быть только заменены целиком.

Для ускорения доступа к тысячам сообщений в папках, имеет смысл использовать поддержку индексирования директорий на уровне файловой системы (это возможно для новых версий ext3). Возможно имеет смысл использовать для каталога почты "ReiserFS" - файловую систему, заточенную для быстрой работы с большим количеством маленьких файлов.

По умолчанию Dovecot использует структуру директорий Maildir++. Это означает, что все папки находятся непосредственно внутри каталога ~/Maildir.

Обычно, имя папки внутри родительского каталога начинается с "." (точки), - все они хранятся в корневом каталоге ("INBOX"), включая подкаталоги (напр.: ~/Maildir/.folder/ , ~/Maildir/.folder.subfolder/ ). Но если в mail_location использовать параметр ":LAYOUT=fs", то папки можно сохранять БЕЗ точки в привычном для файловой системы формате (напр.: ~/Maildir/folder/subfolder/ ).

Пример настройки конфигурации
/etc/dovecot/conf.d/10-mail.conf :

mail_location = maildir:/var/mail/%d/%n/Maildir:LAYOUT=fs

Начиная с версии Dovecot 2.0, разрешения для вновь созданных файлов больше не копируются из файла "dovecot-shared".

При использовании других программ одновременно с Dovecot для доступа в каталоги могут возникнуть серьезные проблемы, связанные с работой с файлом одной программы, и одновременными действиями над ним другой.

Индексное хранилище можно принудительно указывать персональное каждому используя, например ":INDEX=~/public" для параметра mail_location или location. Например, в случае доступа к дополнительным публичным каталогам, можно назначать для такого каталога каждому пользователю свое индексное хранилище.

ВАЖНО! С версии 2.2 необходимо использовать :INDEXPVT.

/etc/dovecot/conf.d/10-mail.conf :

mail_location = maildir:/home/vmail/%d/%n
namespace {
  type = private
  separator = /
  prefix =
  hidden = no
  inbox = yes
}
namespace {
  type = public
  separator = /
  prefix = Public/
  location = maildir:/var/vmail/public:LAYOUT=fs:INDEX=/home/vmail/%d/%n/pub_index
  list = yes
  subscriptions = no
}

В этом примере (он немного изменен и отличается от примера в официальных доках) у каждого пользователя кроме своего ящика, есть доступ к публичному каталогу, но индексное хранилище публичного каталога (с назначенным именем "pub_index") у каждого пользователя находится в его домашнем каталоге.

Если кроме этого, создать в целевой папке файл "dovecot-shared", то это позволит каждому пользователю устанавливать свои "\SEEN" на письма в этом каталоге (помечать как просмотренные персонально для себя, не меняя флаг для других пользователей).

ВАЖНО! Каталоги type = public требуют настройки ACL, иначе они будут недоступны. Самое простое в указанном выше примере - установить глобальный ACL в соответствующем каталоге, создав файл .DEFAULT. Для примера приведенного выше, это может быть что-то вроде /etc/dovecot/acl/public/.DEFAULT с соответствующими разрешениями. См. также заметку Dovecot 2 - ACL.

Кроме того нужно помнить о том, что корневая публичная папка сама по-себе не является почтовым каталогом и не будет содержать писем, пока вручную не будут созданы все требуемые подпапки формата Maildir (cur, new, tmp). Тогда же она станет доступна для подписки. При этом вложенные папки, если они созданы, например через MUA, будут доступны для подписки и могут быть почтовыми каталогами.

Подробнее о namespace - см. выше.

Аутентификация

За аутентификацию, в рассматриваемовом в этой серии заметок частном случае конфигурации, отвечает такие файлы:

  • /etc/dovecot/conf.d/10-auth.conf - указывается подключение (include) файла "auth-sql.conf.ext".
  • /etc/dovecot/conf.d/auth-sql.conf.ext - описаны механизмы подключения. Драйвер - sql для passdb, и драйвер - prefetch для userdb, и т.п.
  • /etc/dovecot/dovecot-sql.conf.ext - содержит запросы к базе данных ("password_query" и "user_query").

10-auth.conf
Содержит много настроек, но самое интересное в самом низу - там, например можно убрать комментирование со строки, инклудящей файл "auth-sql.conf.ext", а остальные "include" закомментить.


auth-sql.conf.ext
В этом файле настраиваются две секции, которые реализуют механизм "prefetch". Идея в том, что можно сократить количество SQL-запросов и все нужные значения вытаскивать сразу в "password_query". В этом случае, в секции "userdb" нужно указать "driver = prefetch". Но надо учитывать два нюанса. Во-первых ко всем параметрам "userdb", получаемым через "password_query", надо будет в запросе (см. далее) добавлять префикс "userdb_". Во-вторых секцию "userdb" по-видимому нужно будет указать дважды, т.к. есть случаи, когда она нужна в полном виде. При этом очередность в этом повторе имеет значение. Первой должна идти секция с "driver = prefetch". См. ниже примеры.


dovecot-sql.conf.ext
Файл содержит собственно сами запросы ("password_query" и "user_query"). В запросах, кроме стандартных полей можно указывать т.н. экстра-поля, в которых определять некоторые более глубокие настройки. Подробнее см. в официальной документации (страница со ссылками - см. ниже).


Здесь описываются примеры для одного конкретного частного случая конфигурации почтовой системы.

Все это может быть реализовано, например так.

/etc/dovecot/conf.d/10-auth.conf :

...
!include auth-sql.conf.ext
...

/etc/dovecot/conf.d/auth-sql.conf.ext :

passdb {
  driver = sql
  args = /etc/dovecot/dovecot-sql.conf.ext
}
userdb {
  driver = prefetch
}
userdb {
  driver = sql
  args = /etc/dovecot/dovecot-sql.conf.ext
}

/etc/dovecot/conf.d/dovecot-sql.conf.ext :

driver = mysql
default_pass_scheme = PLAIN-MD5
connect = host=127.0.0.1 dbname=_ИМЯ_БАЗЫ_ user=_ИМЯ_ПОЛЬЗОВАТЕЛЯ_ password=_ПАРОЛЬ_ПОЛЬЗОВАТЕЛЯ_SQL_
password_query = SELECT username AS user, password, IF(username = 'use@domain.tld', 'yes', 'no') AS 'userdb_namespace/inbox2/list' ... FROM mailbox WHERE username = '%u'
user_query = SELECT CONCAT('/home/vmail/', maildir) AS home, 5000 AS uid, 5000 AS gid, CONCAT('*:storage=', quota, 'B') as quota_rule FROM mailbox WHERE username = '%u'

Пример проверенных полных конфигов, см. в заметке Полный пример установки всех пакетов и настройки конфигурационных файлов.

Авторизация для LMTP см. выше.

Авторизация мастер-пользователя

Мастер-пользователь имеет расширенные возможности - он может входить в систему под другими пользователями.

Для этого есть два метода:

  1. Указать логин пользователя в механизме аутентификации SASL в поле ID.
  2. Указать логин мастер-пользователя в том-же поле, что имя обычного пользователя. Для этого должен быть указан разделитель в параметре auth_master_user_separator. UW-IMAP использует "*" в качестве разделителя, так что это может быть хорошим выбором. В этом случае вход должен осуществляться под логином "login_user*master_user".

Необходимо в секции passdb { ... } указать параметр master=yes (например, в файле "auth-sql.conf.ext"). Мастер-пользователь не может войти в систему самостоятельно под своим логином, - он должен входить под логином других пользователей. Это означает, что он не должен присутствовать в userdb { ... } .

Желательно также указать параметр pass=yes. Он означает, что перед допуском мастер-пользователя, будет проверено наличие логина обычного пользователя, указанного при авторизации вместе с мастер-пользователем. При этом, если обычный пользователь не существует, то, в зависимости от конфигурации, может быть возвращена ошибка, либо этот пользователь автоматически будет создан. Этот параметр не будет работать с PAM или LDAP при auth_bind=yes, поскольку в этом случае, при проверке обычного пользователя, обязательно присутствие также и его пароля. Тестирование показало, что проблемы возникают и у мастер-пользователя, при попытке отправить сообщение от имени пользователя, под которым он зашел, если на сервере включена авторизация для любых сетей (Postfix-smtpd выдает ошибку авторизации).

Если необходимо, чтобы мастер-пользователь мог осуществлять вход самостоятельно, а не только под другим пользователем, то нужно добавить вначале еще одну секцию passdb { ... } с параметром master=yes - для мастер-пользователей. Тогда, при входе "login_user*master_user" будет срабатывать секция, в которой указан master=yes, а при обычном входе, даже для мастер-пользователя будет срабатывать секция без этого параметра.

Кроме того, для мастер-пользователя может понадобится настроить ACL (если это используется), поскольку он изначально не будет иметь никаких разрешений. Одним из вариантов решения, может быть указание параметра master_user=%u в секции userdb { ... } . См. также раздел ACL для мастер-пользователя, в заметке Dovecot 2 - ACL.

КСТАТИ! Клиент RoundCube имеет плагин dovecot_impersonate, который позволяет использовать родной адрес пользователя. Впрочем тестирование показало, что для отправки от его имени это не срабатывает, если на smtpd включена авторизация для всех.

Файлы конфигурации могут выглядеть при этом примерно так:

Пример 1

Это пример из официальной документации с небольшими добавлениями

/etc/dovecot/conf.d/auth-sql.conf.ext :

auth_master_user_separator = *
passdb {
  driver = sql
  args = /etc/dovecot/dovecot-sql-master.conf.ext
  master = yes
  pass = yes
}
passdb {
  driver = sql
  args = /etc/dovecot/dovecot-sql.conf.ext
}
userdb {
  driver = sql
  args = /etc/dovecot/dovecot-sql.conf.ext
}

Файл с параметрами SQL для обычных пользователей может содержать примерно такую строку

/etc/dovecot/dovecot-sql.conf.ext :

...
password_query = SELECT password FROM users WHERE userid = '%u'
...

А файл с параметрами SQL для мастер-пользователя может содержать примерно такую строку

/etc/dovecot/dovecot-sql-master.conf.ext :

...
password_query = SELECT password FROM users WHERE userid = '%u' AND master_user = true
...

В этом случае в таблице "users" должно быть поле "master_user".
ВАЖНО! Если удалить проверку этого поля из запроса или использовать в обоих случаях одинаковый запрос, то, при том что master = yes, то каждый сможет быть мастер-пользователем.

Пример 2

В этом примере используется база PostfixAdmin, а в качестве мастер-пользователя - администратор PostfixAdmin.

Файл /etc/dovecot/conf.d/auth-sql.conf.ext - такой же, как в примере выше.

Файл с параметрами SQL для обычных пользователей может содержать примерно такие строки

/etc/dovecot/dovecot-sql.conf.ext :

...

password_query = SELECT username as user, password FROM mailbox WHERE userid = '%u' AND active = '1'

user_query = SELECT '%u' AS master_user, ... FROM mailbox WHERE username = '%u' AND active = '1'

...

А файл с параметрами SQL для мастер-пользователя может содержать примерно такие строки

/etc/dovecot/dovecot-sql-master.conf.ext :

driver = mysql

default_pass_scheme = PLAIN-MD5

connect = host=127.0.0.1 dbname=_ИМЯ_БАЗЫ_ user=_ИМЯ_ПОЛЬЗОВАТЕЛЯ_ password=_ПАРОЛЬ_ПОЛЬЗОВАТЕЛЯ_SQL_

password_query = SELECT username AS user, password FROM admin WHERE username = '%u' AND active = '1'

Тестирование
# telnet 127.0.0.1 143
* OK Dovecot ready.
1 login loginuser*masteruser masterpass
1 OK Logged in.

При проблемах можно указать параметр auth_debug=yes и посмотреть логи.


Виртуальные папки (плагин virtual)

В этом разделе - чистая отсебятина. Официальная документация показалась мне недостаточно ясной, поэтому, для быстрого знакомства с плагином и понимания его работы, лучше для начала рассмотреть пару примеров. Настоятельно рекомендую после всех ознакомительных экспериментов перечитать официальную документацию по плагину (см. раздел Источники).

ВАЖНО! Плагин не всегда правильно обрабатывает ошибки. В некоторых ситуациях, когда допущена ошибка - он продолжает работать, но глючит.

Плагин virtual позволяет создавать виртуальные каталоги.

Они доступны в MUA как отдельные папки, но изначально в них ничего не отображается, - в них нужно добавлять нечто вроде поискового фильтра, описанного в файле "dovecot-virtual" (для каждой папки/подпапки - свой файл). Используются IMAP LIST-совместимые шаблоны и IMAP SEARCH команды, описанные в RFC 3501. Например, можно сделать так, что в виртуальной папке "Folder1" будут отображаться только сообщения отправленные за последние два дня.

ВАЖНО! В виртуальных папках письма физически не хранятся! Они только отображают письма из других папок в соответствие с правилами, описанными в файлах "dovecot-virtual".

  • * - все совпадения из namespace с пустым prefix =
  • mail* - совпадения в каталогах, начинающихся с mail из namespace с пустым prefix =
  • mail/* - совпадения из namespace с prefix = "mail/"

Разберем несколько примеров.
В них проведем эксперименты на базе настроенной системы, в которой почта виртуальных пользователей хранится в каталоге: /home/vmail/%d/%n , в формате Maildir, где %d - имя домена, а %n - краткое имя текущего пользователя (например пользователь "user").

Пример 1

Для начала добавим плагин в нужные файлы конфигурации и подключим соответствующий namespace { ... } .

Это может быть примерно так

/etc/dovecot/conf.d/20-imap.conf :

protocol imap {
...
  mail_plugins = $mail_plugins ... virtual
...
}

/etc/dovecot/conf.d/20-lmtp.conf :

protocol lmtp {
...
  mail_plugins = $mail_plugins ... virtual
...
}

/etc/dovecot/conf.d/15-lda.conf :

protocol lda {
...
  mail_plugins = ... virtual
...
}

В следующем файле этот параметр нужно указать глобально - вне всяких секций. Возможно в будущем это изменится.

/etc/dovecot/conf.d/20-managesieve.conf :

...
mail_plugins = virtual
...

/etc/dovecot/conf.d/10-mail.conf :

...
namespace virt {
  prefix = virtual/
  separator = /
  location = virtual:/home/vmail/%d/%n/virtual
  inbox = no
  hidden = yes
  list = yes
  subscriptions = yes
}
...

# service dovecot reload

Теперь у каждого пользователя автоматически будет создана (при первом же доступе) папка "virtual" в корневом почтовом каталоге. Пока она пуста, - она не будет доступна нигде в MUA (например RoundCube), кроме настроек (где она пока будет только видна в списке, но тоже недоступна). Имя папки: "virtual" берется из параметра prefix = virtual/ .

Создадим в этой папке подпапку и внутри нее - специальный файл, содержащий фильтр для папки "Отправленные"

# mkdir /home/vmail/domain.tld/user/virtual/Folder1

Создадим этот самый магический файл

# nano /home/vmail/domain.tld/user/virtual/Folder1/dovecot-virtual :

Sent
  all younger 172800

В настройках MUA RoundCube подпишем эту папку. Теперь можем зайти в нее в основном интерфейсе RoundCube и увидеть письма папки "Отправленные" ("Sent") за последние 48 часов (172800 сек).

Сейчас типичная картина скорее всего будет такой: попытки удалить из MUA саму папку "Folder1" или добавить к ней подпапку приведут к ошибке, так же как и попытки добавить еще одну подпапку в пространстве "virtual". Удаление из папки "Folder1" письма - приводит к удалению его из основной папки, к которой был применен фильтр ("Sent"). Копирование письма в эту папку - приводит к ошибке.

Пример 2

Можно создать единую для всех пользователей папку "virual" с файлами-правилами.

Это может выглядеть примерно так

/etc/dovecot/conf.d/20-imap.conf :

protocol imap {
...
  mail_plugins = $mail_plugins ... virtual
...
}

/etc/dovecot/conf.d/20-lmtp.conf :

protocol lmtp {
...
  mail_plugins = $mail_plugins ... virtual
...
}

/etc/dovecot/conf.d/15-lda.conf :

protocol lda {
...
  mail_plugins = ... virtual
...
}

В следующем файле этот параметр нужно указать глобально - вне всяких секций. Возможно в будущем это изменится.

/etc/dovecot/conf.d/20-managesieve.conf :

...
mail_plugins = virtual
...

/etc/dovecot/conf.d/10-mail.conf :

...
namespace virt {
  prefix = virtual/
  separator = /
  location = virtual:/etc/dovecot/virtual:INDEX=/home/vmail/%d/%n/virtual_index
  inbox = no
  hidden = yes
  list = yes
  subscriptions = yes
}
...

Здесь в параметре location = , для всех пользователей указан общий виртуальный каталог, но индексы будут хранится для каждого в его родном почтовом каталоге. Можно здесь же персонализировать информацию о подписке - см. ниже.

Создадим папку для всех пользователей и тестовую подпапку "Folder1" с файлом "dovecot-virtual" (папку с индексами "virtual_index" создавать не нужно - она создастся автоматически):

# mkdir /etc/dovecot/virtual
# mkdir /etc/dovecot/virtual/Folder1
# chown -hR vmail:vmail /etc/dovecot/virtual
# chmod -R 700 /etc/dovecot/virtual

В дальнейшем для всех подпапок внутри /etc/dovecot/virtual нужно будет так же изменять владельца и права.

Повторим содержимое файла из предыдущего примера, но уже в другой папке (с правами на файл проблем быть не должно)

# nano /etc/dovecot/virtual/Folder1/dovecot-virtual :

Sent
  all younger 172800

# service dovecot reload

Подпишем в MUA Roundcube новую папку и убедимся что фильтр работает - в папке должны быть отображены письма из "Отправленные" только за последние 48 часов (172800 сек). При этом видеть папку будет каждый пользователь, но отображаться в ней у каждого будут только его письма из папки "Отправленные", а индексы будут находится в его родном почтовом каталоге.

Сейчас любой пользователь, подписавшись на эту папку сделает ее отображаемой для всех, а отписавшись - не отображаемой также для всех.
Простейший способ изменить ситуацию - подписать папку и изменить права на корневой каталог:
# chmod 500 /etc/dovecot/virtual
В этом случае никто не сможет отписаться от папки.

Можно также в файле /etc/dovecot/conf.d/10-mail.conf добавить нечто вроде:

namespace virt {
...
  mailbox Folder1 {
    auto=subscribe
  }
...
}

Кроме того можно указать в параметре location = ... :CONTROL=/home/vmail/%d/%n/virtual_index . В этом случае каждый может подписываться-отписываться самостоятельно.

А запретить всё, кроме просмотра и чтения писем для виртуального каталога, можно при помощи глобального ACL, примерно так:

# mkdir /etc/dovecot/acl/domain.tld/virtual

# nano /etc/dovecot/acl/domain.tld/virtual/Folder1 :

owner lr

l - просмотр, r - чтение.
Кроме того, чтобы запретить пользователям писать в каталог свои ACL, можно поступить аналогично подписке - изменить права доступа для каталога: # chmod 500 /etc/dovecot/virtual/Folder1 .
См. также заметку Dovecot 2 - ACL

Еще простые примеры файла "dovecot-virtual"

Все письма из "Входящие" и "Отправленные" - в одной виртуальной папке. В комбинации со стилем отображения "Обсуждения" (RoundCube) - показывает ветки дискуссий:

INBOX
Sent
   all

Все письма из "Входящие" и письма за последние 48 часов из папки "Отправленные" - в одной виртуальной папке. В комбинации со стилем отображения "Обсуждения" (RoundCube) - показывает ветки дискуссий:

INBOX
   all
Sent
   all younger 172800

Все непросмотренные письма из "Входящие":

INBOX
  unseen

Разрешает перемещать письма в виртуальную папку (необходимо настроить или отключить ACL). Все перемещенные в папку письма попадают во "Входящие". Тестирование показало, что допускается указание только одной папки для записи (с восклицательным знаком вначале). При этом отображается содержимое двух указанных папок:

!INBOX
Drafts
  all

Все сообщения всех папок за исключением папки "Trash":

*
-Trash
  all

Создав еще одну виртуальную папку "Folder2", запишем в нее правила выбирающие из "Folder1" все письма INBOX, и, в дополнение к ним, - те письма из любых других папок, которые связанны с письмами в INBOX. В комбинации со стилем отображения "Обсуждения" (RoundCube) - показывает ветки дискуссий.

/etc/dovecot/virtual/Folder1/dovecot-virtual :

*
  all

/etc/dovecot/virtual/Folder2/dovecot-virtual :

virtual/Folder1
  inthread refs x-mailbox INBOX

Пример 3

Предыдущие примеры относились в большей степени к папкам и письмам одного пользователя, подразумевая namespace с пустым prefix = . Проведем дополнительный эксперимент для дополнительных namespace. Причем создадим дополнительный namespace, который будет отображать папки всех пользователей определенного домена.

ВАЖНО! Этот пример приведен исключительно в ознакомительных целях, только для большей наглядности возможностей плагина virtual. Последствия могут быть разрушительными, - рекомендуется сделать копию почтового каталога или проводить эксперимент на тестовом сервере.

Конфиг с пространствами имен может выглядеть примерно так

/etc/dovecot/conf.d/10-mail.conf :

mail_location = maildir:/home/vmail/%d/%n:INBOX=/home/vmail/%d/%n
namespace inbox {
type = private
separator = /
prefix = 
inbox = yes
hidden = no
list = yes
subscriptions = yes
}
namespace virt {
  prefix = virtual/
  separator = /
  location = virtual:/etc/dovecot/virtual:INDEX=/home/vmail/%d/%n/virtual_index
  inbox = no
  hidden = yes
  list = no
  subscriptions = yes
}
namespace users {
  type = private
  separator = /
  prefix = "alldomain/%d/"
  location = maildir:/home/vmail/%d:LAYOUT=fs
  inbox = no
  hidden = yes
  list = no
  subscriptions = no
}

Остальные конфиги и последовательность создания папки Folder1 - такие же, как в Пример 2.

Файл виртуальной папки, при этом может выглядеть так

# nano /etc/dovecot/virtual/Folder1/dovecot-virtual :

alldomain/domain.tld/*/.Sent
   all

alldomain/ - первая часть префикса пространства "users".
domain.tld - домен админа: "%d" (вторая часть префикса, - здесь домен указан явно).
/*/ - корневые папки ящиков всех пользователей
.Sent - подпапки в пространстве "users" отображаются с точкой, т.к. :LAYOUT=fs .

Результатом выборки будет отображение всех писем всех папок ".Sent" всех пользователей домена "domain.tld".

Для того чтобы namespace virt { ... } было доступно, например, только пользователю, являющемуся одновременно админом PostfixAdmin, можно доработать упомянутый выше SQL-запрос примерно так (для namespace users { ... } даже при list = no виртуальная папка будет работать, когда она доступна):

password_query = SELECT IF (CHAR_LENGTH(admin.username) > 0, 'yes', 'no') AS 'userdb_namespace/virt/list', ... FROM mailbox LEFT JOIN admin ON mailbox.username = admin.username WHERE mailbox.username = '%u' AND mailbox.active = '1'

Запрос должен быть одной строкой! Запрос заточен под использование механизма "prefetch" для "userdb". Если он не используется, а используется полноценный второй запрос user_query = , то 'userdb_namespace/virt/list' должно выглядеть в нем как 'namespace/virt/list' (без префикса userdb_).

КСТАТИ! Если добавить в запрос что-то вроде , IF (CHAR_LENGTH(admin.username) > 0, 'yes', 'no') AS 'userdb_namespace/users/list' , то для админа PostfixAdmin появится возможность подписать папки всех пользователей и отображать их, например в MUA RoundCube. Впрочем, это, как и весь этот пример - только в целях эксперимента, поэтому желательно сделать предварительную копию всех писем. Одним из побочных эффектов эксперимента, может оказаться засорение каталога /home/vmail/domain.tld/ файлами и папками типичными для каталога формата Maildir.

ВАЖНО! Этот пример нужно пробовать с осторожностью, желательно на тестовом сервере, т.к. в каталоге домена при некоторых условиях (например при использовании определенных ACL настроек в файлах .DEFAULT), могут появиться папки tmp, new и cur, которые могут совпасть с именами каталогов пользователей.
Если же делать что-то подобное всерьез (а не только в ознакомительных целях), то начать нужно с того, что сменить тип namespace на public.
См. комментарий под примером выше. См. также заметку Dovecot 2 - ACL

Здесь просто-таки напрашивается плагин для MUA, который позволил бы управлять виртуальными папками через web-интерфейс. Но для RoundCube я ничего подобного не нашел.


Как убрать фантомные папки (lda-dupes и т.п.)

Если используется Sieve и расширения vacation, vnd.dovecot.duplicate, а также redirect и т.п., то в настройках становится доступна "папка" lda-dupes. На самом деле это на папка, а служебный файл этих расширений ".dovecot.lda-dupes", начинающийся с точки.

ВАЖНО! Все, что начинается с точки, воспринимается в Maildir как imap-папка.

Может быть этот файл был назван так нарочно, чтобы пользователь мог самостоятельно его удалять в настройках MUA, в случае сбоя упомянутых расширений, но у меня с его удалением были проблемы ("...failed: Not a directory" (c))

По-видимому имеет смысл его скрыть. Это можно сделать с помощью глобального ACL примерно так

# mkdir /etc/dovecot/acl/domain.tld/dovecot/

# nano /etc/dovecot/acl/domain.tld/dovecot/lda-dupes :

anyone rp

Аналогично можно скрывать другие папки. Параметры rp здесь нужны для того, чтобы к файлу/"папке" был доступ у LDA (для корректной отработки Sieve). См. также заметку Dovecot 2 - ACL


Откуда может появляться папка "name" в каталогах пользователей

Когда я знакомился и экспериментировал с Dovecot, у меня на каком-то этапе стала автоматически создаваться папка "name" в каталоге каждого ящика, которая была доступна для подписки. Очень долго не мог понять откуда она берется, и в конце-концов махнул рукой. Потом случайно обнаружил ее в одном из конфигурационных файлов Dovecot, где она присутствует в качестве примера. Очевидно я после установки экспериментировал с этим файлом и раскомментировал auto = create . :)

Это файл /etc/dovecot/conf.d/15-mailboxes.conf :

...
namespace inbox {
...
  mailbox name {
...
     auto = create
...
   }
...
}
...

Ее можно закомментировать, либо переименовать весь файл, например

# mv /etc/dovecot/conf.d/15-mailboxes.conf /etc/dovecot/conf.d/15-mailboxes.conf_


Переменные

Специальные переменные можно использовать в нескольких местах:

  • Для mail_location и в namespace
  • В static userdb и passwd-file userdb, в строке шаблона
  • В LDAP и SQL userdb строке запроса
  • log префикс для imap/pop3 процессов
  • В настройках плагинов

Переменные, которые работают почти везде:

Переменная Полное имя Описание
%% Символ "%" и некоторые расширенные значения с соотв. символом
%u user Полное имя (напр.: user@domain.tld)
%n username Левая часть в user@domain.tld (т.е. только "user")
%d domain Доменная часть в user@domain.tld (т.е. только "domain.tld")
%s service imap, pop3, smtp, lda (и doveadm, dsync, и т.п.)
%p pid PID текущего процесса (login или imap/pop3 процесс)
%l lip Локальный IP-адрес
%r rip Удаленный IP-адрес
session ID сессии для текущего клиента (уникальное в промежутке 9 лет) (для версии 2.16 и выше)

Следующие переменные работают почти везде, за исключением Dovecot-auth (userdb запросы/шаблоны):

Переменная Полное имя Описание
%h home Домашний каталог
%i uid ID UNIX пользователя
gid ID UNIX группы (для версий 2.0.17 и выше)

Следующие переменные работают только для Dovecot-AUTH и login_log_format_elements:

Переменная Полное имя Описание
%m mech Механизм аутентификации, напр. PLAIN
%a lport Локальный порт
%b rport Удаленный порт
%c secured "secured"-строка SSL/TLS и localhost соединений. Может быть пустой (empty).
real_rip По типу %{rip}, за исключением настроек прокси, содержащих IP удаленных прокси клиентов (с версии 2.1.10)
real_lip По типу %{lip}, за исключением настроек прокси, содержащих IP локальных прокси (с версии 2.2)
real_rport По типу %{real_rip}, за исключением портов вместо IP
real_lport По типу %{real_lip}, за исключением, за исключением портов вместо IP

Следующие переменные работают только для Dovecot-AUTH:

Переменная Полное имя Описание
%w password plaintext пароль для plaintext-механизма аутентификации
%k cert "valid", если клиент передал валидный сертификат, в противном случае - пусто (empty)
login_user Для master-user входа: user@domain вошедшего
login_username Для master-user входа: user вошедшего
login_domain Для master-user входа: domain вошедшего

Следующие переменные работать только для login_log_format_elements:

Переменная Полное имя Описание
%k ssl_security SSL-протокол и информация шифра, напр.: "TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)"
%e mail_pid PID mail-процесса (imap/pop3), который обрабатывает сообщение post-login соединения

Следующие переменные работать только для deliver_log_format:

Переменная Полное имя Описание
%$ Запись log-журнала
%m msgid Message-ID
%s subject Subject
%f from Адрес "From"
%e from_envelope Оболочка отправителя
%p size Размер сообщения
%w vsize Виртуальный размер сообщения
  • Полные имена переменных могут использоваться как %{long_name} или с "L"-модификатором: %L{long_name}
  • Переменные среды могут быть доступны в %{env:ENVIRONMENT_VARIABLE}
  • Дополнительно представлены очевидные переменные %{pid} и %{hostname}

Модификаторы - применимые для каждой переменной (напр.: %Us = POP3)

  • %L - нижний регистр
  • %U - верхний регистр
  • %E - экранирование символов " ' \ автоматически добавляя "\" перед ними (для SQL-запросов это не нужно)
  • %X - парсинг переменной как 10-ичного числа и перевод в 16-ричное
  • %R - представление значения переменной в обратном порядке
  • %H - 32-битный хеш значения переменной, возвращенный в десятичном виде (подробнее - в офиц. док.).
  • %M - возвращает строку MD5 в десятичном виде
  • %D - возвращает "sub.domain.org" как "sub,dc=domain,dc=org" (для LDAP запросов)
  • %T - удаляет пробелы вначале и в конце

Вы можете получить субстроку переменной и опционально, используя '.' указать смещение и количество символов субстроки. Например %2u дает первые два символа имени пользователя. %2.1u дает один, - третий символ имени пользователя.

Если смещение отрицательное, оно считается с конца, на длину после '.' (точки). Например %-2.2i дает "45" для UID 12345 (последние два знака UID в строке){Информация требует проверки}. Если смещение положительное и точка за пределами значения, то возвращается пустая строка, если смещение отрицательное за пределами значения, то строка начинается со старта.

Если ширина с префиксом, равном 0 (ноль), строка просто дополняется '0 ', и только если она короче. Например i может вернуть "0001", "1000" или "12345"{Информация требует проверки}. %1.04i вернет для этих строк "001", "000" и "2345".

Модификаторы применяются слева направо, исключая субстроку взятую от конца строки.


XEXEC Plugin

Интересное экспериментальное расширение IMAP-протокола (плагин), позволяющее запускать любые приложения на стороне сервера по команде MUA с установленными соответствующими плагинами (например Thunderbird). Можно сделать так, что отправка сообщений для MUA будет происходить без использования SMTP. Достаточно переместить сообщение в нужную папку и... и т.д. :) В официальном описании упоминается возможное применение в составе Groupware и т.п.


Источники

Источники информации и ссылки перечислены на отдельной странице, указанной внизу главной страницы темы:
Установка и настройка почтового сервера

Рекламные ссылки:
Комментариев: 2 RSS

Так и не разобрался как реализовать поддержку вложенных подпапок если имена подпапок начинаются на "."

Например .INBOX/.Subfolder

2 Richard

Любые подпапки надо создавать в корневой папке ящика пользователя, но с использованием точки в качестве разделителя "почтовых" папок. Для INBOX это выглядит так: "/user/.INBOX.Subfolder"

При этом ".INBOX.Subfolder" - имя одной реальной папки.

Также надо правильно указать права и владельца этой папки, и включить подпапку в MUA если нужно.

P.S.

Название вложенной подпапки для Sent будет таким: "/user/.Sent.Subfolder"

Вопросы по теме статьи (просьба - без личностей), - присутствует премодерация:
   - регистрироваться НЕ обязательно! -

Комментарий будет опубликован только после проверки

Вы можете войти под своим логином или зарегистрироваться на сайте.

(обязательно)