Удаление старых писем Dovecot

В данной записи речь пойдет о автоматической очистке старых писем в Dovecot. Очистка осуществляя по дате сообщения, все письма старше года будут удалены. За исключением писем помеченных звездочкой.

Создаем скрипт:

nano /usr/local/sbin/dovecot-cleanup

Вставляем в содержимое файла:

#!/usr/bin/env bash
set -euo pipefail

PASSWD_FILE="${PASSWD_FILE:-/etc/dovecot/passwd}"
RETENTION="${RETENTION:-365d}"   # срок хранения
DATE_KEY="${DATE_KEY:-before}"   # before (INTERNALDATE) или savedbefore
DRY_RUN="${DRY_RUN:-0}"          # 1 = только показать (search), 0 = удалять (expunge)

# Не трогаем Archive и её подпапки: Archive, Archive/..., Archive...., INBOX.Archive..., INBOX/Archive...
KEEP_RE='(^|[./])Archive($|[./])'

# Не удаляем письма со "звездочкой" (\Flagged) — чистим только UNFLAGGED
FLAG_FILTER="UNFLAGGED"

cmd="expunge"
[[ "$DRY_RUN" == "1" ]] && cmd="search"

# Берём список пользователей из passwd-файла (1-е поле до двоеточия), игнорируем пустые/комментарии
awk -F: '!/^[[:space:]]*($|#)/{print $1}' "$PASSWD_FILE" | while IFS= read -r user; do
  [[ -z "$user" ]] && continue

  # Список папок конкретного юзера
  doveadm mailbox list -u "$user" '*' | while IFS= read -r mbox; do
    [[ -z "$mbox" ]] && continue

    # Пропускаем Archive и подпапки
    if [[ "$mbox" =~ $KEEP_RE ]]; then
      continue
    fi

    # Удаляем (или ищем при DRY_RUN=1) письма старше RETENTION, но только НЕ помеченные звездой
    doveadm "$cmd" -u "$user" mailbox "$mbox" "$DATE_KEY" "$RETENTION" "$FLAG_FILTER"
  done
done

Даем права на запуск файла:

chmod +x /usr/local/sbin/dovecot-cleanup

Создаем сервис:

nano /etc/systemd/system/dovecot-cleanup.service

Добавляем в содержимое файла:

[Unit]
Description=Dovecot cleanup

[Service]
Type=oneshot
Environment=PASSWD_FILE=/etc/dovecot/passwd
Environment=RETENTION=365d
Environment=DATE_KEY=before
Environment=DRY_RUN=0
ExecStart=/usr/bin/nice -n 10 /usr/local/sbin/dovecot-cleanup

Создаем таймер:

nano /etc/systemd/system/dovecot-cleanup.timer
[Unit]
Description=Daily Dovecot cleanup

[Timer]
OnCalendar=daily
Persistent=true

[Install]
WantedBy=timers.target

Применяем настройки и выполняем проверку работы сервиса:

systemctl daemon-reload
systemctl enable --now dovecot-cleanup.timer

# статус
systemctl status dovecot-cleanup.timer
systemctl list-timers --all | grep dovecot-cleanup

# лог последнего прогона сервиса
journalctl -u dovecot-cleanup.service -n 200 --no-pager

Настройка Dovecot

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

pacman -S dovecot
# dovecot --version
2.4.2 (0962ed2104)

Включаем автозагрузку:

systemctl enable dovecot

Создай пользователя и группу vmail:

getent passwd vmail || useradd -r -d /srv/mail -s /usr/bin/nologin vmail
getent group vmail  || groupadd -r vmail
usermod -g vmail vmail 2>/dev/null || true

Назначим права на каталог почты:

install -d -o vmail -g vmail -m 0770 /srv/mail
chown -R vmail:vmail /srv/mail

Открываем конфигурационный файл:

nano /etc/dovecot/dovecot.conf

Сотрите все содержимое файла и добавьте параметры ниже.

# -------------------------------------------------------------------
# Include / modular config
# -------------------------------------------------------------------
!include_try conf.d/*.conf


# -------------------------------------------------------------------
# Protocols
# Enable the required protocols:
# - IMAP for mailbox access
# - LMTP for local mail delivery (e.g., from Postfix)
# -------------------------------------------------------------------
protocols {
  imap = yes
  lmtp = yes
}

service imap {
  vsz_limit = 512M
}

# -------------------------------------------------------------------
# Mail storage (Maildir)
# Store mail in Maildir format under user's home directory
# -------------------------------------------------------------------

mail_driver = maildir
mail_path = ~/Maildir

namespace inbox {
  inbox = yes
  separator = /

  mailbox Trash {
    auto = subscribe
    special_use = \Trash
  }
  mailbox Junk {
    auto = subscribe
    special_use = \Junk
  }
}

# -------------------------------------------------------------------
# Authentication (virtual users from file, no PAM)
# IMPORTANT:
# Do NOT use PAM to avoid binding authentication to system users.
# Authenticate virtual users from a password file instead.
# -------------------------------------------------------------------
auth_username_format = %{user | username}
auth_mechanisms = plain login

passdb passwd-file {
  passwd_file_path = /etc/dovecot/passwd
}

userdb static {
  fields {
    uid  = vmail
    gid  = vmail
    home = /srv/mail/%{user | username}
  }
}

# -------------------------------------------------------------------
# TLS / SSL
# Require TLS and use Let's Encrypt certificates
# -------------------------------------------------------------------
ssl = required
ssl_server {
  cert_file = /etc/letsencrypt/live/mx.codebeer.ru/fullchain.pem
  key_file  = /etc/letsencrypt/live/mx.codebeer.ru/privkey.pem
  dh_file   = /etc/dovecot/dh.pem
}

ssl_server_prefer_ciphers = server
ssl_min_protocol = TLSv1.2


# -------------------------------------------------------------------
# Services / sockets for Postfix integration
# -------------------------------------------------------------------
# LMTP socket for Postfix -> Dovecot delivery (to Maildir)
service lmtp {
  unix_listener /var/spool/postfix/private/dovecot-lmtp {
    mode = 0600
    user = postfix
    group = postfix
  }
}

# SASL auth socket for Postfix (submission/587)
service auth {
  unix_listener /var/spool/postfix/private/auth {
    mode = 0660
    user = postfix
    group = postfix
  }
}

Обратите внимание на строки:

cert_file = /etc/letsencrypt/live/mx.codebeer.ru/fullchain.pem
key_file  = /etc/letsencrypt/live/mx.codebeer.ru/privkey.pem

Здесь нужно указать свой путь к файлам сертификата и ключа.
Далее необходимо сгенерировать сертификат Диффи-Хелмана:

openssl dhparam -out /etc/dovecot/dh.pem 4096

Откройте /etc/postfix/main.cf
Добавьте в конец файла:

local_transport = lmtp:unix:private/dovecot-lmtp
local_recipient_maps =

Проверить/создать директорию /var/spool/postfix/private

ls -ld /var/spool/postfix /var/spool/postfix/private || true
getent passwd postfix
getent group postfix
install -d -m 0755 -o postfix -g postfix /var/spool/postfix/private

Примените настройки:

postfix check
systemctl restart dovecot
systemctl restart postfix

Далее необходимо создать файл с логинами и паролями, для подключения пользователей к почтовому серверу.
В примере ниже, я создаю аккаунт admin:

PASS='yFUTHESZIoqvLtFkbqiXbPypxIUQfcPL'
HASH="$(doveadm pw -s BLF-CRYPT -p "$PASS")"

printf "admin:%s\n" "$HASH" | tee -a /etc/dovecot/passwd >/dev/null
chown root:dovecot /etc/dovecot/passwd
chmod 640 /etc/dovecot/passwd

Перезапускаем Dovecot

systemctl restart dovecot

Включаем автозагрузку Dovecot, делаем рестарт сервиса, проверяем состояние процесса.

mkdir -p /etc/systemd/system/dovecot.service.d

cat > /etc/systemd/system/dovecot.service.d/restart.conf <<'EOF'
[Unit]
StartLimitIntervalSec=300
StartLimitBurst=5

[Service]
Restart=on-failure
RestartSec=5s
EOF

Применяем настройки:

systemctl daemon-reload
systemctl restart dovecot

Проверим, что Dovecot подымается после падения:

kill -9 $(pidof dovecot | awk '{print $1}')
sleep 2
systemctl --no-pager -l status dovecot
journalctl -u dovecot -n 30 --no-pager

После настройки необходимо выполнить базовую проверку работы авторизации:

doveadm auth test 'admin' 'ТВОЙ_ПАРОЛЬ'

Должно отобразится сообщение:

passdb: admin auth succeeded
extra fields:
  user=admin

Отправка тестового сообщения:

echo test | sendmail -v [email protected]
Mail Delivery Status Report will be mailed to .
# find /srv/mail/admin/Maildir -maxdepth 2 -type f \( -path '*/new/*' -o -path '*/cur/*' \) | tail
/srv/mail/admin/Maildir/cur/1770504820.M330643P8692.mx.codebeer.ru,S=1006,W=1029:2,a
/srv/mail/admin/Maildir/cur/1770504816.M697890P8676.mx.codebeer.ru,S=1006,W=1029:2,a

Настройка виртуальных алиасов

Необходимо создать файл алисов /etc/postfix/virtual

Добавьте в содержимое по аналогии:

[email protected]      [email protected]
[email protected]     [email protected]
[email protected]          [email protected]
[email protected]  [email protected]

Подключаем файл алисов в конфиге main.cf:

nano /etc/postfix/main.cf

Добавьте в конец файла:

virtual_alias_maps = lmdb:/etc/postfix/virtual

Применяем настройки:

postmap /etc/postfix/virtual
systemctl reload postfix

Включаем загрузку Postfix после запуска сервиса Dovecot:

systemctl edit postfix.service

Добавляем строки:

[Unit]
After=dovecot.service
Wants=dovecot.service

Применяем настройки:

systemctl daemon-reload
systemctl restart postfix