Удаление старых писем 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