Pull to refresh

Идеальный корпоративный почтовый клиент

Reading time 26 min
Views 176K
Когда возникает необходимость настроить почтовую систему для компании в первую очередь на ум приходит использовать решения от Microsoft — Exchange и Outlook. К сожалению, эти решения не обеспечивают достаточной гибкости и многим не подходят по разным параметрам.

Хорошо, но что же использовать вместо них, ведь хочется такой же красивой и прозрачной для пользователя работы с почтой, которую обеспечивает протокол MAPI? Небольшая перетасовычка и на свет появляется вполне очевидное и на самом деле безальтернативное решение — IMAP. IMAP, слава Богу, в современном мире в той или иной степени поддерживают чуть ли не все почтовые клиенты, так что выбор у нас огромен. Но если присмотреться внимательней, то он сужается до весьма скромного множества из одного-двух наименований.

Итак, нам бы хотелось:
  • Для начала — кросплатформенность. Глупо использовать стандартизированные технологии, но привязываться изначально к одной ОС, тогда уж проще сразу купить Exchange и навсегда забыть о какой-либо гибкости разворачиваемой инфраструктуры.
  • Полная поддержка IMAP и IMAP ACL. Второй пункт важен, т.к. без него нельзя будет организовать ни общих папок, ни передачу прав на различные операции с ящиком другим пользователям, а без этого в корпоративной почтовой системе никак.
  • Возможность централизованной настройки клиента через сервер.
  • Гибкость настроек клиента и удобство в использовании.
Недолгий поиск в интернете может поведать, что единственный вариант, который можно было бы рассмотреть поближе — это Mozilla Thunderbird. Но вот вопрос: может ли Thunderbird предоставить весь необходимый функционал, чтобы можно было с лёгкостью заменить им связку Exchange и Outlook? Оказывается не только может, но и позволяет добиться куда как большего, чем просто банальное подражание продуктам Microsoft.

Для начала, конечно, надо определиться с сервером, а то что-то я слишком лихо собрался заменять почтовым клиентом целую инфраструктуру. Я использую Dovecot, поскольку он является одним из самых надёжных и гибких продуктов в своей области, но самое главное — Dovecot единственный широкоиспользуемый сервер, который полностью реализует поддержку протокола IMAP. Вы можете использовать любой другой сервер, однако для достижения максимальной эффективности ваш сервер должен как минимум поддерживать IMAP ACL.

В дебрях конфигов


Теперь перейдём непосредственно к Thunderbird. Все настройки Thunderbird хранит в виде столь любимых многими текстовых конфигурационных файлов, правда, в несколько необычной манере. Конфиги Thunderbird представляют из себя скрипты на JavaScript. И Thunderbird не просто читает их, а исполняет. Из этого следует весьма забавный вывод: можно использовать множество возможностей JS для динамического формирования нужных параметров. Конечно, поддержка JS в Thunderbird далеко не полная, но нам её хватит с лихвой.

Основной конфигурационный файл Thunderbird хранится в профиле пользователя и называется prefs.js. На всякий случай: профиль Thunderbird находится либо в домашней папке (для Linux), либо в AppData (для Windows), либо в папке программы (для Thunderbird Portable).

Формат указанного файла весьма простой, он весь состоит из строчек вида

user_pref("app.update.auto", false);

Я думаю понятно, что подобные строчки задают некоторое значение указанным в качестве первого аргумента параметрам.

Однако редактировать prefs.js вручную нельзя, поскольку он должен исправляться только самим Thunderbird. При этом непосредственно в программе есть встроенный редактор конфигурации, который позволяет получить доступ ко всем опциям из prefs.js. Попасть в него можно зайдя в меню Инструменты->Настройки..., в открывшемся окне перейдя в раздел Дополнительные, затем выбрав вкладку Основные и нажав на ней кнопку Редактор настроек...

Этот редактор вам ещё очень пригодится, так что обязательно его отыщите. Хотя реально что-то изменять через него вам вряд ли понадобится, зато он крайне полезен для поиска названий нужных опций.

Mozilla AutoConfig (aka Mission Control)


Вот мы и подошли к самому интересному. Как я уже сказал, напрямую редактировать prefs.js нельзя, но это и не проблема, поскольку в Thunderbird есть ещё один уровень настроек, с помощью которого можно как угодно управлять пользовательскими параметрами из prefs.js.

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

Для включения дополнительного механизма настройки надо немного поменять файлы в установочной директории Thunderbird. Для начала необходимо добавить две строчки в конец файла greprefs/all.js, найти который можно в /usr/lib/thunderbird-xxx/ в Ubuntu Linux или рядом с Thunderbird.exe в Windows. Вот эти строчки:

pref("general.config.obscure_value", 0);
pref("general.config.filename", "thunderbird.cfg");

Вторая содержит собственно имя конфигурационного файла, который должен использовать Thunderbird, а первая отвечает за его шифрование. Обычно шифровать ничего не нужно, поэтому значение первого параметра лучше выставлять равным 0.

Теперь необходимо создать указанный файл thunderbird.cfg. Располагаться он должен в той же папке, что и основной исполняемый файл Thunderbird. Узнать, где находится Thunderbird в Linux можно командой

which thunderbird

Ну а в Windows вы можете заглянуть, например, в свойства ярлыка.

Что может располагаться в thunderbird.cfg? Любой JavaScript код, который сможет выполнить Thunderbird. Однако нам-то надо работать с опциями настройки, для этого можно использовать следующие функции:

function pref(prefName, value) 
function defaultPref(prefName, value)
function lockPref(prefName, value) 
function unlockPref(prefName) 
function getPref(prefName)
function clearPref(prefName)
function getenv(envName)

Есть ещё парочка доступных функций, но они вам вряд ли понадобятся. Самая полная статья, которую я нашёл на эту тему, находится здесь.

Хорошо, что же делают все эти функции?
  1. pref — устанавливает значение для указанного параметра. При этом пользователь сможет поменять это значение после запуска Thunderbird, однако если вы не измените thunderbird.cfg, то при следующем перезапуске эта функция выполниться снова и снова изменит значение параметра.
  2. defaultPref — устанавливает для указанного параметра значение по умолчанию. Может оказаться полезной при создании нового профиля.
  3. lockPref — самая полезная, пожалуй, функция. Устанавливает значение для некоторого параметра и блокирует его, таким образом запрещая пользователю этот параметр изменять.
  4. unlockPref — как не трудно догадаться, разблокирует ранее заблокированный параметр.
  5. getPref — возвращает текущее значение указанного параметра.
  6. clearPref — сбрасывает значение указанного параметра.
  7. getenv — возвращает текущее значение указанной системной переменной.
Можно ещё получать данные из LDAP, но при этом не поддерживается авторизация, что сводит на нет полезность этого механизма. Да и он не нужен, как вы вскоре убедитесь.

Вот простейший пример файла thunderbird.cfg, который немного «тюнит» Thunderbird:

// Небольшой тюнинг Thunderbird с помощью Mozilla AutoConfig
try {
        // Получаем имя пользователя, Thunderbird запустившего (и домашнюю папку, хоть она нам и не нужна)
        if(getenv("USER") != "") {
                // *NIX параметры
                var env_user    = getenv("USER");
                var env_home    = getenv("HOME");
        } else {
                // Windows параметры
                var env_user    = getenv("USERNAME");
                var env_home    = getenv("HOMEPATH");
        }
        
        // Ставим аккаунтом по умолчанию account1
        defaultPref("mail.accountmanager.defaultaccount", "account1");
        // Добавляем по умолчанию в список аккаунтов только account1
        defaultPref("mail.accountmanager.accounts", "account1");
        // Жёстко закрепляем за account1 сервер server1 (IMAP)
        lockPref("mail.account.account1.server", "server1");
        // Ставим в качестве сервера локальных папок основной IMAP сервер пользователя,
        // тем самым полностью отключая локальные папки в клиенте
        lockPref("mail.accountmanager.localfoldersserver", "server1");
        
        // Отключаем полосочку "Узнайте о своих правах" при первом запуске
        lockPref("mail.rights.version", 1);
        // Отключаем автообновление клиента. Если не отключить, то при обновлении может измениться файл
        // all.js и тогда весь механизм Mozilla AutoConfig сломается.
        lockPref("app.update.enabled", false);
        lockPref("extensions.update.enabled", false);

        // Настройки IMAP сервера
        lockPref("mail.server.server1.type", "imap");
        lockPref("mail.server.server1.hostname", "mail.domain.com");      // Неизвестно, зачем два параметра, но нужны оба,
        lockPref("mail.server.server1.realhostname", "mail.domain.com");  //   иначе можно будет менять пользователю
        lockPref("mail.server.server1.port", 143);                        // Порт сервера
        lockPref("mail.server.server1.socketType", 2);                    // Использовать STARTLS
        lockPref("mail.server.server1.name", env_user);
        lockPref("mail.server.server1.userName", env_user);               // Логин пользователя,
        lockPref("mail.server.server1.realuserName", env_user);           //   комментарий аналогично hostname
        lockPref("mail.server.server1.login_at_startup", true);           // Очень важный параметр! Без него вообще не заработает ничерта;)
        lockPref("mail.server.server1.isSecure", true);                   // Защищённый сервер

        // Настройки SMTP сервера
        lockPref("mail.smtpserver.smtp1.hostname", "mail.domain.com");
        lockPref("mail.smtpserver.smtp1.port", 25);
        lockPref("mail.smtpserver.smtp1.description", "SMTP сервер ЗАО «Рога и Копыта»");
        lockPref("mail.smtpserver.smtp1.try_ssl", 2);
        lockPref("mail.smtpserver.smtp1.auth_method", 1);
        lockPref("mail.smtpserver.smtp1.username", env_user);

        // Настройки аккаунта - адреса почты и т.д.
        defaultPref("mail.identity.id1.fullName", env_user);            //Это поле пользователь сможет поменять сам, но по умолчанию там будет его логин
        lockPref("mail.identity.id1.useremail", env_user + "@domain.com");
        lockPref("mail.identity.id1.reply_to", env_user + "@domain.com");
        lockPref("mail.identity.id1.valid", true);
        lockPref("mail.identity.id1.smtpServer", "smtp1");
        lockPref("mail.identity.id1.organization", "ЗАО «Рога и Копыта»");
        
        // Привязываем ID к аккаунту
        lockPref("mail.account.account1.identities", "id1");

        // Адресные книги LDAP
        lockPref("ldap_2.servers.domain.uri", "ldap://dc.domain.com/OU=Пользователи,OU=domain,DC=DOMAIN,DC=COM??sub?(mail=*)");
        lockPref("ldap_2.servers.domain.auth.dn", "DOMAIN\\" + env_user);
        lockPref("ldap_2.servers.domain.auth.saslmech", "");
        lockPref("ldap_2.servers.domain.description", "Сотрудники 'Рога и Копыта'");
        lockPref("ldap_2.servers.domain.filename", "empl.mab");
        lockPref("ldap_2.servers.domain.maxHits", 300);
        
        // Автодополнение адресов из книги сотрудников
        lockPref("ldap_2.autoComplete.directoryServer", "ldap_2.servers.domain");
        lockPref("ldap_2.autoComplete.useDirectory", true);
        
} catch(e) {
    displayError("lockedPref", e);
}

Файл подробно комментирован, так что надеюсь вы разберётесь, что к чему. Блок try нужен для перехвата ошибок, лучше его не убирайте (иначе в случае чего Thunderbird просто не запустится). Кроме того, все параметры и нужные значения для них для своей конкретной инфраструктуры я скопировал из упоминавшегося редактора конфигурации, настроив предварительно всё вручную обычным способом. Рекомендую всегда именно так и делать, иначе вы будете долго гадать какое значение нужно указать, например, для параметра mail.server.server.socketType в вашем случае.

То есть алгоритм действия по поиску нужных параметров и указанию их значений примерно такой: сначала настраиваем что-то на чистом Thunderbird вручную, а потом копируем все нужные настройки из редактора в самом Thunderbird в скрипт автоконфигурации.

Теперь достаточно при установке Thunderbird положить этот скрипт в папочку с исполняемым файлом (и не забыть добавить две строчки в all.js!), и все ваши пользователи, которые будут открывать Thunderbird на этом компьютере, получат автоматически настроенные параметры своих аккаунтов, а так же подключённую адресную LDAP книгу с сотрудниками организации.

Для проверки работоспособности скрипта можно заглянуть всё в тот же редактор настроек Thunderbird. В нём статус параметров, для которых была выполнена функция lockPref(), должен быть «заблокировано». Если это не так — значит вы где-то ошиблись и ваш скрипт не работает.

Кстати, обратите внимание, хитрый трюк с указанием в качестве localfoldersserver сервера IMAP позволяет отключить локальные папки в клиенте. Это бывает немаловажно в организации с внутренним IMAP сервером и блондинками, которые не понимают, что локальные папки на то и локальные, что хранятся в профиле пользователя на конкретном компьютере, а не на сервере.

Как я уже сказал, вы можете использовать практически все возможности стандартного JavaScript в скрипте автоконфигурации, плюс можете получать значение системных переменных. Это уже очень неплохо, и пытливые администраторы уже наверно стали прикидывать варианты автоматического обновления скриптов thunderbird.cfg на локальных компьютерах. К счастью, изобретать велосипед вовсе не обязательно.

Настройка через сервер


В механизм автонастройки Thunderbird встроена возможность загрузки конфигурационного файла с сервера по указанному URL. Воспользоваться ей очень просто — необходимо в файле, на который ссылается опция general.config.filename из all.js (то есть в нашем случае thunderbird.cfg) указать всего две строчки:

lockPref("autoadmin.global_config_url", "http://mail.domain.com/thunderbird.cfg");
lockPref("autoadmin.append_emailaddr", false);

Ну и конечно по указанному адресу должен находится нужный вам конфигурационный файл вроде того, что приведён в предыдущем разделе. Зачем нужен второй параметр — не совсем понятно, но судя по названию лучше его не включать.

Итого: мы получили достаточно эффективный механизм централизованной настройки Thunderbird. Однако ему явно не хватает гибкости, поскольку JavaScript, увы, многого не умеет. Например — обращаться к внешним источникам данных, как то SQL базы или LDAP каталоги. Соответственно провести тонкую настройку клиента под конкретного пользователя у вас вряд ли получится.

Но если задуматься, это можно легко обойти. Ведь мы храним конфигурационный файл на HTTP сервере, а значит можем его генерировать с помощью полноценного PHP или Perl скрипта на стороне сервера, что значительно расширяет возможности по тонкой настройке, делая их фактически безграничными.

Осталось дело за малым — для тонкой настройки под конкретного пользователя конфигурационного скрипта, а следовательно и Thunderbird, необходимо, чтобы клиент каким-то образом сообщал серверу хотя бы имя пользователя. Thunderbird его может легко вычислить с помощью уже описанной функции getent, ну а передать его можно прямо в URL в виде GET-переменной. Но тут возникает одна проблема: Thunderbird почему-то упорно игнорирует URL с GET-переменными в параметре autoadmin.global_config_url. Хотя это конечно тоже не проблема, ведь с помощью mod_rewrite мы можем на стороне сервера преобразовать обычный URL некоторого вида в URL c GET-переменными и передать уже этот URL скрипту.

Чтобы долго не объяснять, перейдём к практике. Конечный содержимое моего файла thunderbird.cfg, лежащего рядом с бинарником самого Thunderbird, имеет такой вот вид:

// Начальные параметры настройки Thunderbird грузим с сервера
if(getenv("USER") != "") {
// *NIX settings
        var env_user = getenv("USER");
        var env_home = getenv("HOME");
} else {
// Windows settings
        var env_user = getenv("USERNAME");
        var env_home = getenv("HOMEPATH");
}

lockPref("autoadmin.global_config_url", "http://mail.domain.com/tb/user/"+env_user);
lockPref("autoadmin.append_emailaddr", false);

Таким образом запущенный из под учётной записи пользователя malamut Thunderbird за настройками полезет по адресу

http://mail.domain.com/tb/user/malamut

На сервере mail.domain.com у меня стоит Apache с mod_rewrite и mod_perl, как это дело настраивать вместе пожалуй объяснять не буду. В папочке tb/ в каталоге сайта mail.domain.com лежит Perl-скрипт conf.pl, который собственно генерирует конфигурационные файлы для Thunderbird, и файл .htaccess такого вот содержания:

Options -Indexes +ExecCGI
AddHandler cgi-script .pl

RewriteEngine on
RewriteBase /tb
RewriteRule ^user/(.*)                conf.pl?user=$1   [L]

Таким образом запросы по URL вида

http://mail.domain.com/tb/user/malamut

преобразуются в запросы по URL вида

http://mail.domain.com/tb/conf.pl?user=malamut

Осталось только написать Perl скрипт, который будет брать из GET-переменных имя пользователя и выдавать соответствующий конфигурационный файл для Thunderbird.

Вот пример такого скрипта:

#!/usr/bin/perl

use 5.010;
use CGI qw/:standard/;

# Параметры
$smtp_server = "mail.domain.com";
$imap_server = "mail.domain.com";
$organization = "ЗАО «Рога и Копыта»";

# Прикидываемся жаваскриптом
print header(
	-type=>'application/javascript'
);

# Username - из GET переменных
$user = param('user');
unless ($user) { die "We need a user, please!\n" }

# Нам нужен user в lovercase, иначе  будут проблемы с большинством IMAP серверов. Поскольку username берётся
# из переменной глупейшей винды, то там может быть любое награмождение заглавных и строчных букв.
$user = lc $user;

#########################################################################
# Специфичные для конкретной БД пользователей функции

# Получаем все адреса нужного пользователя. Первый будет основным
# FIXME: нужно реализовать эту функцию для вашей БД
@mails = getEmails($user);

# Получаем полное имя пользователя
# FIXME: нужно реализовать эту функцию для вашей БД
$name = getName($user);

#########################################################################
# Создаём конечный конфигурационный файл

print <<HEAD;
//Параметры автонастройки Thunderbird для пользователя $user ($name)
try {
HEAD

# Настройки серверов
# Аккаунт и SMTP сервер добавляется в список уже присутствующих аккаунтов и SMTP серверов соответственно
# с помощью весьма нехитрой конструкции на JavaScript.
# Это нужно для того, чтобы пользователь мог добавлять свои собственные аккаунты вручную в клиент. Если
# заблокировать mail.accountmanager.accounts или mail.smtpservers, то сделать это будет невозможно.
print <<SERVERS;
	// Основные параметры настройки серверов
	
	// Добавляем аккаунт в список уже подключённых аккаунтов, если его там ещё нет
	var accounts = getPref("mail.accountmanager.accounts");
	var accounts_s = accounts + ",";
	if (! (accounts_s.indexOf("account1,")+1) ) {
		accounts = accounts + ",account1";
	}
	pref("mail.accountmanager.accounts",accounts);

	// Настройки IMAP сервера
	lockPref("mail.server.server1.type", "imap");
        lockPref("mail.server.server1.hostname", "$imap_server");     // Неизвестно, зачем два параметра, но нужны оба,
        lockPref("mail.server.server1.realhostname", "$imap_server"); //   иначе можно будет менять пользователю
        lockPref("mail.server.server1.port", 143);                    // Порт сервера
        lockPref("mail.server.server1.socketType", 2);                // Использовать STARTLS
        lockPref("mail.server.server1.name", "$name");
        lockPref("mail.server.server1.userName", "$user");            // Логин пользователя,
        lockPref("mail.server.server1.realuserName", "$user");        //   комментарий аналогично hostname
        lockPref("mail.server.server1.login_at_startup", true);       // Очень важный параметр! Без него вообще не заработает ничерта;)
        lockPref("mail.server.server1.isSecure", true);               // Защищённый сервер

        // Привязываем указанный IMAP сервер к аккаунту
        lockPref("mail.account.account1.server", "server1");

        // Настройки SMTP сервера
        lockPref("mail.smtpserver.smtp1.hostname", "$smtp_server");
        lockPref("mail.smtpserver.smtp1.port", 25);
        lockPref("mail.smtpserver.smtp1.description", "SMTP сервер $organization");
        lockPref("mail.smtpserver.smtp1.try_ssl", 2);
        lockPref("mail.smtpserver.smtp1.auth_method", 1);
        lockPref("mail.smtpserver.smtp1.username", "$user");

        // Добавляем SMTP в список
	var smtp = getPref("mail.smtpservers");
	var smtp_s = smtp + ",";
	if (! (smtp_s.indexOf("smtp1,")+1) ) {
		smtp = smtp + ",smtp1";
	}
	pref("mail.smtpservers", smtp);	

SERVERS

# Различные настройки клиента
print <<MISC;
        // Отключаем полосочку "Узнайте о своих правах" при первом запуске
	lockPref("mail.rights.version", 1);
	// Отключаем автообновление
	lockPref("app.update.enabled", false);
	lockPref("extensions.update.enabled", false);
        // Ставим в качестве сервера локальных папок основной IMAP сервер пользователя,
        // тем самым полностью отключая локальные папки в клиенте
        lockPref("mail.accountmanager.localfoldersserver", "server1");
	// Блокируем корпоративный аккаунт почты в качестве основного аккаунта TB
	lockPref("mail.accountmanager.defaultaccount", "account1");
        // Ставим в качестве сервера локальных папок основной IMAP сервер пользователя,
        // тем самым полностью отключая локальные папки в клиенте
        lockPref("mail.accountmanager.localfoldersserver", "server1");

MISC

# Добавляем все почтовые адреса пользователя
# Отображаемое имя не блокируется, чтобы пользователь смог его сменить.
$i=0;
@ids = ();
foreach $mail (@mails) {	
	$i++;
	$id = <<ID;
	// Адрес $mail для пользователя $user ($name)
	defaultPref("mail.identity.id$i.fullName", "$name");
	lockPref("mail.identity.id$i.useremail", "$mail");
	lockPref("mail.identity.id$i.reply_to", "$mail");
	lockPref("mail.identity.id$i.valid", true);
	lockPref("mail.identity.id$i.smtpServer", "smtp1");
	lockPref("mail.identity.id$i.organization", "$organization");
	lockPref("mail.identity.id$i.archive_folder", "imap://$user\@$imap_server/Archives");
	lockPref("mail.identity.id$i.draft_folder", "imap://$user\@$imap_server/Drafts");
	lockPref("mail.identity.id$i.drafts_folder_picker_mode", 0);
	lockPref("mail.identity.id$i.fcc_folder", "imap://$user\@$imap_server/Sent");
	lockPref("mail.identity.id$i.fcc_folder_picker_mode", 0);
	lockPref("mail.identity.id$i.stationery_folder", "imap://$user\@$imap_server/Templates");

ID
	print $id;
	push @ids, "id$i";		
}
# Теперь надо сказать TB, что данный аккаунт использует все эти адреса
$ids = join ',', @ids;
print <<IDS;
	// Все доступные для этого аккаунта адреса
	lockPref("mail.account.account1.identities", "$ids");

IDS

# Адресные книги LDAP
print <<BOOKS;
        // Адресная книга сотрудников
	lockPref("ldap_2.servers.domain.uri", "ldap://dc.domain.com/OU=Пользователи,OU=domain,DC=DOMAIN,DC=COM??sub?(mail=*)");
        lockPref("ldap_2.servers.domain.auth.dn", "DOMAIN\\\\$user");
        lockPref("ldap_2.servers.domain.auth.saslmech", "");
        lockPref("ldap_2.servers.domain.description", "Сотрудники 'Рога и Копыта'");
        lockPref("ldap_2.servers.domain.filename", "empl.mab");
        lockPref("ldap_2.servers.domain.maxHits", 300);
	
	// Автодополнение адресов из книги сотрудников
	lockPref("ldap_2.autoComplete.directoryServer", "ldap_2.servers.domain");
	lockPref("ldap_2.autoComplete.useDirectory", true);

BOOKS

#################################################
# Дополнительные настройки для конкретных людей #

if ($user eq 'malamut') {
	yandex('yandex',50);
}

#################################################

print <<TAIL;
} catch(e) {
    displayError("lockedPref", e);
}
TAIL

# Добавления указанного аккаунта с Яндекса. id нужен чтобы не смешивать аккаунты, ya_name без домена - только имя пользователя
sub yandex {
	my ($ya_name, $id) = @_;
	
	print <<YANDEX;
	// SMTP Яндекса для $ya_name\@yandex.ru
	lockPref("mail.smtpserver.smtp$id.hostname", "smtp.yandex.ru");
	lockPref("mail.smtpserver.smtp$id.port", 465);
	lockPref("mail.smtpserver.smtp$id.description", "SMTP для $ya_name\@yandex.ru");
	lockPref("mail.smtpserver.smtp$id.try_ssl", 3);
	lockPref("mail.smtpserver.smtp$id.auth_method", 1);
	lockPref("mail.smtpserver.smtp$id.username", "$ya_name\@yandex.ru");
	
	// Добавляем SMTP Яндекса в список
	var smtp = getPref("mail.smtpservers");
	var smtp_s = smtp + ",";
	if (! (smtp_s.indexOf("smtp$id,")+1) ) {
		smtp = smtp + ",smtp$id";
	}
	pref("mail.smtpservers", smtp);
	
	// IMAP Яндекса для $ya_name\@yandex.ru
	lockPref("mail.server.server$id.type", "imap");
	lockPref("mail.server.server$id.hostname", "imap.yandex.ru");
	lockPref("mail.server.server$id.realhostname", "imap.yandex.ru");
	lockPref("mail.server.server$id.port", 993);
	lockPref("mail.server.server$id.socketType", 3);
	lockPref("mail.server.server$id.name", "$ya_name\@yandex.ru");
	lockPref("mail.server.server$id.userName", "$ya_name\@yandex.ru");
	lockPref("mail.server.server$id.realuserName", "$ya_name\@yandex.ru");
	lockPref("mail.server.server$id.check_new_mail", true);
	lockPref("mail.server.server$id.login_at_startup", true);
	lockPref("mail.server.server$id.isSecure", true);
	lockPref("mail.server.server$id.max_cached_connections", 5);
	
	// Аккаунт для $ya_name\@yandex.ru
	defaultPref("mail.identity.id$id.fullName", "$ya_name");
	lockPref("mail.identity.id$id.useremail", "$ya_name\@yandex.ru");
	lockPref("mail.identity.id$id.reply_to", "$ya_name\@yandex.ru");
	lockPref("mail.identity.id$id.valid", true);
	lockPref("mail.identity.id$id.smtpServer", "smtp$id");
	defaultPref("mail.identity.id$id.organization", "");
	
	lockPref("mail.account.account$id.identities", "id$id");
	lockPref("mail.account.account$id.server", "server$id");
	
	// Добавляем аккаунт $ya_name\@yandex.ru в список
	accounts = getPref("mail.accountmanager.accounts");
	accounts_s = accounts + ",";
	if (! (accounts_s.indexOf("account$id,")+1) ) {
		accounts = accounts + ",account$id";
	}
	pref("mail.accountmanager.accounts",accounts);
	
YANDEX
}

Некоторые комментарии чуть ниже. А пока при обращении по адресу

http://mail.domain.com/tb/user/malamut

получим примерно следующий вывод, сгенерированный приведённым скриптом:

//Параметры автонастройки Thunderbird для пользователя malamut (Malamut)
try {
	// Основные параметры настройки серверов
	
	// Добавляем аккаунт в список уже подключённых аккаунтов, если его там ещё нет
	var accounts = getPref("mail.accountmanager.accounts");
	var accounts_s = accounts + ",";
	if (! (accounts_s.indexOf("account1,")+1) ) {
		accounts = accounts + ",account1";
	}
	pref("mail.accountmanager.accounts",accounts);

	// Настройки IMAP сервера
	lockPref("mail.server.server1.type", "imap");
        lockPref("mail.server.server1.hostname", "mail.domain.com");     // Неизвестно, зачем два параметра, но нужны оба,
        lockPref("mail.server.server1.realhostname", "mail.domain.com"); //   иначе можно будет менять пользователю
        lockPref("mail.server.server1.port", 143);                    // Порт сервера
        lockPref("mail.server.server1.socketType", 2);                // Использовать STARTLS
        lockPref("mail.server.server1.name", "Malamut");
        lockPref("mail.server.server1.userName", "malamut");            // Логин пользователя,
        lockPref("mail.server.server1.realuserName", "malamut");        //   комментарий аналогично hostname
        lockPref("mail.server.server1.login_at_startup", true);       // Очень важный параметр! Без него вообще не заработает ничерта;)
        lockPref("mail.server.server1.isSecure", true);               // Защищённый сервер

        // Привязываем указанный IMAP сервер к аккаунту
        lockPref("mail.account.account1.server", "server1");

        // Настройки SMTP сервера
        lockPref("mail.smtpserver.smtp1.hostname", "mail.domain.com");
        lockPref("mail.smtpserver.smtp1.port", 25);
        lockPref("mail.smtpserver.smtp1.description", "SMTP сервер ЗАО «Рога и Копыта»");
        lockPref("mail.smtpserver.smtp1.try_ssl", 2);
        lockPref("mail.smtpserver.smtp1.auth_method", 1);
        lockPref("mail.smtpserver.smtp1.username", "malamut");

        // Добавляем SMTP в список
	var smtp = getPref("mail.smtpservers");
	var smtp_s = smtp + ",";
	if (! (smtp_s.indexOf("smtp1,")+1) ) {
		smtp = smtp + ",smtp1";
	}
	pref("mail.smtpservers", smtp);	

        // Отключаем полосочку "Узнайте о своих правах" при первом запуске
	lockPref("mail.rights.version", 1);
	// Отключаем автообновление
	lockPref("app.update.enabled", false);
	lockPref("extensions.update.enabled", false);
        // Ставим в качестве сервера локальных папок основной IMAP сервер пользователя,
        // тем самым полностью отключая локальные папки в клиенте
        lockPref("mail.accountmanager.localfoldersserver", "server1");
	// Блокируем корпоративный аккаунт почты в качестве основного аккаунта TB
	lockPref("mail.accountmanager.defaultaccount", "account1");
        // Ставим в качестве сервера локальных папок основной IMAP сервер пользователя,
        // тем самым полностью отключая локальные папки в клиенте
        lockPref("mail.accountmanager.localfoldersserver", "server1");

	// Адрес malamut@domain.com для пользователя malamut (Malamut)
	defaultPref("mail.identity.id1.fullName", "Malamut");
	lockPref("mail.identity.id1.useremail", "malamut@domain.com");
	lockPref("mail.identity.id1.reply_to", "malamut@domain.com");
	lockPref("mail.identity.id1.valid", true);
	lockPref("mail.identity.id1.smtpServer", "smtp1");
	lockPref("mail.identity.id1.organization", "ЗАО «Рога и Копыта»");
	lockPref("mail.identity.id1.archive_folder", "imap://malamut@mail.domain.com/Archives");
	lockPref("mail.identity.id1.draft_folder", "imap://malamut@mail.domain.com/Drafts");
	lockPref("mail.identity.id1.drafts_folder_picker_mode", 0);
	lockPref("mail.identity.id1.fcc_folder", "imap://malamut@mail.domain.com/Sent");
	lockPref("mail.identity.id1.fcc_folder_picker_mode", 0);
	lockPref("mail.identity.id1.stationery_folder", "imap://malamut@mail.domain.com/Templates");

	// Адрес admin@domain.com для пользователя malamut (Malamut)
	defaultPref("mail.identity.id2.fullName", "Malamut");
	lockPref("mail.identity.id2.useremail", "admin@domain.com");
	lockPref("mail.identity.id2.reply_to", "admin@domain.com");
	lockPref("mail.identity.id2.valid", true);
	lockPref("mail.identity.id2.smtpServer", "smtp1");
	lockPref("mail.identity.id2.organization", "ЗАО «Рога и Копыта»");
	lockPref("mail.identity.id2.archive_folder", "imap://malamut@mail.domain.com/Archives");
	lockPref("mail.identity.id2.draft_folder", "imap://malamut@mail.domain.com/Drafts");
	lockPref("mail.identity.id2.drafts_folder_picker_mode", 0);
	lockPref("mail.identity.id2.fcc_folder", "imap://malamut@mail.domain.com/Sent");
	lockPref("mail.identity.id2.fcc_folder_picker_mode", 0);
	lockPref("mail.identity.id2.stationery_folder", "imap://malamut@mail.domain.com/Templates");

	// Все доступные для этого аккаунта адреса
	lockPref("mail.account.account1.identities", "id1,id2");

        // Адресная книга сотрудников
	lockPref("ldap_2.servers.domain.uri", "ldap://dc.domain.com/OU=Пользователи,OU=domain,DC=DOMAIN,DC=COM??sub?(mail=*)");
        lockPref("ldap_2.servers.domain.auth.dn", "DOMAIN\\malamut");
        lockPref("ldap_2.servers.domain.auth.saslmech", "");
        lockPref("ldap_2.servers.domain.description", "Сотрудники 'Рога и Копыта'");
        lockPref("ldap_2.servers.domain.filename", "empl.mab");
        lockPref("ldap_2.servers.domain.maxHits", 300);
	
	// Автодополнение адресов из книги сотрудников
	lockPref("ldap_2.autoComplete.directoryServer", "ldap_2.servers.domain");
	lockPref("ldap_2.autoComplete.useDirectory", true);

	// SMTP Яндекса для yandex@yandex.ru
	lockPref("mail.smtpserver.smtp50.hostname", "smtp.yandex.ru");
	lockPref("mail.smtpserver.smtp50.port", 465);
	lockPref("mail.smtpserver.smtp50.description", "SMTP для yandex@yandex.ru");
	lockPref("mail.smtpserver.smtp50.try_ssl", 3);
	lockPref("mail.smtpserver.smtp50.auth_method", 1);
	lockPref("mail.smtpserver.smtp50.username", "yandex@yandex.ru");
	
	// Добавляем SMTP Яндекса в список
	var smtp = getPref("mail.smtpservers");
	var smtp_s = smtp + ",";
	if (! (smtp_s.indexOf("smtp50,")+1) ) {
		smtp = smtp + ",smtp50";
	}
	pref("mail.smtpservers", smtp);
	
	// IMAP Яндекса для yandex@yandex.ru
	lockPref("mail.server.server50.type", "imap");
	lockPref("mail.server.server50.hostname", "imap.yandex.ru");
	lockPref("mail.server.server50.realhostname", "imap.yandex.ru");
	lockPref("mail.server.server50.port", 993);
	lockPref("mail.server.server50.socketType", 3);
	lockPref("mail.server.server50.name", "yandex@yandex.ru");
	lockPref("mail.server.server50.userName", "yandex@yandex.ru");
	lockPref("mail.server.server50.realuserName", "yandex@yandex.ru");
	lockPref("mail.server.server50.check_new_mail", true);
	lockPref("mail.server.server50.login_at_startup", true);
	lockPref("mail.server.server50.isSecure", true);
	lockPref("mail.server.server50.max_cached_connections", 5);
	
	// Аккаунт для yandex@yandex.ru
	defaultPref("mail.identity.id50.fullName", "yandex");
	lockPref("mail.identity.id50.useremail", "yandex@yandex.ru");
	lockPref("mail.identity.id50.reply_to", "yandex@yandex.ru");
	lockPref("mail.identity.id50.valid", true);
	lockPref("mail.identity.id50.smtpServer", "smtp50");
	defaultPref("mail.identity.id50.organization", "");
	
	lockPref("mail.account.account50.identities", "id50");
	lockPref("mail.account.account50.server", "server50");
	
	// Добавляем аккаунт yandex@yandex.ru в список
	accounts = getPref("mail.accountmanager.accounts");
	accounts_s = accounts + ",";
	if (! (accounts_s.indexOf("account50,")+1) ) {
		accounts = accounts + ",account50";
	}
	pref("mail.accountmanager.accounts",accounts);
	
} catch(e) {
    displayError("lockedPref", e);
}

Вот и всё, мы получили файл конфигурации для Thunderbird, сгенерированный Perl скриптом на сервере.

Самое великолепное в этом то, что с помощью описанного механизма можно неограниченно гибко управлять любыми настройками Thunderbird, включая настройки плагинов, которые также подчиняются менеджеру конфигурации. Единственное, что не подвластно такому централизованному конфигурированию — это пользовательский интерфейс, то есть расположение панелек и их размер.

Настройка аккаунтов через конфигурационный файл


Сначала, на всякий случай, рассмотрим основной принцип настроек аккаунтов в Thunderbird, поскольку он не совсем очевиден.

Все множественные данные одного типа Thunderbird нумерует и различает по номерам. Если нужно добавить новый аккаунт, почтовый адрес, SMTP сервер или ещё что, то Thunderbird во внутренних настройках присвоит новому объекту первый доступный номер. Поэтому когда вы добавляете какие-то объекты через скрипт автоконфигурации, то присваивайте номера, заведомо бОльшие, чем уже могут быть в клиенте. Иначе вы можете переписать случайно настройки какого-то пользовательского почтового ящика, что вряд ли понравится пользователю. Исключение — основной корпоративный аккаунт, который имеет номер 1.

Для того, чтобы привязать множественные записи к какому-то объекту, например, несколько почтовых адресов отправки к аккаунту, Thunderbird использует простые списки, разделённые запятой. Например:

lockPref("mail.account.account1.identities", "id1,id2");

Thunderbird поддерживает множественные аккаунты (account), кроме того, у каждого аккаунта может быть несколько почтовых идентификаторов (identity). Названия всех опций, относящихся непосредственно к аккаунту, начинаются с mail.account.accountN, где N — внутренний номер аккаунта. Названия всех опций, относящихся к почтовым идентификаторам, начинаются соответственно с mail.identity.idN, где N — внутренний номер идентификатора.

Список всех аккаунтов Thunderbird хранится в переменной mail.accountmanager.accounts. Кстати, порядок перечисления аккаунтов в этой переменной определяет порядок их следования в левой панели навигации пользовательского интерфейса Thunderbird. Если удалить аккаунт из этого списка, то он пропадёт из Thunderbird, даже не смотря на то, что все его настройки могут остаться на месте.

Список почтовых идентификаторов для аккаунта N указывается в переменной mail.account.accountN.identities. IMAP сервер привязывается к аккаунту с помощью переменной mail.account.accountN.server, SMTP же сервер привязывается к почтовому идентификатору с помощью переменной mail.identity.idN.smtpServer.

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

Полезные трюки для скрипта автоконфигурации


Во-первых, обратите внимание на JavaScript код, который добавляет переменные в список себе подобных. Например, вот так можно добавить аккаунт к уже существующим:

// Добавляем аккаунт в список уже подключённых аккаунтов, если его там ещё нет
	var accounts = getPref("mail.accountmanager.accounts");
	var accounts_s = accounts + ",";
	if (! (accounts_s.indexOf("account1,")+1) ) {
		accounts = accounts + ",account1";
	}
	pref("mail.accountmanager.accounts",accounts);

Этот трюк необходим для того, чтобы скрипт автоконфигурации не уничтожал настройки дополнительных аккаунтов, подключённых пользователем вручную. Именно поэтому нужный аккаунт нужно добавлять в список уже существующих, а не просто перезаписывать весь список.

Кроме того, на уровне Perl скрипта можно организовать какую угодно обработку в зависимости от переданного имени пользователя. Я добавил для примера функцию, которая подключает аккаунт с Yandex по его имени, и добавил вызов этой функции для себя. Теперь мне потребуется всего лишь закрыть Thunderbird и открыть его заново, затем ввести свой пароль и всё, мой Yandex аккаунт будет подключён! Такую технику очень удобно использовать для удалённого управления почтовыми клиентами отдельных пользователей.

Например, звонит вам босс какого-нибудь филиала и просит подключить аккаунт yandex своей тёщи. Вы, вместо того, чтобы высылать туда штатного специалиста, или долго объяснять, куда нажать, или отвлекать от работы и подключаться удалённо, просто добавляете три строчки в скрипт автоконфигурации и просите перезагрузить почтовый клиент и ввести свой пароль. Такой метод настройки также гарантирует, что пользователь ничего не сломает в параметрах, поскольку они все заблокированы.

Ну и наконец немаловажным является тот факт, что однажды заблокированные параметры прописываются в настройки локального клиента. То есть если вы поставите Thunderbird на ноубук шефа, подключите его в корпоративной сети с целью его автоматической конфигурации, а потом шеф с ним куда-то уедет, то его настройки в клиенте всё равно сохраняться. Даже не смотря на то, что сервер автоконфигурации не будет доступен из того места, где он будет подключаться к интернету.

Дополнительные возможности Thunderbird


Конфигурировать Thunderbird вы теперь умеете. Однако не забудьте на радостях, что Thunderbird выгодно отличается от всех других почтовых клиентов тем, что поддерживает расширения. И этих расширений доступно великое множество на все случаи жизни.

Например, для управления совместным доступом к почтовым ящикам с помощью IMAP ACL можно использовать соответствующее расширение. Для добавления календаря в Thunderbird отлично подойдёт Lightning, который, кстати, тоже можно очень гибко настроить через описанный выше механизм.

Для того, чтобы установить расширение для всех пользователей компьютера, можно сначала поставить его штатным способом, а потом скопировать соответствующую папочку из своего профиля в каталог extensions/, который можно найти в основном установочном каталоге Thunderbird.

Кроме того, можно создавать профили по умолчанию для новых пользователей. Для этого используется каталог default/profile. В профиль можно положить, например, файл настроек пользовательского интерфейса или файл с сертификатами.

Комментарии и полезные дополнения к материалу всячески приветствуются!
Tags:
Hubs:
+159
Comments 238
Comments Comments 238

Articles