Всё ниже сказанное проводилось на FreeBSD 7.2
ПС: Статья немного устарела, но всё-таки.
1) Установка
Начнём с установки postfix’a. Обновляем порты и переходим в каталог с postfix:
#cd /usr/ports/mail/postfix && make install clean
Вылазит окошко, в котором выбираем
PCRE Perl Compatible Regular Expressions
DOVECOT Dovecot SASL authentication method
TLS Enable SSL and TLS support
MYSQL MySQL maps (choose version with WITH_MYSQL_VER)
Он за собой потянет dovecot, в котором выберем следующее
KQUEUE kqueue(2) support
SSL SSL support
POP3 POP3 support
LDA LDA support
MYSQL MySQL support
“За компанию поставится” mysql-50-client. Ну что ж староват (уже есть 5.1) Тут поступаем по своему рассуждению. Ставим серверную часть. После установки всего этого переходим к настройке.
2) Генерация серфиката SSL.
Генерируем сертификат (будут задаваться вопросы, отвечайте 🙂 ):
#cd /etc/ssl
#openssl req -new -x509 -nodes -out smtpd.pem -keyout smtpd.pem -days 100000
Внимание!
В случае проблем с сертификатам или с тем, что почтовый клиент не хочет цепляться на ssl порт, попробуйте рекомендации из этой статьи
3) Настройка postfix’a
Переходим в каталог /usr/local/etc/postrfix. Здесь лежат конфигурационные файлы. Нам нужны 2, точнее 1. Это main.cf. Его нужно привести к такому виду (напомню, что виртуальными считаются не системные юзеры, собственно, которых будем потом заводить. Пользователей мы будем хранить в БД Mysql.):
Внимание!!! Не ставьте комментарии посредине строки!!! Иначе будете получать ошибку:
May 14 21:34:31 mail-bsd postfix/smtpd[85652]: fatal: open dictionary: expecting “type:name” form instead of “#”
queue_directory = /var/spool/postfix
command_directory = /usr/local/sbin
daemon_directory = /usr/local/libexec/postfix
data_directory = /var/db/postfix
mail_owner = postfix
myhostname = srv-test.domain.tld
mydomain = domain.tld
myorigin = $myhostname
inet_interfaces = all
mydestination = $myhostname, mysql:/usr/local/etc/postfix/mysql/mydestination.cf
local_recipient_maps = unix:passwd.byname $alias_maps $virtual_mailbox_maps
unknown_local_recipient_reject_code = 550
mynetworks_style = subnet
mynetworks = 10.0.0.0/8, 127.0.0.0/8
relayhost = $mydomain
alias_maps = hash:/etc/mail/aliases
# для виртуальных рассылок, алиасов:
virtual_alias_maps = mysql:/usr/local/etc/postfix/mysql/virtual.cf
alias_database = hash:/etc/mail/aliases
debug_peer_level = 2
debugger_command =
PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin
ddd $daemon_directory/$process_name $process_id & sleep 5
sendmail_path = /usr/local/sbin/sendmail
newaliases_path = /usr/local/bin/newaliases
mailq_path = /usr/local/bin/mailq
setgid_group = maildrop
html_directory = no
manpage_directory = /usr/local/man
sample_directory = /usr/local/etc/postfix
readme_directory = no
#описание различных ограничений на приём, отправку.
#сюда можно вставлять проверки в блэклистах
smtpd_client_restrictions =
permit_mynetworks,
permit_sasl_authenticated,
reject_unauth_pipelining,
permit
smtpd_helo_restrictions =
permit
smtpd_sender_restrictions =
permit_mynetworks,
permit_sasl_authenticated,
reject_non_fqdn_sender,
reject_unknown_sender_domain,
reject_unverified_sender,
permit
smtpd_recipient_restrictions =
permit_mynetworks,
permit_sasl_authenticated,
reject_non_fqdn_recipient,
reject_unauth_destination,
reject_unknown_recipient_domain,
reject_unverified_recipient,
permit
smtpd_data_restrictions =
permit
smtpd_end_of_data_restrictions =
permit
smtpd_etrn_restrictions =
permit
transport_maps = mysql:/usr/local/etc/postfix/mysql/transport.cf
#здесь описание для виртуальных юзеров (то есть не системных)
virtual_maps = mysql:/usr/local/etc/postfix/mysql/virtual.cf
# здесь будем хранить почту:
virtual_mailbox_base = /var/spool/vmail
virtual_mailbox_maps = mysql:/usr/local/etc/postfix/mysql/virtual_mailbox.cf
virtual_uid_maps = static:990
virtual_gid_maps = static:990
virtual_minimum_uid = 990
virtual_mailbox_limit_maps=mysql:/usr/local/etc/postfix/mysql/virtual_mailbox_limit.cf
virtual_mailbox_limit_override = yes
virtual_maildir_limit_message = Sorry, the user's maildir has no space available in their inbox.
virtual_overquota_bounce = yes
#секция, отвечающая за авторизацию:
#мы будем авторизироваться через dovecot
smtpd_sasl_auth_enable = yes
smtpd_sasl_application_name = smtpd
smtpd_sasl_local_domain = srv-test.domain.tld
smtpd_sasl_security_options = noanonymous
smtpd_sasl_type = dovecot
smtpd_sasl_path = /var/run/dovecot/auth-client
broken_sasl_auth_clients = yes
# секция, отвечающая за сертификаты. если у вас возникли
#проблемы с ним, то первые 2 строчки поставьте в no,
#остальные - заккоментируйте.
smtp_use_tls = yes
smtpd_use_tls = yes
smtp_tls_note_starttls_offer = yes
smtpd_tls_key_file = /etc/ssl/smtpd.pem
smtpd_tls_cert_file = /etc/ssl/smtpd.pem
smtpd_tls_loglevel = 1
smtpd_tls_received_header = yes
smtpd_tls_session_cache_timeout = 3600s
Приведу содержимое файлов из папки /usr/local/etc/postfix/mysql (Ставим права на эту папку 755 и владелец root:wheel, а права на файлы в папке mysql = 640 и владелец root:postfix):
mydestination.cf
hosts = localhost
dbname = postfixadmin
user = postfixadmin
password = postfixadmin
table = domain
select_field = transport
where_field = domain
additional_conditions = AND (transport = 'local' OR transport = 'virtual')
transport.cf
hosts = localhost
dbname = postfixadmin
user = postfixadmin
password = postfixadmin
table = domain
select_field = transport
where_field = domain
virtual.cf
hosts = localhost
dbname = postfixadmin
user = postfixadmin
password = postfixadmin
table = alias
select_field = goto
where_field = address
virtual_mailbox.cf
hosts = localhost
dbname = postfixadmin
user = postfixadmin
password = postfixadmin
table = mailbox
select_field = maildir
where_field = username
additional_conditions = and active = '1'
virtual_mailbox_limit.cf
hosts = localhost
dbname = postfixadmin
user = postfixadmin
password = postfixafmin
table = mailbox
select_field = quota
where_field = username
Последовательно выполняем действия:
– создадим каталог /var/spool/vmail, в котором собственно и будет храниться наша почта.
– заведём юзера vmail и группу vmail, с uid=990, gid=990 и сделаем его владельцем папки /var/spool/vmail с правами 700.
– добавим юзера postfix в группы mail и dovecot.
– добавим строчки для блокировки запуска sendmail:
sendmail_enable="NONE"
– “убъём” sendmail
#killall -9 sendmail
– добавим строчку для запуска в /etc/rc.conf
postfix_enable="YES"
– запустим postfix:
#/usr/local/etc/rc.d/postfix start
В логе /var/log/maillog должны появится строки:
May 15 15:21:33 srv-test postfix/postfix-script[53879]: starting the Postfix mail system
May 15 15:21:33 srv-test postfix/master[53880]: daemon started -- version 2.5.6, configuration /usr/local/etc/postfix
4) Настройка dovecot
Приводим файл /usr/local/etc/dovecot.conf к такому виду:
protocols = imap imaps pop3 pop3s
listen = *
disable_plaintext_auth = no
log_path = /var/log/maillog
log_timestamp = "%b %d %H:%M:%S "
syslog_facility = mail
ssl_cert_file = /etc/ssl/smtpd.pem
ssl_key_file = /etc/ssl/smtpd.pem
mail_location = maildir:/var/spool/vmail/%h
mail_privileged_group = mail
dotlock_use_excl = yes
verbose_proctitle = yes
first_valid_uid = 990
first_valid_gid = 990
maildir_copy_with_hardlinks = yes
protocol imap {
login_greeting_capability = no
imap_client_workarounds = delay-newmail outlook-idle netscape-eoh tb-extra-mailbox-sep
}
protocol pop3 {
pop3_uidl_format = %08Xu%08Xv
pop3_client_workarounds = outlook-no-nuls oe-ns-eoh
}
protocol lda {
postmaster_address = postmaster@example.com
sendmail_path = /usr/sbin/sendmail
}
auth_default_realm = domain.tld
auth_username_format = %Lu
auth_verbose = no
auth_debug = no
auth default {
mechanisms = plain login
passdb pam {
}
passdb sql {
args = /usr/local/etc/dovecot-sql.conf
}
userdb passwd {
args = blocking=yes
}
userdb sql {
args = /usr/local/etc/dovecot-sql.conf
}
user = root
socket listen {
client {
path = /var/run/dovecot/auth-client
mode = 0660
user = dovecot
group = dovecot
}
}
}
dict {
}
plugin {
}
Ставим права на этот файл 444 и владелец root:wheel
Содержимое /usr/local/etc/dovecot-sql.conf
driver = mysql
connect = host=localhost user=postfixadmin password=postfixadmin dbname=postfixadmin
default_pass_scheme = MD5
user_query = SELECT maildir AS home, 990 AS uid, 990 AS gid FROM mailbox WHERE username = '%n@%d'
password_query = SELECT password AS password FROM mailbox WHERE username = '%n@%d' AND active = '1'
Ставим права на этот файл 600 и владелец root:wheel
5) Теперь переходим к mysql.
После установки базы производим её инициализацию:
#mysql_install_db
#chown -R mysql:mysql /var/db/mysql
Добавляем в /etc/rc.conf строку для запуска и собственно запускаем:
#echo 'mysql_enable="YES"' >> /etc/rc.conf
#/usr/local/etc/rc.d/mysql-server start
Теперь создадим базу postixadmin, юзера postfixadmin.
#mysql
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 284
Server version: 5.0.81 FreeBSD port: mysql-server-5.0.81
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>CREATE DATABASE postfixadmin;
mysql>GRANT ALL PRIVILEGES ON postfixadmin.* TO 'postfixadmin'@'localhost' IDENTIFIED BY 'postfixadmin'
mysql>FLUSH PRIVILEGES;
mysql>QUIT;
Теперь добавляем строку запуска dovecot’a в /etc/rc.conf и собственно запускаем его:
#echo 'dovecot_enable="YES"' >> /etc/rc.conf
#/usr/local/etc/rc.d/dovecot start
6) Ставим PostfixAdmin
Идём в порты и ставим postfixadmin:
#cd /usr/ports/mail/postfixadmin && make install clean
После установки редактируем httpd.conf для возможности запуска postfixadmin’a:
Alias /postfixadmin /usr/local/www/postfixadmin
<Directory /usr/local/www/postfixadmin>
AllowOverride None
Order allow,deny
Allow from all
</Directory>
Теперь отредактируем конфиг postfixadmin’a config.inc.php, который находится в корне папки с postfixadmin’om. Приведу лишь опции, которые требуют изменений (остальные по вкусу):
$CONF['configured'] = true;
$CONF['default_language'] = 'ru';
$CONF['database_type'] = 'mysql';
$CONF['database_host'] = 'localhost';
$CONF['database_user'] = 'postfixadmin';
$CONF['database_password'] = 'postfixadmin';
$CONF['database_name'] = 'postfixadmin';
$CONF['database_prefix'] = '';
$CONF['min_password_length'] = 0;
$CONF['domain_path'] = 'YES';
$CONF['aliases'] = '0';
$CONF['mailboxes'] = '0';
$CONF['maxquota'] = '0';
$CONF['alias_goto_limit'] = '0';
$CONF['show_status']='YES';
$CONF['show_status_key']='YES';
$CONF['show_undeliverable']='YES';
$CONF['show_popimap']='YES';
Перечитываем конфиг apach’a и заходим по адресу http://IP_сервера/postfixadmin. Кликаем по ссылке setup и смотрим, что нам выдаёт(если у вас нет подобных ошибок, то просто пропускаем этот пункт):
# Error: Depends on: multibyte string - NOT FOUND
To install multibyte string support, install php5-mbstring
# Warning: Depends on: IMAP functions - NOT FOUND
To install IMAP support, install php5-imap
Without IMAP support, you won't be able to create subfolders when creating mailboxes.
Чесно ставим, то, чего недостаёт, а именно php5-mbstring, php5-imap:
#cd /usr/ports/converters/php5-mbstring && make install clean
#cd /usr/ports/mail/php5-imap && make install clean
После установки проверяем, добавлены ли следующие строчки в файл extensions.ini,
extension=mbstring.so
extension=imap.so
Можно ещё отключить Magic в php.ini, что мы и сделаем. Копируем файл php-ini.dist в php.ini в каталоге /usr/local/etc и выставляем параметр magic_quotes_gpc = Off. После всего этого перечитываем конфиг apach’a и обновляем страницу с postfixadmin’om. Если всё ок (а так и должно быть) то внизу страницы должна быть форма для ввода логина и пасса администратораpostfixadmin’a. Потом по рекомендации удаляем файл setup.php из папки /usr/local/www/postfixadmin и заходим на страницу http://IP_сервера/postfixadmin. Если всё ок, то увидим форму для ввода логина\пароля.
Сейчас хочу немного затюнить postfixadmin. Дело в том, что я часто имею дела с юзерами, которые по тем или иным причинам теряют\забывают свои пароли. И хотелось бы иметь возможность в любое время их посмотреть. Хотя в postfixadmin’e и есть опция показывать пароли, на самом деле она показывает пароль только при создании ящика. Сначало добавим столбец для хранения чистого пароля в таблице mailbox:
#mysql postfixadmin -upostfixadmin -ppostfixadmin
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 284
Server version: 5.0.81 FreeBSD port: mysql-server-5.0.81
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>ALTER TABLE mailbox ADD pw_clear TEXT NOT NULL AFTER password;
mysql>QUIT;
Добавили поле pw_clear. Теперь подредактируем php-скрипты. Будем редактировать такие файлы: create-mailbox.php, edit-mailbox.php, templates/edit-mailbox.php. Имена файлов относительно корня postfixadmin’a. Редактируем:
create-mailbox.php
Ищем и комментируем блок (это делается )
# $result = db_query ("INSERT INTO $table_alias (address,goto,domain,created,modified,active) VALUES ('$fUsername','$fUsername','$fDomain',NOW(),NOW(),
# if ($result['rows'] != 1)
# {
# $tDomain = $fDomain;
# $tMessage = $PALANG['pAlias_result_error'] . "
($fUsername -> $fUsername)
";
# }
Ищем строку
$result = db_query ("INSERT INTO $table_mailbox (username,password,
и вставляем нужные поля (выделены жирным):
$result = db_query ("INSERT INTO $table_mailbox (username,password,pw_clear,name,maildir,local_part,quota,domain,created,modified,active) VALUES ('$fUsername','$password','$fPassword','$fName','$maildir','$local_part','$quota','$fDomain',NOW(),NOW(),'$sqlActive')");
edit-mailbox.php
Ищем строку:
$formvars['password'] = pacrypt($fPassword);
и вставляем после неё строку
$formvars['pw_clear'] = $fPassword;
template\edit-mailbox.php
В самом начале файла есть код, заключенный в :
if( !defined('POSTFIXADMIN') ) die( "This file cannot be used standalone." ); ?>
Так вот, переделываем его в такой:
if( !defined('POSTFIXADMIN') ) die( "This file cannot be used standalone." );
$con = mysql_connect("localhost", "postfixadmin", "postfixadmin") or die(mysql_error());
mysql_select_db("postfixadmin", $con) or die(mysql_error());
$result = mysql_query("SELECT pw_clear FROM mailbox where username='$fUsername'") or die(mysql_error());
while($row = mysql_fetch_row( $result ))
{
$pass=$row['0'];
}
?>
Так же после блока
<tr>
<td><?php print $PALANG['pEdit_mailbox_username']; ?></td>
<td><?php print $fUsername; ?></td>
<td><?php print $pEdit_mailbox_username_text; ?></td>
</tr>
Вставляем такой
<tr>
<td><?php print "current password"; ?></td>
<td><?php print $pass; ?></td>
</tr>
Всё! Готово. Теперь при заходе по ссылке изменить пароль, в поле current password будет отображаться текущий пароль!
Есть ещё одна неприятность: при создании ящика, автоматом создаётся и алиас с его самого на его самого. Причём, при попытке создать алиас с этого ящика на другой – вызывает ошибку: “Такой алиас уже есть”. Для того, что бы не создавался атоматом алиас открываем файл create-mailbox.php, ищем и комментируем блок
# $result = db_query ("INSERT INTO $table_alias (address,goto,domain,created,modified,active) VALUES ('$fUsername','$fUsername','$fDomain',NOW(),NOW(),
# if ($result['rows'] != 1)
# {
# $tDomain = $fDomain;
# $tMessage = $PALANG['pAlias_result_error'] . "
($fUsername -> $fUsername)
";
# }
Осталось дело за малым: завести домен, юзеров.
Теперь попробуем подключить учётную запись IMAP и отправить письмо кому-нибудь из заведённых юзеров. Смотрим лог /var/log/maillog:
dovecot: May 15 15:27:27 Info: imap-login: Login: user=, method=PLAIN, rip=10.10.10.1, lip=10.10.10.33
May 15 15:36:14 srv-test postfix/smtpd[53942]: connect from my.comp[10.10.10.1]
May 15 15:36:14 srv-test postfix/smtpd[53942]: setting up TLS connection from my.comp[10.10.10.1]
May 15 15:36:20 srv-test postfix/smtpd[53942]: Anonymous TLS connection established from my.comp[10.10.10.1]: TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)
May 15 15:36:24 srv-test postfix/smtpd[53942]: 7BEFC170CD: client=my.comp[10.10.10.1], sasl_method=PLAIN, sasl_username=admin@domain.tld
May 15 15:36:24 srv-test postfix/cleanup[53944]: 7BEFC170CD: message-id=<4A0D6198.7020309@domain.tld>
May 15 15:36:24 srv-test postfix/qmgr[53882]: 7BEFC170CD: from=, size=610, nrcpt=1 (queue active)
May 15 15:36:24 srv-test postfix/smtpd[53942]: disconnect from my.comp[10.10.10.1]
May 15 15:36:24 srv-test postfix/virtual[53945]: 7BEFC170CD: to=, relay=virtual, delay=0.16, delays=0.13/0.02/0/0.02, dsn=2.0.0, status=sent (delivered to maildir)
May 15 15:36:24 srv-test postfix/qmgr[53882]: 7BEFC170CD: removed
dovecot: May 15 15:37:06 Info: IMAP(admin@domain.tld): Disconnected: Logged out bytes=506/673
Как видим, что и tls у нас работает. Кстати, проверить работает ли tls на сервере можно, подключившись к нему:
$telnet 10.10.10.33 25
Trying 10.10.10.33...
Connected to srv-test.
Escape character is '^]'.
220 srv-test.domain.tld ESMTP Postfix
ehlo a.ua <<<<< это мы ввели
250-srv-test.domain.tld
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250-STARTTLS <<<<< вот собственно и видно :)
250-AUTH PLAIN LOGIN
250-AUTH=PLAIN LOGIN
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN
6) squirrelmail
Переходим в каталог /usr/ports/mail/squirrelmail и ставим. По своей сути squirrelmail – набор php-скриптов для работы с imap-сервером. После установки появится каталог/usr/local/www/squirrelmail. Переходим в него и запускаем скрипт ./configure:
SquirrelMail Configuration : Read: config.php (1.4.0)
---------------------------------------------------------
Main Menu --
1. Organization Preferences
2. Server Settings
3. Folder Defaults
4. General Options
5. Themes
6. Address Books
7. Message of the Day (MOTD)
8. Plugins
9. Database
10. Languages
D. Set pre-defined settings for specific IMAP servers
C Turn color off
S Save data
Q Quit
Command >>
Тут ходим по менюшкам и ставим по своему вкусу. Едиственное, что я поменял, так это в 10-ом пункте Languages язык:
1. Default Language : ru_RU
2. Default Charset : utf-8
Теперь Нажимаем S, потом Q. Заходим в броузер и любуемся 🙂
Собственно это всё 🙂 В будущем планируется включить поддержку фильтрации спама и антивирус.