Почтовый сервер Exim + Dovecot
Опубликовано вс, 12/15/2013 – 18:26 пользователем Demontager
Заметка о том как можно настроить самый простой почтовый сервер на базе Exim и Dovecot. Этот конфиг я использовал на FreeBSD сервере и только модифицировал его чтобы он работал на Debian/Ubuntu Linux. Используется простая SMTP авторизация с хранением аккаунтов и паролей в базе данных MySQL. Так как мне не нужно защищенное соединение, SSL/TLS авторизация не используется. Пошагово разберем установку
1. Начнем с установки пакетов
#apt-get install dovecot-imapd dovecot-pop3d dovecot-common dovecot-mysql exim4-daemon-heavy
2. Ставим mysql сервер и задаем пароль рута
apt-get install mysql-server mysqladmin -u root password NEWPASSWORD
3. Создать БД exim_db.
mysql -uroot -pMySQLpass mysql>create database exim_db; mysql>quit;
Заранее подготовить структуру таблиц в базе mysql. Сохраните ее в формате base.sql в любом текстовом редакторе и подготовьте для иморта.
-- phpMyAdmin SQL Dump -- version 4.0.4-rc1 -- http://www.phpmyadmin.net -- -- Host: localhost -- Generation Time: Dec 15, 2013 at 03:08 PM -- Server version: 5.5.29-0ubuntu1 -- PHP Version: 5.4.9-4ubuntu2 SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; SET time_zone = "+00:00"; /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; /*!40101 SET NAMES utf8 */; -- -- Database: `exim_db` -- -- -------------------------------------------------------- -- -- Table structure for table `accounts` -- CREATE TABLE IF NOT EXISTS `accounts` ( `login` varchar(128) COLLATE utf8_bin NOT NULL DEFAULT '', `password` varchar(128) COLLATE utf8_bin NOT NULL DEFAULT '', `uid` int(11) NOT NULL DEFAULT '118', `gid` int(11) NOT NULL DEFAULT '8', `domain` varchar(128) COLLATE utf8_bin NOT NULL DEFAULT 'nixtalk.com', `quota` varchar(16) COLLATE utf8_bin NOT NULL DEFAULT '250M', `status` int(11) NOT NULL DEFAULT '1', PRIMARY KEY (`login`,`domain`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin; -- -- Dumping data for table `accounts` -- INSERT INTO `accounts` (`login`, `password`, `uid`, `gid`, `domain`, `quota`, `status`) VALUES ('support', 'secretPassword', 118, 8, 'nixtalk.com', '250M', 1); -- -------------------------------------------------------- -- -- Table structure for table `aliases` -- CREATE TABLE IF NOT EXISTS `aliases` ( `address` varchar(128) COLLATE utf8_bin DEFAULT NULL, `goto` varchar(128) COLLATE utf8_bin DEFAULT NULL, `domain` varchar(128) COLLATE utf8_bin DEFAULT 'nixtalk.com' ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin; -- -------------------------------------------------------- -- -- Table structure for table `domains` -- CREATE TABLE IF NOT EXISTS `domains` ( `domain` varchar(128) COLLATE utf8_bin NOT NULL DEFAULT '', `status` int(11) NOT NULL DEFAULT '1', PRIMARY KEY (`domain`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin; -- -- Dumping data for table `domains` -- INSERT INTO `domains` (`domain`, `status`) VALUES ('nixtalk.com', 1); -- -------------------------------------------------------- -- -- Table structure for table `whitelist` -- CREATE TABLE IF NOT EXISTS `whitelist` ( `senders` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT 'support@nixtalk.com' ) ENGINE=InnoDB DEFAULT CHARSET=latin1; /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
Пояснения к cтруктуре базы:
для примера уже вставлен один аккаунт support@nixtalk.com c квотой 250M. Если нужно добавить другой аккаунт, предпочтительно делать это в phpmyadmin, выбрав таблицу и нажав Insert. По дефолту доступ к почте имеет пользователь с uid 118, входящий в группу с gid 8.
для примера уже вставлен один аккаунт support@nixtalk.com c квотой 250M. Если нужно добавить другой аккаунт, предпочтительно делать это в phpmyadmin, выбрав таблицу и нажав Insert. По дефолту доступ к почте имеет пользователь с uid 118, входящий в группу с gid 8.
Импортируем базу через phpmyadmin или с терминала
mysql -uroot -pMySQLpass exim_db < base.sql
4. Редактируем основной конфиг exim-а
nano /etc/exim4/update-exim4.conf.conf
#почта будет ходить через Internet dc_eximconfig_configtype='internet' dc_other_hostnames='nixtalk.com' dc_local_interfaces='127.0.0.1' dc_readhost='' dc_relay_domains='nixtalk.com' dc_minimaldns='false' #через эти сети разрешен relay dc_relay_nets='127.0.0.1:77.124.5.76' dc_smarthost='' CFILEMODE='644' dc_use_split_config='false' dc_hide_mailname='' dc_mailname_in_oh='true' dc_localdelivery='mail_spool' dc_use_split_config='false'
– очень важный момент, этим мы указывает что хотим использовать только один конфигурационный файл для exim. Это сделано в целях удобства, так как общая конфигурация довольна простая и не требует указания большого количества директив.
После внесения изменений не забываем выполнить
update-exim4.conf
Все файлы и папки кроме update-exim4.conf.conf и exim4.conf.template можно удалить. Теперь редактируем exim4.conf.template
nano /etc/exim4/exim4.conf.template
и приводим к такому виду, заменяя на свои данные
primary_hostname = mail.nixtalk.com # имя базы и пароль hide mysql_servers = localhost/exim_db/exim/eximPassword domainlist local_domains = ${lookup mysql{select domain from domains where domain='${domain}'}} domainlist relay_to_domains = ${lookup mysql{select domain from domains where domain='${domain}'}} hostlist relay_from_hosts = localhost : 127.0.0.1 acl_smtp_rcpt = acl_check_rcpt acl_smtp_data = acl_check_data #tls_certificate = /etc/ssl/certs/favmail.pem #tls_privatekey = /etc/ssl/certs/favmail.pem #порт smtp daemon_smtp_ports = 25 #tls_on_connect_ports = 465 qualify_domain = mail.nixtalk.com allow_domain_literals = false exim_user = Debian-exim exim_group = mail never_users = root host_lookup = * rfc1413_hosts = * rfc1413_query_timeout = 5s ignore_bounce_errors_after = 2h timeout_frozen_after = 7d return_size_limit = 10K split_spool_directory = true syslog_timestamp = no begin acl acl_check_rcpt: accept hosts = : deny domains = +local_domains local_parts = ^[.] : ^.*[@%!/|] deny domains = !+local_domains local_parts = ^[./|] : ^.*[@%!] : ^.*/\\.\\./ accept senders=${lookup mysql{SELECT senders FROM whitelist \ WHERE senders='${quote_mysql:$sender_address}'}} deny message = HELO/EHLO required by SMTP RFC condition = ${if eq{$sender_helo_name}{}{yes}{no}} deny message = Go Away! You are spammer. condition = ${if match{$sender_host_name} \ {bezeqint\\.net|net\\.il|pool|peer|dhcp} \ {yes}{no}} deny message = rejected because $sender_host_address \ is in a black list at $dnslist_domain\n$dnslist_text hosts = !+relay_from_hosts !authenticated = * log_message = found in $dnslist_domain dnslists = bl.spamcop.net : \ cbl.abuseat.org : \ dnsbl.njabl.org : \ pbl.spamhaus.org warn set acl_m0 = 25s warn hosts = +relay_from_hosts set acl_m0 = 0s warn authenticated = * set acl_m0 = 0s warn logwrite = Delay $acl_m0 for $sender_host_name \ [$sender_host_address] with HELO=$sender_helo_name. Mail \ from $sender_address to $local_part@$domain. delay = $acl_m0 drop message = Rejected - Sender Verify Failed log_message = Rejected - Sender Verify Failed hosts = * !verify = sender/no_details/callout=2m,defer_ok !condition = ${if eq{$sender_verify_failure}{}} accept domains = +local_domains endpass message = unknown user verify = recipient accept domains = +relay_to_domains endpass message = unrouteable address verify = recipient accept hosts = +relay_from_hosts accept authenticated = * deny message = relay not permitted acl_check_data: # China symbols deny message = This is spam - denied !senders = : condition = ${if match{$message_body}{105[-_]*51[-_]*86|778[-_]*98[-_]*94}{yes}{no}} #Extensions deny message = contains $found_extension file (blacklisted). !senders = : demime = com:vbs:bat:pif:scr:exe #Check MIME deny message = This message contains a MIME error ($demime_reason) !senders = : demime = * condition = ${if >{$demime_errorlevel}{2}{1}{0}} #Messages with NUL- symbols deny message = This message contains NUL characters !senders = : log_message = NUL characters! condition = ${if >{$body_zerocount}{0}{1}{0}} # Headers deny message = Incorrect headers syntax hosts = !+relay_from_hosts:* !senders = : !verify = header_syntax accept 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 goto from aliases where address='${quote_mysql:$local_part}' and domain='${quote_mysql:$domain}'}} user = Debian-exim group = mail file_transport = address_file pipe_transport = address_pipe userforward: driver = redirect check_local_user no_verify no_expn check_ancestor file_transport = address_file pipe_transport = address_pipe reply_transport = address_reply data = ${lookup mysql{select goto from aliases where address='${quote_mysql:$local_part}' and domain='${quote_mysql:$domain}'}} localuser: driver = accept domains = ${lookup mysql{select domain from domains where domain='${domain}'}} local_parts = ${lookup mysql{select login from accounts where login='${local_part}' and domain='${domain}'}} transport = local_delivery cannot_route_message = Unknown user begin transports remote_smtp: driver = smtp local_delivery: driver = appendfile maildir_format maildir_tag = ,S=$message_size directory = /home/mail/$domain/$local_part create_directory delivery_date_add envelope_to_add return_path_add group = mail mode = 0660 no_mode_fail_narrower 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 server_set_id = $2 server_prompts = : public_name = PLAIN server_condition = ${lookup mysql{select login from accounts where login='${quote_mysql:${local_part: $2}}' and password='${quote_mysql:$3}'}{yes}{no}} auth_login: driver = plaintext public_name = LOGIN server_set_id = $1 server_prompts = Username:: : Password:: server_condition = ${lookup mysql{select login from accounts where login='${quote_mysql:${local_part: $1}}' and password='${quote_mysql:$2}'}{yes}{no}} auth_cram_md5: driver = cram_md5 public_name = CRAM-MD5 server_secret = ${lookup mysql{select password from accounts where login='${quote_mysql: ${local_part:$1}}'}{$value}fail} server_set_id = $1
5. Теперь настроим dovecot, редактируем
nano /etc/dovecot/dovecot.conf auth_default_realm = mail.nixtalk.com auth_verbose = yes base_dir = /var/run/dovecot/ disable_plaintext_auth = no first_valid_gid = 8 first_valid_uid = 118 login_greeting = Dovecot ready log_path = /var/log/dovecot.log login_log_format_elements = user=<%u> method=%m rip=%r lip=%l %c mail_access_groups = mail mail_debug = yes mail_location = maildir:/home/mail/%d/%n passdb { args = /etc/dovecot/dovecot-sql.conf driver = sql } protocols = pop3 imap service auth { unix_listener auth-master { mode = 0600 user = Debian-exim } user = root } service imap-login { chroot = login inet_listener imap { address = * port = 143 } process_limit = 3 process_min_avail = 3 service_count = 1 user = dovecot vsz_limit = 64 M } service pop3-login { chroot = login inet_listener pop3 { address = * port = 110 } process_limit = 3 process_min_avail = 3 service_count = 1 user = dovecot vsz_limit = 64 M } ssl = no #ssl_cert = </etc/ssl/certs/favmail.pem #ssl_key = </etc/ssl/certs/favmail.pem userdb { args = /etc/dovecot/dovecot-sql.conf driver = sql } verbose_proctitle = yes #protocol imap { # imap_client_workarounds = delay-newmail tb-extra-mailbox-sep #} protocol pop3 { pop3_client_workarounds = outlook-no-nuls oe-ns-eoh pop3_uidl_format = %08Xu%08Xv } protocol lda { auth_socket_path = /var/run/dovecot/auth-master postmaster_address = support@nixtalk.com }
6. Редактируем конфиг dovecot для доступа к mysql базе
nano /etc/dovecot/dovecot-sql.conf
driver=mysql connect=host=127.0.0.1 dbname=exim_db user=exim password=eximPassword default_pass_scheme=PLAIN password_query=select password from accounts where login='%n' and domain='%d' user_query=select uid, gid from accounts where login='%n' and domain='%d'
7. Создаем директорию для писем и даем ей права
mkdir /home/mail chown Debian-exim:exim /home/mail
8. Прописываем в /etc/hosts IP нашего почтового сервера
77.124.5.76 nixtalk.com 77.124.5.76 mail.nixtalk.com
На этом настройка закончена и в конце даю короткие команды где смотреть логи
tailf /var/log/dovecot.log tailf /var/log/exim4/mainlog tailf /var/log/exim4/rejectlog tailf /var/log/exim4/paniclog # Появляется при фатальных ошибках
Перезапуск сервисов
serviсe dovecot restart service exim4 restart