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

114 lines
7.1 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# mcimport — массовое создание ящиков mailcow из CSV
Однобинарный инструмент (stdlib-only Go, embedded веб-морда) для провижининга
почтовых ящиков mailcow через API. Импорт файла → предпросмотр с валидацией →
потоковый журнал создания.
![Интерфейс mcimport: подключение к API и предпросмотр импорта](pic1.png)
## Возможности
- **Проверка подключения** к API (домены/ящики читаются, чтобы подтвердить ключ и allow-list).
- **Выбор домена**: после проверки подключения можно выбрать домен из списка mailcow —
тогда в CSV достаточно логина без `@домена` (email собирается как `логин@выбранный_домен`).
- **Предпросмотр**: разбор CSV, структурная валидация (email, пароль, дубликаты),
плюс — если задан ключ — сверка с живым mailcow: пропуск существующих ящиков и
отсев несуществующих доменов.
- **Импорт** с потоковым (NDJSON) журналом в реальном времени: по строке на ящик,
разбор ответа mailcow (`success`/`danger`), счётчики, выгрузка лога в CSV.
## Формат CSV
Заголовок обязателен. Разделитель — точка с запятой (`;`); также распознаются
`,` и таб. BOM снимается, кодировка — UTF-8. Готовый образец можно скачать в UI
(ссылка «Скачать пример CSV») или по `GET /api/example`.
С выбранным в UI доменом достаточно логина:
```csv
login;password;name
ivanov;S3cretPass!;Иван Иванов
petrov;An0therPass!;Пётр Петров
```
Без выбора домена — полный email в каждой строке:
```csv
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` |
## Запуск
### Бинарь
```bash
CGO_ENABLED=0 go build -ldflags="-s -w" -o mcimport .
MAILCOW_URL=https://mail.dom.ru ./mcimport
# открыть http://localhost:8080
```
### Docker
```bash
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:
```bash
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`.