Почтовый сервер на sendmail + dovecot

Полезные советы и программы от пользователей нашего форума.

Модератор: Модераторы разделов

Ответить
Аватара пользователя
kasak
Сообщения: 893
ОС: OpenBSD
Контактная информация:

Почтовый сервер на sendmail + dovecot

Сообщение kasak »

Когда-то очень давно я решил запустить на своём компьютере почтовый сервер. И поскольку я больше люблю Slackware за его простоту и понятность (а в составе slackware имеется почтовый сервер sendmail), то основываться я решил именно на sendmail. Однако попытавшись найти какую-либо информацию, чтобы понять основы работы с почтой и сендмейлом, я почти везде натыкался на комменты "зачем тебе sendmail? это очень сложно, поставь postfix." В принципе сейчас мне понятны эти предложения, однако я долго разбирался в тонкостях и всё-таки сделал всё на сендмейле.

Для кого этот мануал: для людей, разбирающихся в основах линукс, понимающих, что такое "внешный выделенный IP адрес", и понимающих, что такое dns, однако не знающих как работает почта, и желающих разобраться с ней по одному понятному мануалу.

Сначала я расскажу как работает почта в моём понимании.
Существует множество smtp серверов, которые могут обмениваться почтой между собой. Это как почтовые отделения обмениваются письмами, и некоторые могут подумать, что приёмом почты с этих серверов занимается протокол pop или imap. Это немного не так. Чтобы обмениваться почтой, необходимо и достаточно иметь smtp сервер. Почта будет приходить в локальную папку пользователя или в отдельный файл, из которого её можно прочесть. Протоколы IMAP и POP используются лишь для доставки почты с почтового сервера на клиент приёма почты (например kmail, thunderbird или evolution).
Почта может храниться на сервере в нескольких вариантах, первый - это mailbox. Этот вариант хранит почту в одном большом файле, письма приписываются в него. В итоге создаётся один громоздкий файл. При его повреждении может потеряться даже вся почта. Пока вы читаете письма, этот файл будет заблокирован и новые приходить не смогут. Этот метод устарел, и сегодня используется другой метод - maildir. В этом случае почта будет храниться в директории, каждое письмо - это отдельный файл. Директория с почтой содержит в себе три основных директории: new, cur и tmp. В идеале, когда новое письмо попадает на сервер, оно должно попадать в директорию tmp, после записи в файл всего сообщения на этот файл должна быть создана жётская ссылка в каталоге new, а файл в каталоге tmp будет удалён. Это позволяет предотвратить чтение сообщения другими процессами, до того, как оно будет целым. После прочтения нового письма оно помечается как прочитанное и перемещается в каталог cur.

Sendmail сам по себе не может работать с maildir, однако существует замечательная вещь - procmail. Она может многое, а главное может быть помощником сендмейла, чтобы работать всё-таки с maildir.

Не обращайте внимания на тех, кто громко голосит о том, что сендмейл очень сложен и не нужен. Для моих простых целей (простой почтовый сервер) настроить сендмейл не сложнее, чем тот же vsftpd. Главное сделать это один раз и вы поймёте, что всё не так сложно.

Перед настройкой почтового сервера вам нужно зарегистрировать себе доменное имя, и правильно прописать почтовую запись в dns.
У меня это сделано следующим образом:

Код: Выделить всё

$TTL 86400
@       IN      SOA     ns.somedomain.net.        hostmaster.somedomain.net. (
                        201006061; serial
                        1D; refresh
                        2H; retry
                        1W; expire
                        1D ); ttl
;
                NS      ns.somedomain.net.
                NS      ns.*****.ru.
                A       ***.***.***.*
                MX      10 mx.somedomain.net.
;
ns              A       ***.***.***.***
mx              A       ***.***.***.***


А также должна быть создана обратная запись в реверсной зоне днс.
Поскольку сию инструкцию читает скорее всего новичок и купленных айпи адресов у него нет, то скажу, что реверсную зону днс должен прописывать владелец адреса, скорее всего это ваш провайдер. Настройка dns - это отдельная тема. Если провайдер прописал зону и с вашей стороны домен настроен правильно, можно перейти к следующему шагу. Если обратную зону не прописать, некоторые серверы будут отбрасывать ваши письма.

Пропишите имя почтового сервера в файле /etc/localhost
Запишите туда внешний ip адрес и имя, примерно вот так:
111.111.111.222 mx.somedomain.net mx

Авторизация:
Правильный почтовый сервер должен иметь авторизацию через имя пользователя и пароль. Я предполагаю, что пользователи должны авторизовываться из системных учётных записей и паролей, а письма будут лежать в их домашних директориях. Чтобы научить sendmail авторизовывать, нужен cyrus-sasl. В Slackware он уже идёт в комплекте, однако не умеет работать с нужными механизмами авторизации. Я скачал слакбилд к нему и исправил его, чтобы тот содержал опции сборки

--enable-login \
--enable-plain \
Если этого не сделать, многие клиенты не смогут авторизоваться.
Далее в каталоге /etc/sasl2 создаётся файл Sendmail.conf с содержанием:

Код: Выделить всё

pwcheck_method:saslauthd
mech_list:LOGIN PLAIN

Далее правится файл /etc/rc.d/rc.saslauthd , чтобы sasl запускался с опцией -a shadow.
Я предполагаю, что читатель разбирается в таких простых вещах.

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

cd /usr/share/sendmail/cf/cf/
Я взял за основу файл sendmail-slackware-tls.mc ,
содержание которого я приведу:

Код: Выделить всё

include(`../m4/cf.m4')
VERSIONID(`TLS supporting setup for Slackware Linux')dnl
OSTYPE(`linux')dnl
dnl#
dnl# You will need to create the certificates below with OpenSSL first:
define(`confCACERT_PATH', `/etc/mail/certs/')
define(`confCACERT', `/etc/mail/certs/CA.cert.pem')
define(`confSERVER_CERT', `/etc/mail/certs/smtp.cert.pem')
define(`confSERVER_KEY', `/etc/mail/certs/smtp.key.pem')
dnl# These settings help protect against people verifying email addresses
dnl# at your site in order to send you email that you probably don't want:
define(`confPRIVACY_FLAGS', `authwarnings,novrfy,noexpn,restrictqrun')dnl
dnl# Uncomment the line below to send outgoing mail through an external server:
dnl define(`SMART_HOST',`mailserver.example.com')
dnl# No timeout for ident:
define(`confTO_IDENT', `0')dnl
dnl# Enable the line below to use smrsh to restrict what sendmail can run:
dnl FEATURE(`smrsh',`/usr/sbin/smrsh')dnl
dnl# See the README in /usr/share/sendmail/cf for a ton of information on
dnl# how these options work:
FEATURE(`use_cw_file')dnl
FEATURE(`use_ct_file')dnl
FEATURE(`mailertable',`hash -o /etc/mail/mailertable.db')dnl
FEATURE(`virtusertable',`hash -o /etc/mail/virtusertable.db')dnl
FEATURE(`access_db', `hash -T<TMPF> /etc/mail/access')dnl
FEATURE(`blacklist_recipients')dnl
FEATURE(`local_procmail',`',`procmail -t -Y -a $h -d $u')dnl
FEATURE(`always_add_domain')dnl
FEATURE(`redirect')dnl
dnl# Turn this feature on if you don't always have DNS, or enjoy junk mail:
dnl FEATURE(`accept_unresolvable_domains')dnl
EXPOSED_USER(`root')dnl
dnl# Also accept mail for localhost.localdomain:
LOCAL_DOMAIN(`localhost.localdomain')dnl
MAILER(local)dnl
MAILER(smtp)dnl
MAILER(procmail)dnl
DAEMON_OPTIONS(`Port=smtp, Name=MTA')dnl
dnl# Daemon options after M= below that might need to be changed are:
dnl# s (allow SSL, not only TLS)
dnl# a (require authentication)
DAEMON_OPTIONS(`Port=smtps, Name=MSA-SSL, M=Es')dnl
LOCAL_CONFIG
dnl# Do not allow the weak SSLv2:
O CipherList=ALL:!ADH:!NULL:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:-LOW:+SSLv3:+TLSv1:-SSLv2:+EXP:+eNULL


В принципе, описание ко всем опциям дано прямо в конфиге. Однако я изменил некоторые опции, которые приведу ниже.

Надо настроить авторизацию:

define(`confAUTH_REALM', `somedomain.net')dnl
define(`confAUTH_OPTIONS', `A p y')dnl
define(`confAUTH_MECHANISMS', `LOGIN PLAIN DIGEST-MD5 CRAM-MD5')dnl
TRUST_AUTH_MECH(`LOGIN PLAIN DIGEST-MD5 CRAM-MD5')dnl

Первая строка нужна для того, чтобы при авторизации на сервере не приходилось вводить логин полностью вместе с доменом. Только имя пользователя.
Вторая строка включет механизм авторизации, включает доверие к механизму plain только после того, как соединение будет зашифровано и запрещает анонимные логины.
Третья строка перечисляет механизмы авторизации, которые будут использоваться.
Последняя строка говорит сендмейлу, каким механизмам доверять.
В строке DAEMON_OPTIONS(`Port=smtps, Name=MSA-SSL, M=Es')dnl надо после Es дописать символ 'a', чтобы заставить сендмейл требовать авторизацию по защищённому smtp.

Вот в принципе и всё, что нужно. Дефайны для авторизации надо вводить после описаний MAILER. В макросе должна быть последовательность. Про порядок заполнения mc макросов есть документация, интересующиеся смогут её найти.

Далее надо скомпилировать mc файл. В Slackware для этого рядом лежит файлик Build, который надо вызвать примерно так:
./Build my.mc
Если же речь о не-Slackware, наверное можно скомпилить файлик просто через команду m4, например так:
m4 my.mc > sendmail.cf
По сути скрипт build делает то же самое.
Далее получившийся файлик надо скопировать в /etc/mail с именем sendmail.cf .

В каталоге /etc/mail находятся ещё несколько файлов, которые надо изменить. В local-host-names надо написать имя домена, для которого мы принимаем почту.
Например somehost.net mx.somehost.net

Настройка TLS

Для авторизации на сервере надо использовать защищённый протокол. Для его защиты нужны сертификаты. Сертификаты нужно сгененрировать. К сожалению, я не помню источник, в котором я прочёл как их сгенерировать. Потрудитесь найти источник сами и сгенерируйте нужные сертификаты. Они описаны в опциях
define(`confCACERT', `/etc/mail/certs/CA.cert.pem')
define(`confSERVER_CERT', `/etc/mail/certs/smtp.cert.pem')
define(`confSERVER_KEY', `/etc/mail/certs/smtp.key.pem')
Также можно использовать сертификаты от довекота (dovecot), описание которого будет дано ниже.
В принципе, если я ничего не забыл, можно запускать saslauthd и sendmail. Работать должно.

Далее установите довекот.
Его конфиг должен выглядеть так:

Код: Выделить всё

base_dir = /var/run/dovecot/

protocols = pop3 imap imaps pop3s

ssl =yes
ssl_cert_file = /etc/ssl/certs/dovecot.pem
ssl_key_file = /etc/ssl/private/dovecot.pem

protocol pop3 {
listen = *:110
ssl_listen = *:995
}

protocol imap {
listen = *:143
ssl_listen = *:993
}

protocol lda {
log_path = /var/log/deliver.log
info_log_path = /var/log/deliver.log
}

log_path = /var/log/dovecot.log
info_log_path = /var/log/dovecot.log
disable_plaintext_auth = no
mail_location = maildir:~/Maildir
auth default {
mechanisms = plain login
userdb passwd {
}

passdb shadow {
}

}
auth_debug = yes


Ничего более для его настройки не нужно.

Теперь самое интересное. Чтобы всё это заработало, нужно чтобы сендмеил клал письма в каталог пользователя. Но перед этим надо установить фильтр спама. В слакваре это проще всего сделать, установив через cpan зависимости сендмейла (поищите их в интернете, это не трудно). А потом и сам сендмейл. Можно попробовать поставить через cpan и его, но работает это криво. Проще скачать пакет spamassassin с его родного сайта и собрать вот так:
perl Makefile.pl PREFIX=/usr SYSCONFDIR=/etc
make
make install

Когда фильтр установлен, добавьте в rc.local строку запуска спам демона:
spamd -c -d

Теперь конфиг процмейл (procmail), он должен называться /etc/procmailrc
и содержание его должно быть такое:

Код: Выделить всё

LOGFILE=$HOME/procmail.log
DROPPRIVS=yes
UMASK=007
DEFAULT=$HOME/Maildir
MAILDIR=$DEFAULT

:0fw
* < 512000
| /usr/bin/spamc -f
:0
* ^X-Spam-Status: Yes
$DEFAULT/.Junk/new
:0
$DEFAULT/new

Опция DROPPRIVS отвечает за то, чтобы письма к пользователям доставлялись в правильных правах доступа, и не приходилось создавать каждый раз procmailrc в папках пользователей. Достаточо один раз настроить процмейл.

Остальные опции должны быть интуитивно понятны. DEFAULT и MAILDIR - это просто переменные. UMASK - это название, которое говорит само за себя =)
Далее идут правила. Правила начинаются с :0, потом идут опции. Потом иногда ставят двоеточие. В этом случае создаётся специальный файл lock, блокирующий доступ к файлу, с которым работает procmail до его освобождения. С локами надо быть осторожнее. Об этом дальше.
После :0 идёт описание, какую почту обрабатывать и как. * < 512000 означает, что обрабатывать почту надо только размером меньше, чем 512000 байт.
| /usr/bin/spamc -f означает, что почта будет перенаправлена в клиент от клиент-серверной системы spamassassin.
Далее идёт правило, направляющее почту с пометкой X-Spam-Status в папку junk, то есть спам. Последнее правило кладёт остальную почту в нужную папку.
Так вот про локи: промните простые правила. Если вы направляете почту на спам фильтр спамассассин (в не-клиент-серверном варианте), то надо ставить двоеточие, например
:0fw:
|/usr/bin/spamassassin
Если же использовать клиент-серверную версию, то блок ставить не надо.
И ещё одно: если почта идёт в mailbox, то блок надо ставить. Если в maildir, то не надо. Вот и весь секрет.

В принципе это всё, что нужно для функционирования. Извините, что не описал некоторые процессы, например как создавать сертификаты или не описал что-то более подробно. Если есть вопросы, спрашивайте, я отвечу.
Итак, система будет работать следующим образом: приходящее письмо будет перенаправляться в домашний каталог пользователя в папку Maildir. Например письмо пользователю kasak будет положено в /home/kasak/Maildir/ ,
оно будет направлено от сендмейла к процмейлу, который и положит его на место. Когда вы будете настраивать почтовый клиент, укажите как логин - логин системного юзера и от него же пароль. И то же самое для smtp сервера. (Можно поставить галочку "использовать для авторизации по smtp имя от imap (pop)")
Имап сервер будет связующим звеном между папкой на сервере и почтовым клиентом. Спам будет помещаться в папку junk (её будет видно в почтовом клиенте).


P.S. Безусловно можно построить более красивые и правильные варианты при помощи dovecot + postfix. Довекот может предоставлять сокет для авторизации постфиксу и постфикс может передавать довекоту письма, чтобы он их сам доставлял до нужного мейлдира и было бы всё чинно-благородно. Я настраивал такие сервера и мне нравится, как они работают, однако я описал другой способ.
Также гуру скажут, что класть процмейлом почту прямо в папку new - это неправильно, скажут, что лучше передать её довекотовому деливеру и чтобы деливер сам клал её как надо, скажут, что это быстрее и првильнее. И я согласен, это так. Но, к сожалению, у меня эта схема не сработала. Деливер выдаёт ошибку и письма исчезают. Если расскажут мне гуру, как это настроить, буду очень рад.
Успехов вам всем. Если надо что-то добавить, спрашивайте. С радостью поделюсь. Но помните, я не профи, я такой же ламер как вы.



UPDATE:

Родной деливер от довекота всё-таки заработал. Во-первых я обновил довекот до второй версии.
Вот кусок конфига от деливера:

Код: Выделить всё

protocol lda {
  info_log_path = /var/log/deliver.log
  log_path = /var/log/deliver.log
}


Файл /var/log/deliver.log надо создать и сделать ему права ugo+rw (666) дабы была возможность самому деливеру писать в этот конфиг.
/etc/procmailrc при этом принимает вид:

Код: Выделить всё

LOGFILE=/var/log/maillog
DELIVER=/usr/libexec/dovecot/dovecot-lda
DROPPRIVS=yes
UMASK=007
DEFAULT=$HOME/Maildir
MAILDIR=$DEFAULT

:0fw
* < 512000
| /usr/bin/spamc -f
:0
* ^X-Spam-Status: Yes
| $DELIVER -m Junk
:0
| $DELIVER


Теперь почта летит "как надо". Вообще-то на лог файл /var/log/deliver.log возможно достаточно просто назначить правильного владельца и сделать права 640, но кто этот таинственный владелец один леший знает, ни dovecot ни dovenull не подошли. Так что я просто оставил rw-rw-rw- до лучших времён.
Linux kasakoff 5.10.7-200.fc33.x86_64 #1 SMP Tue Jan 12 20:20:11 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
Спасибо сказали:
Аватара пользователя
kasak
Сообщения: 893
ОС: OpenBSD
Контактная информация:

Re: Почтовый сервер на sendmail + dovecot

Сообщение kasak »

что-то я коментов не вижу. не понравилось наверно?

как дополнительный совет могу сказать, спамассассина можно обучать (алгоритм байеса)
вот так:
sa-learn --spam /home/user/Maildir/.Junk/cur
sa-learn --ham /home/user/Maildir/cur


в основном это конечно рассчитано на одного пользователя, но работать будет и со многими. просто скрипт обучиния должен быть хитрее. написать несложно
Linux kasakoff 5.10.7-200.fc33.x86_64 #1 SMP Tue Jan 12 20:20:11 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
Спасибо сказали:
Аватара пользователя
sash-kan
Администратор
Сообщения: 13939
Статус: oel ngati kameie
ОС: GNU
Контактная информация:

Re: Почтовый сервер на sendmail + dovecot

Сообщение sash-kan »

kasak писал(а):
10.08.2010 23:14
что-то я коментов не вижу
вероятно, sendmail мало кого интересует.
Писать безграмотно - значит посягать на время людей, к которым мы адресуемся, а потому совершенно недопустимо в правильно организованном обществе. © Щерба Л. В., 1957
при сбоях форума см.блог
Спасибо сказали:
Аватара пользователя
kasak
Сообщения: 893
ОС: OpenBSD
Контактная информация:

Re: Почтовый сервер на sendmail + dovecot

Сообщение kasak »

обновил конец, кое-что усовершенствовал.
Linux kasakoff 5.10.7-200.fc33.x86_64 #1 SMP Tue Jan 12 20:20:11 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
Спасибо сказали:
AndyIP
Сообщения: 1
ОС: Gentoo

Re: Почтовый сервер на sendmail + dovecot

Сообщение AndyIP »

sash-kan писал(а):
10.08.2010 23:27
kasak писал(а):
10.08.2010 23:14
что-то я коментов не вижу
вероятно, sendmail мало кого интересует.



Здравствуйте!
Отличный пост! Вот только бы довести его до ума :) Ну типа с генерациями ключиков и т.д... :)
Спасибо сказали:
Ответить