Files
2026-07-14 13:35:56 +07:00

7.1 KiB
Raw Permalink Blame History

mcimport — массовое создание ящиков mailcow из CSV

Однобинарный инструмент (stdlib-only Go, embedded веб-морда) для провижининга почтовых ящиков mailcow через API. Импорт файла → предпросмотр с валидацией → потоковый журнал создания.

Интерфейс mcimport: подключение к API и предпросмотр импорта

Возможности

  • Проверка подключения к API (домены/ящики читаются, чтобы подтвердить ключ и allow-list).
  • Выбор домена: после проверки подключения можно выбрать домен из списка mailcow — тогда в CSV достаточно логина без @домена (email собирается как логин@выбранный_домен).
  • Предпросмотр: разбор CSV, структурная валидация (email, пароль, дубликаты), плюс — если задан ключ — сверка с живым mailcow: пропуск существующих ящиков и отсев несуществующих доменов.
  • Импорт с потоковым (NDJSON) журналом в реальном времени: по строке на ящик, разбор ответа mailcow (success/danger), счётчики, выгрузка лога в CSV.

Формат CSV

Заголовок обязателен. Разделитель — точка с запятой (;); также распознаются , и таб. BOM снимается, кодировка — UTF-8. Готовый образец можно скачать в UI (ссылка «Скачать пример CSV») или по GET /api/example.

С выбранным в UI доменом достаточно логина:

login;password;name
ivanov;S3cretPass!;Иван Иванов
petrov;An0therPass!;Пётр Петров

Без выбора домена — полный email в каждой строке:

email;password;name
ivanov@bildme.ru;S3cretPass!;Иван Иванов
petrov@amega.kz;An0therPass!;Пётр Петров

Колонки (регистр/пробелы/подчёркивания не важны, есть RU-алиасы):

колонка обяз. примечание
email / login да* при выбранном домене — логин без @; иначе полный email или пара localpart + domain
password да <8 символов → предупреждение
name нет ФИО; по умолчанию = localpart
quota нет МиБ; иначе «квота по умолчанию»
active нет 1/0, по умолчанию 1

Запуск

Бинарь

CGO_ENABLED=0 go build -ldflags="-s -w" -o mcimport .
MAILCOW_URL=https://mail.dom.ru ./mcimport
# открыть http://localhost:8080

Docker

docker compose up -d --build
# морда на 127.0.0.1:8080 — ходите через SSH-туннель:
# ssh -L 8080:127.0.0.1:8080 user@host

Переменные окружения

переменная по умолчанию назначение
MAILCOW_URL базовый URL (можно ввести в UI)
MAILCOW_API_KEY Read-Write ключ; если задан — не вводится в UI
DEFAULT_QUOTA 10240 квота по умолчанию, МиБ
LISTEN :8080 адрес прослушивания
INSECURE_SKIP_VERIFY false отключить проверку TLS (внутренний CA)

Что нужно на стороне mailcow

  1. UI → Configuration → Access → Edit administrator details → API: создать ключ с правами Read-Write.
  2. В API_ALLOW_FROM добавить IP, с которого mcimport ходит в API (egress-IP контейнера/хоста). Иначе — отказ доступа.
  3. Убедиться, что лимит «Максимум почтовых ящиков» у домена и квоты домена покрывают импортируемую пачку.

Общая квота домена (частая ошибка mailbox_quota_left_exceeded)

mailcow не даст создать ящик, если Σ выделенных квот ящиков домена превысит Domain quota (общую квоту домена). Это не про квоту одного ящика — ставить её в 0 (безлимит) не нужно. Предпросмотр (при заданном ключе) заранее считает нехватку и останавливает импорт с подсказкой, до какого значения поднять Domain quota.

Поднять квоту домена: mailcow UI → домен → «Domain quota», либо один вызов API:

curl -sk -X POST https://mail.dom.ru/api/v1/edit/domain \
  -H "X-API-Key: $KEY" -H "Content-Type: application/json" \
  -d '{"items":["a27.kz"],"attr":{"quota":"307200"}}'   # 300 ГБ (МиБ)

После правки — в UI кнопка «Повторить проверку» (перепроверить без загрузки файла) или «Повторить неудавшиеся» в журнале (досоздать только упавшие ящики).

Замечания по безопасности

  • Инструмент stateless: ключ и пароли нигде не пишутся на диск и не логируются. Пароли из CSV во время предпросмотра проходят через браузер (внутренний тул) — запускайте только в доверенной сети / за туннелем, не публикуйте наружу.
  • Публикация порта в примере — только на 127.0.0.1.
  • Слабые пароли mailcow отклонит по политике; такие строки видны в предпросмотре как предупреждение и в журнале как danger: password_complexity.