Grommunio

Материал из wiki.nntc.nnov.ru
Версия от 11:54, 31 июля 2026; Vovan (обсуждение | вклад) (→‎Скрипт переноса всех ящиков из Zimbra в Grommunio)
Перейти к навигации Перейти к поиску

Развёртывание

Где брать, как ставить

Для развёртывания на PVE можно прямо в хранилище PVE затащить образ по ссылке

https://download.grommunio.com/appliance/grommunio.x86_64-latest.install.iso

Ставить по этой инструкции

https://docs.grommunio.com/admin/installation/

Если ваши будущие емэйлы будут вида

user@myorg.net

То нужно ориентироваться на домены

mail.myorg.net

и

myorg.net

при инсталляции.


Порты 80 и 443 должны быть зарулены на сервер, если предполагается настройка сертификатов инсталлером через LestsEncrypt!


После инсталляции админка будет доступна на порту

8443

и туда входить нужно только по логину (не по полной почте).

Т.е. только по

admin

, а не по

admin@myorg.net


А в веб интерфейсе почты -- наоборот. Он находится по стандартному порту

443

и туда входим по

admin@myorg.net

, а не по

admin


Остальные порты важны будут при эксплуатации и при развёртывании их можно не забрасывать, о них -- ниже.

Порты

Порт Протокол Сервис / Назначение в Grommunio
25 TCP SMTP — входящая почта (передача между почтовыми серверами)
80 TCP HTTP — веб-интерфейс (перенаправление на HTTPS / Let's Encrypt)
110 TCP POP3 — получение почты (незашифрованный)
143 TCP IMAP — получение почты (незашифрованный / STARTTLS)
443 TCP HTTPS — Grommunio Web (Webmail), Outlook (EAS/MAPI over HTTP), Admin API
465 TCP SMTPS — защищённая отправка почты клиентами (SSL/TLS)
587 TCP SMTP Submission — отправка почты клиентами (STARTTLS)
993 TCP IMAPS — защищённое получение почты (SSL/TLS)
995 TCP POP3S — защищённое получение почты (SSL/TLS)
5349 TCP STUN/TURN (coturn) — установка видеосоединений Jitsi за NAT (HTTPS/TLS)
8443 TCP Grommunio Admin Admin Web Console — веб-панель администратора
10000 UDP Jitsi Videobridge — медиапоток (аудио, видео, шеринг экрана)

Записи для домена

Инструкция по проверке DNS-записей почтового сервера (myorg.net)
Назначение Тип Команда для проверки Ожидаемый результат
Маршрутизация почты MX dig MX myorg.net +short 1 mail.myorg.net.
IP-адрес узла A dig A mail.myorg.net +short 37.1.2.3
Обратная зона (PTR) PTR dig -x 37.1.2.3 +short mail.myorg.net.
Разрешенные отправители (SPF) TXT dig TXT myorg.net +short | grep spf "v=spf1 a mx ip4:37.1.2.3 ~all"
Цифровая подпись (DKIM) TXT dig TXT mailserver._domainkey.myorg.net +short "v=DKIM1; k=rsa; p=MIGfMA...AFwIDAQAB"
Политика безопасности (DMARC) TXT dig TXT _dmarc.myorg.net +short "v=DMARC1; p=quarantine; rua=mailto:admin@myorg.net"


БОльшую часть из этой информации можно также получить из формы настроек домена из админки grommunio.

Но есть нюанс с двумя записями:

1. Обратная зона (PTR) -- её невозможно настроить в админке провайдера днс зоны. Её должен настроить провайдер, выдающий интернет для почтового сервера и статический айпи адрес для него. Здесь необходимо добиться от интернет-провайдера, чтобы на его стороне была прописана эта самая обратная зона PTR. Суть в том, чтобы происходил процесс наоборот: по айпи адресу -- выдавался домен. Для почтовых серверов это важно!

2. Цифровая подпись (DKIM) -- чтобы корректно работала эта запись, сначала её необходимо настроить. Об этом подробно написано ниже!

3. Разрешенные отправители (SPF) -- здесь также должен фигурировать статический айпи адрес почтового сервера.

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

Настроить подпись писем через DKIM

Действия мышкой в админке

Сначала внутри админки нужно создать домен и перейти в форму управления этим доменом.

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

С этими умолчаниями пользователи будут создаваться, если их создавать из админки.


Для настройки подписи через DKIM нужно нажать соответствующую кнопку в форме управления доменом. В открывшемся окне выполнить создание ключевой пары для подписи.

Выбрать алгоритм RSA и selector. По умолчанию selector имеет значение

dkim

, но можно установить свой. Этот селектор будет использован при настройке TXT записи для почтового домена.

Например, можно выбрать селектор

mailserver


В ответ на запрос генерации ключей придёт примерно такой шаблон для настройки TXT записи для домена:

mailserver._domainkey IN TXT ( "v=DKIM1; k=rsa; "
	"p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAs/D2gdESmBR0TqqeZ42wXCsEjGpPOB7uxp4uY0De+297hKs3XV+1CehUu5BxXxKKeJJIKRzogvzzOj76AXWMpiF5LS4oOUd3I+I+H8aCAC69QuV/TKHuB0Qqv7c8S54dw4210fHOSMMwVYlzfRGeyPfrKBcfZi4v98j7jh2on5f5btiaeppkUgUxMOPjTRepl3VzxTkID9cLrIEDc"
	"iA3nVMXbkj4wULMNSL3IjfuW4MRIJ6a4zZZqOECjrhBiSgAies+l0yh/+mn3LQmVcjba0RTuxa7x5xuf21AnKZvv0uZeQrROd0WrbLYGLFRO2Nk6/jUQPaPHS3ThDggbXz3RwIDAQAB"
) ; 

и будет сказано что ключ лежит где-то здесь:

The private key has been generated on the server at
/var/lib/grommunio-admin-api/myorg.net.mailserver.key

Этот путь до файла ключа будет нужен потом при настройке сервера по ssh.

Настройка сервера по ssh

Для доступа по ssh под root лучше сразу получить на сервер открытую часть ssh ключа и настроить конфиг ssh для быстрого подключения. Под root на сервер по паролю подключиться не получится. А через виртуальный дисплей виртуальной машины нельзя будет скопировать текст на сервер.

Поэтому самый верный вариант - зайти на сервер через виртуальный дисплей виртуальной машины, скопировать через scp открытую часть ключа с другой машины по сети, затем перейти на другую машину и подключаться по ключу с ней на сервер.


Войдя по ssh на сервер необходимо сделать ряд настроек:

Если ваш домен:

myorg.net

а селектор

mailserver 

1. Создаём каталог

mkdir -p /var/lib/grommunio-antispam/dkim/myorg.net

2. Копируем тот самый файл, путь к которому нам сообщили в веб интерфейсе в предыдущем пункте в файл с названием селектора в только что созданный каталог

cp /var/lib/grommunio-admin-api/myorg.net.mailserver.key /var/lib/grommunio-antispam/dkim/myorg.net/mailserver.key

3. Создайм файл

cat << 'EOF' > /etc/grommunio-antispam/override.d/dkim_signing.conf
enabled = true;
sign_authenticated = true;
sign_local = true;

domain {
    "myorg.net" {
        path = "/var/lib/grommunio-antispam/dkim/myorg.net/mailserver.key";
        selector = "mailserver";
    }
}

use_domain = "header";

4. Устанавливаем права доступа на каталог и файл

chown -R groas:grommunio /var/lib/grommunio-antispam/dkim/
chmod 600 /var/lib/grommunio-antispam/dkim/myorg.net/mailserver.key

5. Перезапустить сервисы

systemctl restart grommunio-antispam
systemctl restart postfix

Настройка TXT записи для домена

Эта настройка делается в веб панели управления доменом. В зависимости от того, где арендован домен. Например, reg.ru, beget.com и т.д...


Нюанс

Веб админка выдала на генерацию ключей что-то типа того:

mailserver._domainkey IN TXT ( "v=DKIM1; k=rsa; "
	"p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAs/D2gdESmBR0TqqeZ42wXCsEjGpPOB7uxp4uY0De+297hKs3XV+1CehUu5BxXxKKeJJIKRzogvzzOj76AXWMpiF5LS4oOUd3I+I+H8aCAC69QuV/TKHuB0Qqv7c8S54dw4210fHOSMMwVYlzfRGeyPfrKBcfZi4v98j7jh2on5f5btiaeppkUgUxMOPjTRepl3VzxTkID9cLrIEDc"
	"iA3nVMXbkj4wULMNSL3IjfuW4MRIJ6a4zZZqOECjrhBiSgAies+l0yh/+mn3LQmVcjba0RTuxa7x5xuf21AnKZvv0uZeQrROd0WrbLYGLFRO2Nk6/jUQPaPHS3ThDggbXz3RwIDAQAB"
) ; 

Это на самом деле означает, что значение TXT записи

mailserver._domainkey

в веб админке провайдера днс должно быть таким:

v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAs/D2gdESmBR0TqqeZ42wXCsEjGpPOB7uxp4uY0De+297hKs3XV+1CehUu5BxXxKKeJJIKRzogvzzOj76AXWMpiF5LS4oOUd3I+I+H8aCAC69QuV/TKHuB0Qqv7c8S54dw4210fHOSMMwVYlzfRGeyPfrKBcfZi4v98j7jh2on5f5btiaeppkUgUxMOPjTRepl3VzxTkID9cLrIEDciA3nVMXbkj4wULMNSL3IjfuW4MRIJ6a4zZZqOECjrhBiSgAies+l0yh/+mn3LQmVcjba0RTuxa7x5xuf21AnKZvv0uZeQrROd0WrbLYGLFRO2Nk6/jUQPaPHS3ThDggbXz3RwIDAQAB

, а на строчки оно разбивается по некоторым историческим причинам, суть которых в ограничении длины строки. Видимо, особенности протокола DNS...

Перед тем, как конфигурировать TXT запись на уровне DNS необходимо свериться: точно ли у ключа, который ранее был скопирован в файл

/var/lib/grommunio-antispam/dkim/myorg.net/mailserver.key

base64 строка соответствует значению ключа

p=

из значения для TXT записи, приведённой выше.

Получить этот ключ можно следующим образом:

openssl rsa -in /var/lib/grommunio-antispam/dkim/myorg.net/mailserver.key -pubout -outform DER 2>/dev/null | base64 -w 0

В ответ придёт что-то вроде:

MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAs/D2gdESmBR0TqqeZ42wXCsEjGpPOB7uxp4uY0De+297hKs3XV+1CehUu5BxXxKKeJJIKRzogvzzOj76AXWMpiF5LS4oOUd3I+I+H8aCAC69QuV/TKHuB0Qqv7c8S54dw4210fHOSMMwVYlzfRGeyPfrKBcfZi4v98j7jh2on5f5btiaeppkUgUxMOPjTRepl3VzxTkID9cLrIEDciA3nVMXbkj4wULMNSL3IjfuW4MRIJ6a4zZZqOECjrhBiSgAies+l0yh/+mn3LQmVcjba0RTuxa7x5xuf21AnKZvv0uZeQrROd0WrbLYGLFRO2Nk6/jUQPaPHS3ThDggbXz3RwIDAQAB

В теории (в теории, но на практике было и по другому. Это надо проверить ещй раз!) эти ключи должны совпадать. Т.е. ключ, который с переносами и кавычками был выдан веб интеряейсом, и ключ, который выдала команда выше -- должны быть одинаковы. Ведь файл ключа одинаковый (мы его просто скопировали для донастройки grommunio-antispam)!

Но на практике было и так что команда

openssl rsa -in...

выдавала ключ, который отличается. Если ключи будут отличаться, то в значение

p=

для DNS записи необходимо заменить на значение, полученное от команды:

openssl rsa -in...


Далее в веб-админке DNS сервера добавляем запись типа

TXT

, поддомен которой должен быть такой (полный домен имеется в виду такой: mailserver._domainkey.myorg.net)

mailserver._domainkey

, а его значением должно быть

v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAs/D2gdESmBR0TqqeZ42wXCsEjGpPOB7uxp4uY0De+297hKs3XV+1CehUu5BxXxKKeJJIKRzogvzzOj76AXWMpiF5LS4oOUd3I+I+H8aCAC69QuV/TKHuB0Qqv7c8S54dw4210fHOSMMwVYlzfRGeyPfrKBcfZi4v98j7jh2on5f5btiaeppkUgUxMOPjTRepl3VzxTkID9cLrIEDciA3nVMXbkj4wULMNSL3IjfuW4MRIJ6a4zZZqOECjrhBiSgAies+l0yh/+mn3LQmVcjba0RTuxa7x5xuf21AnKZvv0uZeQrROd0WrbLYGLFRO2Nk6/jUQPaPHS3ThDggbXz3RwIDAQAB

т.е. в общем виде так:

v=DKIM1; k=rsa; p=<результат, полученный от команды openssl rsa -in...>

Проверка TXT записи

После того, как TXT запись домена проделегируется проверить это можно командой:

dig TXT mailserver._domainkey.myorg.net +short

в ответ должно прийти что-то типа

"v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAs/D2gdESmBR0TqqeZ42wXCsEjGpPOB7uxp4uY0De+297hKs3XV+1CehUu5BxXxKKeJJIKRzogvzzOj76AXWMpiF5LS4oOUd3I+I+H8aCAC69QuV/TKHuB0Qqv7c8S54dw4210fHOSMMwVYlzfRGeyPfrKBcfZi4v98j7jh2on5f5btiaeppkUgUxMOPjTRepl3VzxTkID9cLrIEDciA3nVMXbkj4wULMNSL3IjfuW4MRIJ6a4zZZqOECjrhBiSgAies+l0yh/+mn3LQmVcjba0RTuxa7x5xuf21AnKZvv0uZeQrROd0WrbLYGLFRO2Nk6/jUQPaPHS3ThDggbXz3RwIDAQAB"

здесь важно проверить что значение

p=

соответствует той самой base64 строке, которая выше была получена через

openssl rsa -in...


Проверка работы механизма подписи емэйлов

Войти в веб интерфейс почты (не в админку по https://mail.myorg.net:8443, а просто на https://mail.myorg.net) любым ящиком, который есть в домене и отправить с него письмо куда-нибудь себе на ящик (gmail, yandex и.т.д...).

У себя в аккаунте (gmail, yandex и.т.д...) ищем исходники письма (это обычно PlainText) и там должны быть такие строки:

Раз! Само наличие этой строки говорит о том, что сервер стал подписывать письма!

DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=myorg.net; s=mailserver; t=1785189679; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type; bh=ckTMbuexoDGBdcu/luc2eNS+Ap0k9i9yjhltmXYdzGo=; b=BOe7sXr+EW6iTfZdDVCxA8gZ2gXBw3KcWC2PFALvbi6inSXlO/u3cZCLtEcBCJ9/accyFP Hn1W2qHSKEeY1B8Ri5SqqUoXBO7bEc5IPOr0dYyrivABFsT+Zr7XNeDUHlC6Lbt7YvaI4z vatOvc5T+qzDv/bqu685KqqK33PRQiY=

Но это ещё не всё... Необходимо проверить проверку этой подписи. Здесь как раз важно, чтобы TXT запись у домена была корректна.


Два!

Для этого также ищем среди исходинка письма следующую строку:

Authentication-Results: mx.google.com; dkim=pass header.i=@myorg.net header.s=mailserver header.b=BOe7sXr+; spf=pass (google.com: domain of admin@myorg.net designates 37.112.130.81 as permitted sender) smtp.mailfrom=admin@myorg.net; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=myorg.net

Здесь важно увидеть

dkim=pass

и

spf=pass

После этого можно проверить работу сервера через внешний сервис

https://mail-tester.com/

При корректной настройке почтового сервера этот сервис должен показать 10 из 10 возможных "попугаев".

Важно! У сервиса этого есть ограничения на кол-во проверок в сутки. Потом он просит денюжку или ждать следующего дня. Поэтому сначала проверяем текст в исходниках письма, как описано выше, и только потом - через сервис.

Скрипты и автоматизация

Все скрипты, представленные здесь, запускать необходимо с сервера Grommunio!


Скрипт создания одного ящика

cat << 'EOF' > create_mailbox.sh 
#!/bin/bash
USER_GROMMUNIO="$1"
PASS_GROMMUNIO="$2"

# Проверка входных параметров
if [ -z "$USER_GROMMUNIO" ] || [ -z "$PASS_GROMMUNIO" ]; then
    echo "Использование: $0 <user_grommunio> <pass_grommunio>"
    echo "Пример: $0 user@domain.ru 'ThePass'"
    exit 1
fi

echo "=== 1. Проверка / Создание ящика $USER_GROMMUNIO в Grommunio ==="

# Проверяем наличие ящика
if grommunio-admin user show "$USER_GROMMUNIO" >/dev/null 2>&1; then
    echo "i Ящик $USER_GROMMUNIO уже существует. Пропускаем создание."
else
    echo "Пользователь не найден. Создаём ящик $USER_GROMMUNIO..."

    DISPLAY_NAME=$(echo "$USER_GROMMUNIO" | cut -d'@' -f1)

    # Создаем юзера
    grommunio-admin user create "$USER_GROMMUNIO"
    if [ $? -ne 0 ]; then
        echo "Ошибка создания пользователя $USER_GROMMUNIO!"
        exit 1
    fi

    # Устанавливаем свойства пользователю
    grommunio-admin user modify \
		--property givenname="$DISPLAY_NAME" \
		--property surname="$DISPLAY_NAME" \
		--property displayname="$DISPLAY_NAME" \
		--property country="Russian Federation" \
		"$USER_GROMMUNIO"
    if [ $? -ne 0 ]; then
        echo "Ошибка установки свойств пользователя $USER_GROMMUNIO!"
        exit 1
    fi

    # Задаем пароль
    grommunio-admin passwd --password "$PASS_GROMMUNIO" "$USER_GROMMUNIO"
    if [ $? -ne 0 ]; then
        echo "Ошибка установки пароля для $USER_GROMMUNIO!"
        exit 1
    fi

    echo "✓ Ящик $USER_GROMMUNIO успешно создан и пароль установлен."
fi
EOF

chmod +x create_mailbox.sh


Скрипт переноса одного ящика из Zimbra в Grommunio

Для работы скрипта необходимо наличие рядом предыдущего скрипта (create_mailbox.sh)

А также внутри скрипта необходимо задать адрес сервера Zimbra и логин и пароль мастер-аккаунта Zimbra


cat << 'EOF' > migrate_account_from_zimbra_to_grommunio.sh
#!/bin/bash

# Настройки серверов
ZIMBRA_SERVER="192.168.0.1"
GROMMUNIO_SERVER="127.0.0.1"

# Мастер-аккаунт с Zimbra с паролем
ZIMBRA_ADMIN_USER="admin@myorg.net"
ZIMBRA_ADMIN_PASS="SuperAdminPassword"

# Определяем директорию, в которой расположен текущий скрипт
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
CREATE_SCRIPT="$SCRIPT_DIR/create_mailbox.sh"

# Чтение аргументов
USER_ZIMBRA="$1"
USER_GROMMUNIO="$2"
PASS_GROMMUNIO="$3"

# Проверка входных параметров
if [ -z "$USER_ZIMBRA" ] || [ -z "$USER_GROMMUNIO" ] || [ -z "$PASS_GROMMUNIO" ]; then
    echo "Использование: $0 <mailbox_zimbra> <mailbox_grommunio> <pass_grommunio>"
    echo "Пример: $0 old_user@domain.ru new_user@domain.ru 'GromPass'"
    exit 1
fi

# Проверка наличия и прав на выполнение вспомогательного скрипта
if [ ! -f "$CREATE_SCRIPT" ]; then
    echo "Ошибка: Вспомогательный скрипт '$CREATE_SCRIPT' не найден!"
    exit 1
fi

if [ ! -x "$CREATE_SCRIPT" ]; then
    echo "Ошибка: Скрипт '$CREATE_SCRIPT' найден, но не имеет прав на выполнение (chmod +x)!"
    exit 1
fi

# Вызов внешнего скрипта для создания ящика
"$CREATE_SCRIPT" "$USER_GROMMUNIO" "$PASS_GROMMUNIO"
if [ $? -ne 0 ]; then
    echo "Ошибка при подготовке ящика $USER_GROMMUNIO через $CREATE_SCRIPT"
    exit 1
fi

echo "=== 2. Запуск переноса почты из Zimbra в Grommunio ==="

set -x

# Создаем временные защищенные файлы для паролей
PASSFILE1=$(mktemp)
PASSFILE2=$(mktemp)

printf '%s' "$ZIMBRA_ADMIN_PASS" > "$PASSFILE1"
printf '%s' "$PASS_GROMMUNIO" > "$PASSFILE2"

imapsync \
  --host1 "$ZIMBRA_SERVER" \
  --user1 "$USER_ZIMBRA" \
  --authuser1 "$ZIMBRA_ADMIN_USER" \
  --passfile1 "$PASSFILE1" \
  --authmech1 PLAIN \
  --ssl1 \
  --sslargs1 SSL_verify_mode=0 \
  --host2 "$GROMMUNIO_SERVER" \
  --user2 "$USER_GROMMUNIO" \
  --passfile2 "$PASSFILE2" \
  --authmech2 LOGIN \
  --ssl2 \
  --sslargs2 SSL_verify_mode=0 \
  --useheader "Message-ID" \
  --automap \
  --f1f2 "Sent=&BB4EQgQ,BEAEMAQyBDsENQQ9BD0ESwQ1-" \
  --f1f2 "Trash=&BCMENAQwBDsENQQ9BD0ESwQ1-" \
  --f1f2 "Junk=&BB0ENQQ2BDUEOwQwBEIENQQ7BEwEPQQwBE8- &BD8EPgRHBEIEMA-" \
  --f1f2 "Drafts=&BCcENQRABD0EPgQyBDgEOgQ4-" \
  --noauthmd5

# если не надо синхронизировать спам и корзину
#  --exclude "Junk" \
#  --exclude "Trash" \

# Удаляем временные файлы с паролями
rm -f "$PASSFILE1" "$PASSFILE2"
EOF

chmod +x migrate_account_from_zimbra_to_grommunio.sh

Скрипт переноса всех ящиков из Zimbra в Grommunio

Для работы скрипта необходимо наличие рядом предыдущего скрипта (migrate_account_from_zimbra_to_grommunio.sh, для которого необходимо наличие предпредыдущего скрипта (create_mailbox.sh))

Чтобы скрипт знал какие ящики переносить необходимо создать файл mailboxes.txt, в котором одна строчка - один ящик. Например так:

cat << 'EOF' > mailboxes.txt
admin@myorg.net
manager@myorg.net
EOF


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

Файл с данными новых ящиков будет называться:

migrated_passwords.csv

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

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


Сам скрипт:

cat << 'EOF' > migrate_all_zimbra_accounts.sh 
#!/bin/bash

TARGET_SCRIPT="./migrate_account_from_zimbra_to_grommunio.sh"
MAILBOXES_FILE="mailboxes.txt"
OUTPUT_CSV="migrated_passwords.csv"

if [ ! -f "$TARGET_SCRIPT" ]; then
  echo "Ошибка: Исполняемый файл '$TARGET_SCRIPT' не найден!" >&2
  exit 1
fi

if [ ! -x "$TARGET_SCRIPT" ]; then
  echo "Ошибка: Файл '$TARGET_SCRIPT' существует, но у него нет прав на выполнение (chmod +x)!" >&2
  exit 1
fi

if [ ! -f "$MAILBOXES_FILE" ]; then
  echo "Ошибка: Файл со списком ящиков '$MAILBOXES_FILE' не найден!" >&2
  exit 1
fi

generate_password() {
  # 16 символов: буквы (разного регистра), цифры и безопасные спецсимволы
  LC_ALL=C tr -dc 'A-Za-z0-9' < /dev/urandom | head -c 16
}

# Инициализация / очистка CSV файла
echo "Email;Password" > "$OUTPUT_CSV"

OUTPUT_CSV_BACKUP="${OUTPUT_CSV%.csv}_$(date +%Y-%m-%d-%H-%M-%S).csv"

if [ -f "$OUTPUT_CSV" ]; then
  cp "$OUTPUT_CSV" "$OUTPUT_CSV_BACKUP"
  echo "Создан бэкап предыдущего CSV: $OUTPUT_CSV_BACKUP"
fi

echo "Все проверки пройдены. Начинаем обработку списков..."
echo "------------------------------------------------"

while read ACCOUNT; do
  # Пропускаем пустые строки
  [ -z "$ACCOUNT" ] && continue

  NEW_PASS=$(generate_password)

  echo "Обработка ящика: $ACCOUNT"

  echo "Сохраняем данные аккаунта ${ACCOUNT} в файл $OUTPUT_CSV"
  echo "${ACCOUNT};${NEW_PASS}" >> "$OUTPUT_CSV"

  echo "Начата синхронизация аккаунта ${ACCOUNT}..."
  if "$TARGET_SCRIPT" "$ACCOUNT" "$ACCOUNT" "$NEW_PASS"; then
    echo "Успешно: $ACCOUNT"
  else
    echo "ОШИБКА: Сбой при обработке $ACCOUNT" >&2
  fi

  echo "------------------------------------------------"

done < "$MAILBOXES_FILE"

echo "Готово! Сгенерированные пароли сохранены в файл: $OUTPUT_CSV"
EOF

chmod +x migrate_all_zimbra_accounts.sh 

Особенности работы и способы починки

Ошибки входа в веб интерфейс

После нескольких итераций создания/удаления пользователя с одинаковым емэйлом веб интерфейс почтового ящика (не админский интерфейс на порту 8443, а обычный - на порту 443) показывает невменяемые ошибки прав доступа.

Как конкретно это решить без перезагрузки сервера до сих пор выяснить не удалось.

Но перезагрузка сервера - точно решает большинство таких проблем. Наверное, даже, все.

Кратко: ошибка где-то в кешах сессий или что-то в этом роде.

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

Комьюнити версия не разрешает создавать больше 5 учётных записей почты на домен

Чтобы создавать больше - нужно покупать лицензию. Или...

Открываем файл

/usr/share/grommunio-admin-api/orm/users.py

Ищем там строчки по

License user limit exceeded

Включаем скилл программиста и комментируем по вкусу. Затем перезагружаемся.

В этом разделе специально подробно не описан процесс решения этой проблемы - из-за солидарности с разработчиками продукта.