Главная > Linux > Почтовый SMTP / IMAP сервер своими руками.

Почтовый SMTP / IMAP сервер своими руками.

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

За прошедшее время набралось по крайней мере три темы, которые я хотел бы осветить в блоге. Начать решил с установки и настройки своего полноценного почтового сервера на связке Postfix + Dovecot + MySQL в системе Debian Squeeze.

Оглавление

Инструментарий

В качестве MTA я выбрал Postfix по нескольким причинам: мне он показался самым простым в настройке, обладающим всем необходимым функционалом, активно разрабатывается, имеет хорошую документацию и, самое главное, умеет работать с Dovecot из коробки.

MDA был выбран Dovecot за свою хорошую документацию, простоту конфигурирации и возможность тесно работать с Postfix.

Чтобы обеспечить максимальную гибкость, я решил связать почтовую систему с базой данных. Трудностей в выборе СУБД не возникло, так как и Postfix и Dovecot могут работать практически с любой хорошо известной (PostgreSQL, SQLite, MySQL). Здесь я взял первое что пришло в голову — MySQL.

С выбором операционной системы в которой все это дело будет работать проблемы так же не появилось. Выбрать я мог одно из двух: Debian или Ubuntu, с которыми я достаточно хорошо знаком. Debian был проверен временем и все необходимое для настройки было в репозиториях, поэтому я остановился на нем. Squeeze — потому, что stable морально устарел, а testing уже несколько месяцев в заморозке перед релизом.

Подготовка

Установим необходимые пакеты:

~$ sudo aptitude install postfix postfix-mysql dovecot-imapd mysql-server

Подготовим mysql:

-- создаем нового пользователя mailuser@localhost с паролем mailpassword
CREATE USER 'mailuser'@'localhost' IDENTIFIED BY 'mailpassword';

-- создадим базу данных mailserver
CREATE DATABASE IF NOT EXISTS `mailserver`;

-- дадим созданному пользователю все права на созданную БД
GRANT ALL PRIVILEGES ON `mailserver`.* TO 'mailuser'@'localhost';

-- выбираем созданную БД
USE mailserver;

-- создаем таблицу для хранения виртуальных доменов
CREATE TABLE `virtual_domains` (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
name VARCHAR( 50 ) NOT NULL
) ENGINE = INNODB;

-- создаем таблицу для виртуальных пользователей
CREATE TABLE `virtual_users` (
id INT( 11 ) NOT NULL AUTO_INCREMENT PRIMARY KEY,
domain_id INT( 11 ) NOT NULL,
user VARCHAR( 40 ) NOT NULL,
PASSWORD VARCHAR( 32 ) NOT NULL,
CONSTRAINT UNIQUE_EMAIL UNIQUE (
domain_id,
user
),
FOREIGN KEY ( domain_id ) REFERENCES virtual_domains( id ) ON DELETE CASCADE
) ENGINE = INNODB;

-- создаем таблицу для хранения виртуальных алиасов
CREATE TABLE `virtual_aliases` (
id INT( 11 ) NOT NULL AUTO_INCREMENT PRIMARY KEY,
domain_id INT( 11 ) NOT NULL,
source VARCHAR( 40 ) NOT NULL,
destination VARCHAR( 80 ) NOT NULL,
FOREIGN KEY ( domain_id ) REFERENCES virtual_domains( id ) ON DELETE CASCADE
) ENGINE = INNODB;

-- создаем виртуальную таблицу с пользовательскими аккаунтами
CREATE VIEW `view_users` AS SELECT CONCAT(virtual_users.user, '@', virtual_domains.name ) AS email, virtual_users.password
FROM virtual_users
LEFT JOIN virtual_domains ON virtual_users.domain_id = virtual_domains.id;

-- создаем виртуальную таблицу с алиасами
CREATE VIEW `view_aliases` AS SELECT CONCAT( virtual_aliases.source, '@', virtual_domains.name ) AS email, destination
FROM virtual_aliases
LEFT JOIN virtual_domains ON virtual_aliases.domain_id = virtual_domains.id;

Первичная настройка Postfix

Создадим файл /etc/postfix/mysql_virtual_domains.cf со следующим содержанием:

user = mailuser
password = mailpassword
hosts = 127.0.0.1
dbname = mailserver
query = SELECT 1 FROM virtual_domains WHERE name='%s'

Добавим в файл /etc/postfix/main.cf опцию virtual_mailbox_domains.
Эта опция проверяет список доменов с которыми Postfix может работать. В данном случает результат будет взят из MySQL:

virtual_mailbox_domains = mysql:/etc/postfix/mysql_virtual_domains.cf

Добавим в базу новый виртуальный домен:

INSERT INTO virtual_domains (name) VALUES ('example.com');

Если все настроено верно, то следующая команда выдаст в качестве результата единицу:

~$ sudo postmap -q example.com mysql:/etc/postfix/mysql_virtual_domains.cf

Создадим файл /etc/postfix/mysql_virtual_maps.cf:

user = mailuser
password = mailpassword
hosts = 127.0.0.1
dbname = mailserver
query = SELECT 1 FROM view_users WHERE email='%s'

Добавим в файл /etc/postfix/main.cf опцию virtual_mailbox_maps.
Эта опция проверяет существование почтовых адресов на сервере:

virtual_mailbox_maps = mysql:/etc/postfix/mysql_virtual_maps.cf

Добавим в базу нового пользователя username с паролем password на домене example.com:

INSERT INTO `virtual_users` (domain_id, user, password) VALUES (1, 'username', MD5('password'));

Проверим результат:

~$ sudo postmap -q username@example.com mysql:/etc/postfix/mysql_virtual_maps.cf

Создадим файл /etc/postfix/mysql_virtual_alias_maps.cf:

user = mailuser
password = mailpassword
hosts = 127.0.0.1
dbname = mailserver
query = SELECT destination FROM view_aliases WHERE email='%s'

Добавим в файл /etc/postfix/main.cf опцию virtual_alias_maps.
Эта опция получает список адресов на которые будет пересылаться вся корреспонденция:

virtual_alias_maps = mysql:/etc/postfix/mysql_virtual_alias_maps.cf

Добавим в базу новый алиас для только что созданного почтового ящика:

INSERT INTO `virtual_aliases` ( domain_id, source, destination )
VALUES ( 1, 'username', 'copy@example.com' );

и проверим результат:

~$ sudo postmap -q username@example.com mysql:/etc/postfix/mysql_virtual_alias_maps.cf

Теперь укажем Postfix использовать Dovecot в качестве локального агента доставки почты.
Для этого добавим следующие строки в /etc/postfix/master.cf:

dovecot unix - n n - - pipe
flags=DRhu user=nobody:nogroup argv=/usr/lib/dovecot/deliver -d ${recipient}

Так же добавим в /etc/postfix/main.cf:

virtual_transport = dovecot
dovecot_destination_recipient_limit = 1

Настройка Dovecot

Файл конфигурации /etc/dovecot/dovecot.conf в общем виде:

# протоколы, с которыми будет работать Dovecot
protocols = imap imaps

# директория, куда будет складываться почта
# %d - имя домена, %n - имя пользователя
mail_location = maildir:/var/spool/virtual/%d/%n

# настройка авторизации
auth default {
# механизмы авторизации
mechanisms = plain login

# получает адрес и пароль из БД для авторизации
passdb sql {
# файл, в котором описывается подключение к БД и сам запрос
args = /etc/dovecot/dovecot-sql.conf
}

# права на директорию с почтой
userdb static {
args = uid=65534 gid=65534 home=/var/spool/virtual/%d/%n allow_all_users=yes
}

# сетевые настройки аутентификации
socket listen {
# для аутентификации подключений к самому Dovecot
master {
path = /var/run/dovecot/auth-master
mode = 0600
user = nobody
}

# для аутентификации внешних приложений ( у нас для Posfix )
client {
path = /var/spool/postfix/private/auth
mode = 0660
user = postfix
group = postfix
}
}
}

# настройка локального агента доставки почты
protocol lda {
# путь до сокета для авторизации
auth_socket_path = /var/run/dovecot/auth-master

# адрес администратора почтового сервера
postmaster_address = postmaster@example.com
}

Файл с описанием подключения к БД для получения данных о пользователе /etc/dovecot/dovecot-sql.conf:

# используем подключение к MySQL
driver = mysql

# параметры MySQL авторизации
connect = host=127.0.0.1 dbname=mailserver user=mailuser password=mailpassword

# формат, в которых хранятся пароли в БД ( у нас это MD5 )
default_pass_scheme = PLAIN-MD5

# запрос, возвращающий пользователя и пароль
password_query = SELECT email as user, password FROM view_users WHERE email='%u';

И не забываем включить сам сервис Dovecot, указав в файле /etc/default/dovecot:

ENABLED=1

Иначе он не будет запускаться.

Заключительная настройка Postfix

Так как авторизация пользователей Postfix у нас производится с помощью Dovecot, то добавим следующие строки в /etc/postfix/main.cf:

smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yes

Так же добавим некоторые правила фильтрации почты, чем отбросим большую часть спам-ботов и им сочувствующих.
Добавим в /etc/postfix/main.cf:

smtpd_client_restrictions =
permit_mynetworks
permit_sasl_authenticated
reject_unknown_client_hostname

smtpd_helo_restrictions =
permit_mynetworks
permit_sasl_authenticated
reject_invalid_helo_hostname
reject_non_fqdn_helo_hostname
reject_unknown_helo_hostname

smtpd_sender_restrictions =
permit_mynetworks
permit_sasl_authenticated
reject_non_fqdn_sender
reject_unknown_sender_domainАга,
reject_unverified_sender

smtpd_recipient_restrictions =
permit_mynetworks
permit_sasl_authenticated
reject_non_fqdn_recipient
reject_unlisted_recipient
reject_unauth_destination

Заключение

Теперь можно смело перезапустить наши сервисы:

~$ sudo invoke-rc.d dovecot restart
~$ sudo invoke-rc.d postfix restart

Вся информация по работе почтовой системы логируется в файлы:

/var/log/mail.log
/var/log/mail.err
/var/log/mail.warn
/var/log/mail.info

Что еще можно сделать с сервером? Скажу, что целую массу полезного и интересного. Из того, что вспомнил, могу предложить проверку на вирусы с помощью ClamAV, «серые» списки с помощью Postgrey, фильтрацию спама с помощью SpamAssassin, Web-клиент для работы с почтой типа RoundCube и многое другое. О части из перечисленного я планирую рассказать, но когда это будет — неизвестно даже мне. :)

Любые предложения и замечания жду в комментариях.

Используемые ресурсы

Дополнения

Описание используемых флагов smtpd_*_restrictions

permit_mynetworks — разрешает любые запросы с IP адресов, указанных в параметре mynetworks.

permit_sasl_authenticated — разрешает любые запросы для пользователей, успешно прошедших аутентификацию на сервере.

reject_unknown_client_hostname — отклоняет все запросы от клиента в одном из трех случаев:

  1. IP адрес клиента не имеет PTR записи на DNS.
  2. Доменное имя клиента не имеет A записи на DNS.
  3. А запись клиента не соответствует его IP адресу.

reject_invalid_helo_hostname — отклоняет запросы от клиентов с неверным FQDN в HELO запросе.

reject_non_fqdn_helo_hostname — отклоняет клиентов с не FQDN в HELO запросе.

reject_unknown_helo_hostname — отклоняет клиентов с неизвестным FQDN в HELO запросе.

reject_non_fqdn_sender — отклоняет клиентов с не FQDN в адресе отправителя.

reject_unknown_sender_domain — отклоняет клиентов с неизвестным FQDN в адресе отправителя.

reject_unverified_sender — проверяет существование адреса отправителя на его сервере и отклоняет запрос если проверка не удалась

reject_non_fqdn_recipient — отклоняет клиентов с не FQDN в адресе получателя.

reject_unlisted_recipient — отклоняет запрос если получатель не существует.

reject_unauth_destination — отклоняет запросы от неавторизованных пользователей сервера.

Утилиты

Для упрощения работы с данным почтовым сервером я написал несколько небольших скриптов.
Взять их можно тут git://github.com/Ky6uk/scripts.git

VN:F [1.9.22_1171]
Rating: 7.9/10 (9 votes cast)
Почтовый SMTP / IMAP сервер своими руками., 7.9 out of 10 based on 9 ratings
Categories: Linux Tags: , , , , , , , ,
  1. 13 Декабрь 2011 в 19:48 | #1
    Использует Google Chrome 17.0.963.2 Google Chrome 17.0.963.2 на Windows 7 x64 Edition Windows 7 x64 Edition

    @Alex G.
    Не могу сказать в чем причина. Несколько раз сам настраивал сервера по этой статье, ни разу не выскачила подобная проблема. Попробуйте поискать в интернете что это за errno: 150

    VN:F [1.9.22_1171]
    Rating: 0.0/5 (0 votes cast)
  2. Тимур
    10 Январь 2012 в 00:19 | #2
    Использует Safari 5.1.2 Safari 5.1.2 на Mac OS X 10.7.2 Mac OS X 10.7.2

    Тимур :
    Использует Firefox 8.0 на UbuntuТак, предыдущая проблема разрешилась сменой хозяев для файлов, теперь проблема новая: настраиваю Thunderbird, подключил пользователя, но он не может послать сообщение даже сам себе. Вроде бы все нормально, никаких ошибок не выдает, даже в mail.err ничего не пишет, но писем никаких не принимает «No messages to download»…. В чем может быть ошибка? Подскажите пожалуйста
    VA:F [1.9.13_1145]один момент…Rating: 0.0/5 (0 votes cast)

    В ходе исследований выяснилось следующее: вся почта уходит в папку алиаса (copy). Если вручную скопировать файлы из нее в папку самого ящика (usermail) — то почтовый клиент примет эти письма. Подскажите, пожалуйста, как можно исправить это безобразие? Очень нужно для курсовой…

    VA:F [1.9.22_1171]
    Rating: 0.0/5 (0 votes cast)
  3. 23 Апрель 2012 в 15:09 | #3
    Использует Firefox 3.6 Firefox 3.6 на Windows 7 Windows 7

    Начало вроде хорошее но у меня поднять сервак не получилось !!! Очень много но… Первое что бросилось в глазе нету параметров описания имени, не создаются сертификаты,,, если для профессионалов то они и так знают !!!

    VA:F [1.9.22_1171]
    Rating: 0.0/5 (0 votes cast)
  4. 17 Октябрь 2012 в 19:43 | #4
    Использует Google Chrome 22.0.1229.94 Google Chrome 22.0.1229.94 на Mac OS X 10.8.2 Mac OS X 10.8.2

    Еще нужно предвательно поставить пакет dovecot-mysql.
    Долго не знал что да как. Потом глянул в логи. Укажите, пожайлуйста, это в статье.

    А так все круто. Спасибо за подробное описание процесса.

    VA:F [1.9.22_1171]
    Rating: 5.0/5 (1 vote cast)
    • 17 Октябрь 2012 в 21:51 | #5
      Использует Google Chrome 23.0.1271.26 Google Chrome 23.0.1271.26 на Windows 7 x64 Edition Windows 7 x64 Edition

      В Debian Squeeze ничего не нужно ставить. Пакет dovecot-imapd уже имеет поддержку SQL. Все это писалось одновременно с чистой установкой.

      VN:F [1.9.22_1171]
      Rating: 0.0/5 (0 votes cast)
  5. kos
    1 Декабрь 2012 в 12:04 | #6
    Использует Google Chrome 23.0.1.0 Google Chrome 23.0.1.0 на Windows 7 x64 Edition Windows 7 x64 Edition

    подскажите, почему после входа в mysql вместо
    «mysql>»
    у меня просто
    «>»
    и после выполнения команд ничего не происходит (по нажатию enter просто переходит к следующей строке
    «>»

    VA:F [1.9.22_1171]
    Rating: 0.0/5 (0 votes cast)
Страницы комментариев
  1. Пока что нет уведомлений.