Приветствую! Теперь на sys.net.ru будут публикации не только о
Linux, но и о BSD-системах. Я, как закоренелый BSD-шник, постараюсь
периодически наполнять сайт свежими материалами... Итак, мой дебют -
почтовый сервер.
Потребовался простейший почтовый сервер с поддержкой нескольких доменов...
Потребовался простейший почтовый сервер с поддержкой нескольких
доменов на базе FreeBSD 6.1 и последовав примеру хостера, я решил
сделать связку exim+dovecot, использовав для аутентификации mysql. Как
руководство для себя использовал http://www.opennet.ru/docs/134.shtml
, однако конфигурационные файлы указанного и моего приемра различаются,
т.к. exim поднялся до версии 4.60, а dovecot - до 1.0.b3 и мне пришлось
кое-что править ручками. Данная инструкция позволяет быстро собрать
100% работающий почтовый сервер на базе FreeBSD из родных портов этой
системы с поддержкой протоколов smtp, pop3 и imap с хранением учетных
записей пользователей в базе данных mysql, а почты - в папке /var/mail.
Итак, приступим.
1. Подготовка
Для работы с сервером баз данных есть необходимое условие - чтобы в
системе был установлен mysql-client, т.к. и exim и dovecot используют
его библиотеки. Сам сервер может находиться где угодно. Необходимо
создать базу данных и, из соображений безопасности, завести отдельного
пользователся для это БД:
CREATE DATABASE mail;
GRANT ALL PRIVILEGES ON mail.* TO mailuser@localhost IDENTIFIED BY 'my_password';
Создавать таблицы мы будем после компиляции серверов.
Также для компиляции потребуется gmake. Впрочем, если Вы его не установите, система портов сама его достанет и установит;).
2. Компиляция exim
Поскольку устанавливать серверы мы будем из портов, то, соответственно,
они должны присутствовать в Вашей системе. В портах уже присутствует
exim-mysql, поэтому компилировать будем именно его:
cd /usr/ports/mail/exim-mysql
make&&make install
Не забудьте прописать в /etc/rc.conf строку exim_enable="YES", чтобы он стартовал при запуске системы.
3. Компиляция dovecot
Здесь нет ничего особенного, за исключением того, что перейдя в
/usr/ports/mail/dovecot и набрав команду make, выскочит запрос о том, с
какими опциями мы захотим скомпилировать dovecot? Лично я отказался от
всего кроме mysql. Если Вы выбрали ошибочную конфигурацию и при этом
умудрились нажать OK, то этот процесс можно прервать, нажав Ctrl+C...
Снова make... Но что это??? На этот раз нас ничего не спросили??? Дело
в том, что выбранные в первый раз опции сохранились в файле
/var/db/ports/dovecot/options и если удалить этот файл - при попытке
компиляции снова будет задан вопрос. Либо можно набрать make rmconfig - результат будет тот же.
cd /usr/ports/mail/dovecotmake -DWITH_MYSQL -DWITHOUT_VPOPMAIL
-DWITHOUT_LDAP && make -DWITH_MYSQL -DWITHOUT_VPOPMAIL
-DWITHOUT_LDAP install
После установки будет предложено создать пользователя и группу dovecot
- соглашайтесь, т.к. процесс авторизации будет выполняться именно этим
пользователем.
4. База данных
Пример базы взят из указанного выше примера
http://www.opennet.ru/docs/134.shtml. Ниже - дамп базы данных, отличие
от примера состоит в uid и gid, которые прописаны в CREATE TABLE
таблицы users. Дело в том, что uid, указанный в примере (1003) не
совпадает с uid, под которыми создается пользователь exim'а (26).
Именно с правами доступа могут быть связаны некоторые сложности работы
сервера.
begin routers
dnslookup:
driver = dnslookup
domains = ! +local_domains
transport = remote_smtp
ignore_target_hosts = 0.0.0.0 : 127.0.0.0/8
no_more
system_aliases:
driver = redirect
allow_fail
allow_defer
data = ${lookup mysql{SELECT recipients FROM aliases WHERE local_part='${local_part}' AND domain='${domain}'}}
userforward:
driver = redirect
allow_fail
allow_defer
data = ${lookup mysql{SELECT recipients FROM userforward WHERE local_part='${local_part}' AND domain='${domain}'}}
virtual_localuser:
driver = accept
domains = ${lookup mysql{SELECT domain from domains WHERE domain='${domain}'}}
local_parts = ${lookup mysql{SELECT login from users WHERE login='${local_part}' AND domain='${domain}'}}
transport = local_delivery
localuser:
driver = accept
check_local_user
transport = local_delivery
cannot_route_message = Unknown user
begin transports
remote_smtp:
driver = smtp
local_delivery:
driver = appendfile
check_string = ""
create_directory
delivery_date_add
directory = /var/mail/$domain/$local_part
directory_mode = 770
envelope_to_add
group = mail
maildir_format
maildir_tag = ,S=$message_size
message_prefix = ""
message_suffix = ""
mode = 0660
quota = ${lookup mysql{SELECT quota FROM users WHERE login='${local_part}' AND domain='${domain}'}{${value}M}}
quota_size_regex = S=(\d+)$
quota_warn_threshold = 75%
return_path_add
address_pipe:
driver = pipe
return_output
address_file:
driver = appendfile
delivery_date_add
envelope_to_add
return_path_add
address_reply:
driver = autoreply
begin retry
* * F,2h,15m; G,16h,1h,1.5; F,4d,6h
begin rewrite
begin authenticators
auth_plain:
driver = plaintext
public_name = PLAIN
server_condition = ${lookup mysql{SELECT login FROM users WHERE
login = '${quote_mysql:${local_part:$2}}' AND domain =
'${quote_mysql:${domain:$2}}' AND decrypt = '${quote_mysql:$3}' AND
status = '1'}{yes}{no}}
server_prompts = :
server_set_id = $2
auth_login:
driver = plaintext
public_name = LOGIN
server_condition = ${lookup mysql{SELECT login FROM users WHERE
login = '${quote_mysql:${local_part:$1}}' AND domain =
'${quote_mysql:${domain:$1}}' AND decrypt = '${quote_mysql:$2}' AND
status = '1'}{yes}{no}}
server_prompts = Username:: : Password::
server_set_id = $1
auth_cram_md5:
driver = cram_md5
public_name = CRAM-MD5
server_secret = ${lookup mysql{SELECT decrypt FROM users WHERE
login = '${quote_mysql:${local_part:$1}}' AND domain =
'${quote_mysql:${domain:$1}}' AND status = '1'}{$value}fail}
server_set_id = $1
6. Конфигурация dovecot
Файл /usr/local/etc/dovecot.conf
base_dir = /var/run/dovecot/
protocols = imap pop3
ssl_disable = yes #если нам не нужен SSL
disable_plaintext_auth = no #Иначе не пустит на сервер с простой аутентификацией
log_path = /var/log/dovecot
log_timestamp = "%b %d %H:%M:%S "
syslog_facility = mail
login_user = dovecot
login_process_size = 64
login_greeting = Dovecot at mail.bsd.home is ready. PREVED! ;)
verbose_proctitle = yes
first_valid_uid = 25
first_valid_gid = 6
mail_extra_groups = mail
default_mail_env = maildir:/var/mail/%d/%n
umask = 0007 # Эту опцию я опишу ниже
protocol imap {
login_executable = /usr/local/libexec/dovecot/imap-login
mail_executable = /usr/local/libexec/dovecot/imap
imap_client_workarounds = delay-newmail outlook-idle netscape-eoh tb-extra-mailbox-sep
}
protocol pop3 {
login_executable = /usr/local/libexec/dovecot/pop3-login
mail_executable = /usr/local/libexec/dovecot/pop3
pop3_uidl_format = %08Xu%08Xv
pop3_client_workarounds = outlook-no-nuls oe-ns-eoh
}
auth_executable = /usr/local/libexec/dovecot/dovecot-auth
auth default {
mechanisms = plain
passdb pam {
}
passdb sql {
args = /usr/local/etc/dovecot-mysql.conf
}
userdb passwd {
}
userdb sql {
args = /usr/local/etc/dovecot-mysql.conf
}
user = root
}
Опция umask задает права на доступ к файлам и папкам, которые создает
dovecot. Если оставить эту опцию по умолчанию - будут создаваться папки
с разрешением rwx------, а это не есть гуд, надо еще и членам группы
mail дать достьуп туда.
login_greeting можете написать любой, хоть "Эксчендж", хоть "ПРЕВЕД
МЕДВЕД!" - это сообщение, которое будет выдаваться сервером при
соединении.
default_mail_env я заменил - теперь почтовый ящик физически находится в /var/mail/bsd.home/admin/
Файл /usr/local/etc/dovecot-mysql.conf
driver = mysql
default_pass_scheme = CRYPT
connect = host=localhost dbname=mail user=mailuser password=my_password
password_query = SELECT password FROM users WHERE login = '%n' AND domain = '%d' AND status = '1'
user_query = SELECT uid, gid FROM users WHERE login = '%n' AND domain = '%d'
7. Финал
Теперь самое время проверить работоспособность сервера... Вы не забыли указать в своем DNS зоны и MX-записи? ;)
Для быстрого создания пользователей в пределах одного домена я сделал
скрипт на perl, который требует только наличие в системе консольного
mysql-клиента. При этом предполагается, что домен bsd.home уже добавлен
в таблицу domains.
$email=~/([-a-z0-9]+)\@(.+)/;
$login=$1;
$domain=$2;
$query.="INSERT INTO users VALUES(\"$login\",'',ENCRYPT(\"$pass\"),\"$pass\",26,26,\"$domain\",'0','1');";
open(SQL,"|/usr/local/bin/mysql -h $dbhost -u $dbuser -p$dbpass $dbname")||die "Cannot open pipe to mysql";
print SQL $query;
close SQL;
Итак, добавили пользователей, можно пробовать. Запустите серверы
командами /usr/local/etc/rc.d/exim.sh start и
/usr/local/etc/rc.d/dovecot start . Кроме отладочных сообщений и
предупреждений ничего более не должно выводиться. Проверьте, слушают-ли
серверы порты:
-bash2-2.05b$ telnet 127.0.0.1 25
Trying 127.0.0.1...
Connected to localhost.home.
Escape character is '^]'.
220 bsd.home ESMTP Exim 4.60 Mon, 23 Oct 2006 17:59:40 +0500
HELO bsd.home
250 bsd.home Hello localhost.home [127.0.0.1]
MAIL FROM:
admin@bsd.homeadmin@bsd.home
250 OK
RCPT TO:
admin@bsd.homeadmin@bsd.home
250 Accepted
DATA
354 Enter message, ending with "." on a line by itself
Subject: Hello, there!
Helo, it's a test
PREVED!
.
250 OK id=1GbzPa-0000Oi-EZ
QUIT
221 bsd.home closing connection
Connection closed by foreign host.
Да, отправилось. Теперь попробуем принять по протоколу POP3: