Zimbra
Zimbra Collaboration Suite (ZCS) — программный продукт для автоматизации совместной деятельности рабочих групп, аналог MS Exchange, включает в себя ряд бесплатных и открытых продуктов (Apache, MySQL, Postfix и др.), предоставляя сервисы почты, обмена быстрыми сообщениями (jabber), общие документы и календари и т.д. Есть как платные так и бесплатные версии ZCS, мы будем устанавливать последнюю.
Содержание
Подготовка ОС
Так как Zimbrа несёт с собой много ПО, то её лучше устанавливать на отдельный сервер, или по крайней мере перед остальными приложениями.
Удаление других почтовых программ
на Debian удаляем все пакеты почтового сервера exim4
# apt-get remove exim4-base exim4-config
Установка необходимых пакетов
Устанавливаем необходимые дополнительные пакеты (удовлетворяем зависимости).
# apt-get install libstdc++5 sysstat
Настройка МХ записи и имени домена
- Убедимся, что настроен правильно MX на hostname сервера, куда устанавливается Zimbra
# dig mx mail.domain.ru ;; ANSWER SECTION: mail.domain.ru. 3600 IN MX 10 domain.ru. ;; ADDITIONAL SECTION: domain.ru. 1882 IN A 94.94.94.94
- Добавляем в /etc/hosts соответствующую запись вида:
94.94.94.94 mail.domain.ru mail
Установка Zimbra
Распаковываем дистрибутив Zimbra и запускаем install.sh. Если каких-то пакетов не хватает, то установщик скажет об этом и их нужно будет доустановить.
Настройка Zimbra
Настройка почтового домена
После установки зайдём на web интерфейс сервера пользователем admin и перейдём по ссылке "Администратор домена", где настроим:
Конфигурация - Класс обслуживания - default
Конфигурация - Домены - mail.domain.ru
Перенос учётных записей
Перенесём (импортируем) учётные записи из предыдущей почтовой системы. У меня использовался Postfix под управлением PostfixAdmin.
#!/usr/bin/php // Postfixadmin (http://postfixadmin.sourceforge.net/) to Zimbra // (www.zimbra.com) migration script // // History: // Based on work from: Jaros Baw Czarniak // Enhanced by NERvOus (www.nervous.it) on 1-12-2009 <?php ///////////////////////////////////////////////////////// $user="postfix"; $pass="postfixadmin"; $db="postfix"; $table_mbox="mailbox"; $table_alias="alias"; $file="import.sh"; ///////////////////////////////////////////////////////// echo "This script generates a bash script called: $file The script contains the commands to re-create the mboxes and aliases on zimbra server.\n\n "; $mydb = mysql_connect('localhost',$user, $pass) or die ('Error connecting to server'); mysql_select_db($db); mysql_query("SET CHARACTER SET utf8"); mysql_query("SET NAMES utf8"); $query = "SELECT username,password,name,maildir,quota,domain FROM $table_mbox"; $dane = mysql_query($query) or die ('Error during query for '.mysql_error()); echo "Writing to $file ...\n"; $fh = fopen($file, "w"); fwrite($fh, "#!/bin/sh -x\n\n"); while ($row = mysql_fetch_array($dane, MYSQL_NUM)) { $data_mbox = "zmprov ca ".$row[0]." dsfs123hsdyfgbsdgfbsd displayName '".$row[2]."'\n"; $data_mbox .= "zmprov ma ".$row[0]." userPassword '{crypt}".$row[1]."'"."\n"; fwrite($fh, $data_mbox); } // skip domain aliases, aliases that forward to themselves and aliases // for which a mbox exists $query = "SELECT address, trim(trailing ',' from goto) AS dest FROM ".$table_alias." WHERE address NOT LIKE '@%' AND address NOT IN (SELECT username FROM $table_mbox) HAVING address != dest"; $dane = mysql_query($query) or die ('Error during query for '.mysql_error()); while ($row = mysql_fetch_array($dane, MYSQL_NUM)) { // multiple dests unset($rawdest_r); unset($dest_r); $rawdest_r = preg_split('/,/', $row[1]); foreach ($rawdest_r as $dest) { if ($dest != $row[0]) { // don't forward to itself $dest_r[] = $dest; } } if (count($dest_r) > 1) { // distribution list $data_list .= "zmprov cdl $row[0]\n"; foreach ($dest_r as $dest) { $data_list .= "zmprov adlm $row[0] $dest\n"; } } if (count($dest_r) == 1) { preg_match('/@(.*)$/', $row[0], $matches); $acct_domain = $matches[0]; preg_match('/@(.*)$/', $dest_r[0], $matches); $alias_domain = $matches[0]; if ($acct_domain == $alias_domain) { // we are adding an alias, not a forward // try to create alias both for a normal // account and for a distribution list. One of the // commands will fail, pity. $data_alias .= "zmprov aaa $dest_r[0] $row[0]\n"; $data_alias .= "zmprov adla $dest_r[0] $row[0]\n"; } else { // we are adding a forward $data_alias .= "zmprov ca $row[0] " . rand_str(11) . "\n"; $data_alias .= "zmprov ma $row[0] zimbraprefmailforwardingaddress $dest_r[0]\n"; } } } // first create all distribution lists, last all aliases // We cannot create aliases for distribution lists that do not // exist yet fwrite($fh, $data_list . $data_alias); fclose($fh); echo "Done. Now copy $file to zimbra server and run: # su - zimbra $ sh ./$file "; function rand_str($length = 32, $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890') { // Length of character list $chars_length = (strlen($chars) - 1); // Start our string $string = $chars{rand(0, $chars_length)}; // Generate random string for ($i = 1; $i < $length; $i = strlen($string)) { // Grab a random character from our list $r = $chars{rand(0, $chars_length)}; // Make sure the same two characters don't appear next to each // other if ($r != $string{$i - 1}) $string .= $r; } // Return the string return $string; }
Полученный с помощью этого скрипта файл import.sh выполняем на сервере Zimbra.
Скрипт я взял из вики справочника Zimbra. Он полезен, если мы не знаем пароли пользователей, если же мы их знаем, то можно подготовить файл и сделать импорт в Административной консоли управления: Адреса - Учётные записи - Групповая подготовка.
Автоматизация переноса учёток
Почтовая учётная запись создаётся двумя командами:
/opt/zimbra/bin/zmprov ca user@domain.ru userpass displayName "Фамилия Имя Отчество" /opt/zimbra/bin/zmprov ma user@domain.ru userPassword 'userpass'
где userpass - пароль пользователя
Первая команда создаёт пользователя с открытым паролем, вторая - перезаписывает открытый пароль шифрованным (поэтому первый пароль может быть любым).
Если есть список пользоватей и их пароли, то скрипт можно составить, например, в OpenOffice Calc добавить необходимые поля (команды, кавычки), и затем сохранить в формате csv с разделителем "пробел".
Можно сначала создать все учётные записи, а зетем у всех поменять пароль.
Чтобы корректно отображались кирилические буквы, скрипт лучше выполнять от имени root или можно настроить локаль. Проверить настройки локали можно командной:
# echo $LANG ru_RU.UTF-8
а установить командами:
LANG=ru_RU.UTF-8 export $LANG
Перенос писем
Перенесём все письма со старого сервера с помощью программы imapsync, способной синхронизировать почтовые ящики по протоколу IMAP. Эта задача довольно хорошо описана на вики, на основе неё я и написал весь этот пункт. Для выполнения переноса нужно знать пароль старой учётной записи и новой, что не очень удобно для автоматизации процесса. Мы обойдём это требование, воспользовавшись своими администраторскими привилегиями. Для определённсти решим, что у нас почтовый домен mydomain.ru (хотя можно синхронизировать ящики из разных доменов), старый сервер имеет ip адрес 10.0.0.211, а новый - 10.0.0.254 (можно использовать и DNS имена) Краткий алгоритм такой (дальше будет подробней, так что, если не понятно, то не смущайтесь):
- Выберем любой почтовый ящик из переносимого домена, пароль которого мы знаем, скажем, user@mydomain.ru и создадим в его каталоге ссылки на все почтовые ящики (каталоги) домена.
- На новых ящиках придётся временно установить у всех один пароль.
- Синхронизировать ящики на новом сервере будем всегда с одним этим выбранным пользователем, но не весь его каталог, а лишь с тем подкаталогом, который является ссылкой на реальный ящик.
- После синхронизации всех ящиков восстановим пароли.
- Сначала синхронизируем только тот ящик, пароль которого мы знаем и выбрали как основной для последующей синхронизации всех. Это нам заодно поможет выясненить точные настройки подключения к обоим IMAP серверам. создаём скрипт imap_sync_alone.sh:
#!/bin/bash imapsync --nosyncacls --syncinternaldates \ --host1 10.0.0.211 --port1 143 --authmech1 PLAIN --user1 user@mydomain.ru --passfile1 /tmp/zimbra/user \ --host2 10.0.0.254 --ssl2 --port2 993 --authmech2 PLAIN --user2 user@mydomain.ru --passfile2 /tmp/zimbra/user INBOX/ 2> /tmp/zimbra/error.log > /tmp/zimbra/user.log
Этот скрипт можно запустить на любом из серверов. Проверяем журнал, проверяем, что письма перенесены. Теперь займёмся автоманизацией переноса остальных записей.
- На старом сервере создаём ссылки с помощью скрипта create_links.sh:
#!/bin/bash # # Script to create symlinks to all mail dirs # DATE=`date +%Y.%m.%d_%H:%M` LOGFILE="create_links.log" MAILDIR="/var/spool/vmail" ADMINDIR="user@mydomain.ru" echo "$DATE Start to create links" > $LOGFILE # Begin 'for' loop, calling the list of user names for USER in `ls $MAILDIR` do ln -s $MAILDIR/$USER $MAILDIR/$ADMINDIR/.$USER echo Link created for $USER >> $LOGFILE done echo "" >> $LOGFILE echo "Remove admin recursive link: $MAILDIR/$ADMINDIR/.$ADMINDIR" >> $LOGFILE rm -f $MAILDIR/$ADMINDIR/.$ADMINDIR echo "$DATE All done" >> $LOGFILE
- Подготовим скрипт update_pass.sh для восстановления паролей. Для этого используем скрипт import.sh подготовленный во время переноса пользователей:
# cat ./import.sh | grep userPassword > update_pass.sh
проверьте, что в нём остались только записи вида:
zmprov ma user_name@mydomain.ru userPassword '{crypt}$1$18445fb2$8ZPUW9tFPzmT3v4j9SF5Y.'
- Создадим временных каталог и сделаем его общедоступным:
# mkdir /tmp/zimbra # chmod 777 /tmp/zimbra
В нём будем вести журнал выполнения синхронизации, сюда же положим дополнительные файлы
- update_pass.sh - скрипт восстановления паролей
- pass_adm - пароль пользователя user@mydomain.ru
- pass_tmp - единый временный пароль для всех пользователей, я указал 1234567
- userlist - список всех пользователей кому нужно синхронизировать ящик. Этот список можно получить из update_pass.sh, если знать как вытащить из строки подстроку между вторым и третим пробелом. С perl'ом я связываться не хотел, как сделать шелом не знаю, поэтому мне быстрее было вывести этот файл на экран командой cat затем скопировать в OpenOffice Calc разбив столбцы по пробелам и, взяв 3-й столбец, вставить его в редакторе mc в открытый файл userlist. На это ушла минута-две.
- Создадим скрипт для синхронизации всех почтовых ящиков imap_sync_all.sh:
#!/bin/bash # # Script to migrate all imap mailboxes using the single account # DATE=`date +%Y.%m.%d_%H:%M` TMPDIR="/tmp/zimbra" LOGFILE=$TMPDIR/"imap_sync_all.log" LOGERRORS=$TMPDIR/"imap_sync_errors.log" PASSADM=$TMPDIR/pass_adm PASSTMP=$TMPDIR/pass_tmp PASS=`cat $PASSTMP` echo "$DATE IMAPSync starting" > $LOGFILE echo "$DATE IMAPSync starting" > $LOGERRORS # Begin 'for' loop, calling the list of user names already collected for USER in `cat $TMPDIR/userlist` do # Reset the Zimbra password temporarily: zmprov setPassword $USER $PASS # Then migrate: echo "" >> $LOGFILE echo "-------------------------------------------------" >> $LOGFILE echo "--- syncronize account: $USER -------" >> $LOGFILE echo "-------------------------------------------------" >> $LOGFILE /usr/bin/imapsync --nosyncacls --syncinternaldates \ --host1 10.0.0.211 --port1 143 --authmech1 PLAIN --user1 user@mydomain.ru --passfile1 $PASSADM \ --host2 10.0.0.254 --ssl2 --port2 993 --authmech2 PLAIN --user2 $USER --passfile2 $PASSTMP \ --folderrec INBOX.$USER --regextrans2 's/(.*)/INBOX/' 2>> $LOGERRORS >> $LOGFILE done echo "" >> $LOGFILE echo "$DATE Change the passwords back to the encrypted ones" >> $LOGFILE $TMPDIR/update_pass.sh echo "" >> $LOGFILE echo "$DATE All done" >> $LOGFILE echo "$DATE All done" >> $LOGERRORS
Учтите, что синхронизация идёт довольно долго. После завершения, загляните в журнал, всё ли прошло успешно, если да, то можно удалять каталог /tmp/zimbra
Подробней про миграцию на Zimbra можно узнать на официальной странице
Настройка алиасов домена
Настроим (если есть) алиасы домена. Если хотим сделать для существущего домена domain.com ссылку (alias) example.com, то выполняем:
$ zmprov createAliasDomain example.com domain.com zimbraMailCatchAllForwardingAddress @domain.com
Подробней можно узнать на официальной страничке
Борьба со спамом
Этому посвящена специальная статья на вики Zimbra (на англ.).
Чтобы добавить правило, редактируем файл /opt/zimbra/conf/salocal.cf.in, добавляя две строки:
body LOCAL_RULE /порно/ score LOCAL_RULE 10.0
Проверено на кирилице в кодировке utf8. По-умолчанию файл доступен только для чтения, что можно исправить:
chmod u+w ./salocal.cf.in
После этого нужно перезагрузить zimbra:
$ zmcontrol restart
но может быть будет достаточно перезагрузить только модуль антиспама:
$ zmantispamctl restart
Ограничение размера ящика и письма
Zimbra в качестве MTA использует Postfix, где эти ограничения задаются переменными:
# устанавливаем ограничение на ящик в 100Мб и на письмо в 10Мб mailbox_size_limit = 102400000 message_size_limit = 10240000
Конфигурационный файл /opt/zimbra/postfix/conf/main.cf генерируется при каждом запуске зимбры, поэтому исправлять его нет смысла. Редактируем файл /opt/zimbra/conf/zmmta.cf, но так как он доступен только для чтения, то сначала придётся сменить права:
$ chmod u+w ./zmmta.cf
Находим вышеуказанные переменные, присваиваем нужные значения, перезагружаем зимбру:
$ zmcontrol restart
Маршрутизация почты (mail routing)
Так как Zimbra использует Postfix как МТА, то маршрутизацию (перенаправление) почты настраиваем в нём. Создаём файл с описанием маршрутов /opt/zimbra/postfix/conf/transport-table:
mydomain.com :[mail.otherdomain.com] mydomain.ru :[192.168.0.10]
В этой таблице мы перенаправляем всю почту для домена mydomain.com на другой адрес в Интернете mail.otherdomain.com, а почту для домена mydomain.ru передаём почтовому серверу 192.168.0.10 в локальной сети. При этом имя пользователя (адресата) не изменяется.
! | Маршрутизация почты не затрагивает правила IP маршрутизации и меняет лишь домен назначения. Таким образом, после того как эти правила были применены дальнейшее разрешение DNS имён и отправка IP пакетов идут своим обычным чередом. |
- Подробнее про маршрутизацию почты в Zimbra см в официальной документации:
Полезные команды
Все команды запускаются от имени пользователя zimbra:
$ zmcontrol - управление всеми сервисам Zimbra сразу (status | stop | start | maintenance)
$ zmcontrol <имя_сервиса> команда - управление отдельным сервисом (status | stop | start | maintenance)
$ zmprov - работа с каталогом (LDAP). Запустив без параметров, зайдём в командный интерфейс и получим мощный инструмент для адмиинистрирования:
prov> help zmprov is used for provisioning. Try: zmprov help account help on account-related commands zmprov help calendar help on calendar resource-related commands zmprov help commands help on all commands zmprov help config help on config-related commands zmprov help cos help on COS-related commands zmprov help domain help on domain-related commands zmprov help freebusy help on free/busy-related commands zmprov help list help on distribution list-related commands zmprov help log help on logging commands zmprov help misc help on misc commands zmprov help mailbox help on mailbox-related commands zmprov help notebook help on notebook-related commands zmprov help right help on right-related commands zmprov help search help on search-related commands zmprov help server help on server-related commands zmprov help share help on share related commands
На оффициальной вики можно узнать подробней про команду Zmprov и примеры с ней.
Решение проблем (troubleshooting)
Не отображается "Статистика сервера"
Не отображается "Статистика сервера", при попытке обновить, выдаёт ошибку:
Message: system failure: Unable to read logger stats Error code: service.FAILURE Method: GetLoggerStatsRequest Details:soap:Receiver
Решение:нужно доустановить rsyslog и выполнить его настройку от рута:
# apt-get install rsyslog # /opt/zimbra/bin/zmsyslogsetup
переключиться на пользователя zimbra и перезапустить:
# su - zimbra $ zmcontrol stop $ zmcontrol start
Unable to commit database transaction
Полное сообщение об ошибке в /opt/zimbra/log/mailbox.log может выглядить так (ip случайный):
FATAL [LmtpServer-21] [ip=193.192.191.190;] system - Unable to commit database transaction. Forcing server to abort.
или так:
FATAL [LmtpServer-7] [name=user@domain.ru;mid=40;ip=193.192.191.190;] system - Unable to commit database transaction. Forcing server to abort.
более подробное описание можно почитать в журнале mysql_error.log поискав по ключевому слову "error".
Решение: перезагрузить сервер. Ошибка исчезнет если была проблема в кэше. Если ошибка не исчезла, то нужно восстанавливать таблицу(ы), см. Forcing InnoDB Recovery
Перенос сервера с 32 разрядной системы на 64 разрядную
Подробный мануал есть на официальном сайте: http://wiki.zimbra.com/index.php?title=64_bit
Полезные ссылки
- http://www.zimbra.com/products/product_editions.html - Сравнение возможностей разных редакций Zimbra.
- http://www.zimbra.com/forums/ - официальный форум
- http://wiki.zimbra.com/wiki/ - официальное вики
- http://hidx.wordpress.com/2010/05/14/чёрные-и-белые-списки-в-zimbra/
Zimbra и Active Directory