Ё-маё, нащёл свой же вопрос в гугле спустя более 3-ёх лет. :-)
Сейчас мне очень стыдно. :-(1 587-ой порт только может отправлять почту. Для получения почты нужен обязательно 25-ый порт, который тоже вполне может отправлять с TLS.
2 TLS через telnet не проверяют, для этого используют:
openssl s_client -starttls smtp -connect localhost:587
А на некоторых серверах может ещё понадобиться указать путь к корневым сертификатам.
openssl s_client -starttls smtp -CApath /etc/ssl/certs -connect localhost:587
А ещё одна забавная вещь, что "RCPT TO:", вопреки спекам, в s_client-e нельзя отправлять заглавными буквами, иначе отправитель будет отвергнут с непонятным выводом ssl.3 Перезаписывать опции в master.cf под
submission inet n - n - - smtpd -v
НЕ НУЖНО, а вместо этого эти параметры нужно указать в main.cf
При этом smtp_tls_security_level = encrypt и smtpd_tls_security_level = encrypt для клиента (sendmail, php mail()) и сервера (telnet, s_client) соответственно, означает что сервер будет принимать и отправлять почту только тем почтовым серверам, которые имеют создавать шифрованный канал связи (STARTLS), в противном случае почта отвергается или не отправляется. Если такое поведение не устраивает, то нужно использовать уровень may.4
smtpd_recipient_restrictions=reject_non_fqdn_recipient,reject_unknown_recipient_domain,permit_sasl_authenticated,reject
Тут я не понимал правила проверки параметров и как они работают.
Эти правила для этапа назначения получателя ВСЕГДА будут отклонять входящую почту и исходящую без аутентификации, включая telnet и s_client, так как в конце тупо стоит reject вместо reject_unauth_destination.
И вообще, нельзя тупо писать permit или reject, за исключением в smtpd_etrn_restrictions, так как это сразу прекращает ВСЕ этапы проверки, которые следуют после проверки отправителя.
Пожалуй, тут лучше приведу корректные ограничения.
inet_interfaces = $myhostname, localhost
strict_rfc821_envelopes = yes
smtpd_helo_required = yes
smtpd_recipient_restrictions = reject_invalid_helo_hostname, reject_non_fqdn_helo_hostname, reject_non_fqdn_sender, reject_non_fqdn_recipient, reject_unknown_sender_domain, reject_unknown_recipient_domain, reject_unknown_helo_hostname, reject_unknown_client_hostname, reject_rbl_client zen.spamhaus.org
smtpd_relay_restrictions = permit_inet_interfaces, permit_sasl_authenticated, reject_unauth_destination
smtpd_data_restrictions = reject_unauth_pipelining, reject_multi_recipient_bounce
smtpd_etrn_restrictions = reject
5 Сертификат нужно готовить как для nginx, помещая в конец открытого ключа (сертификата), сертификаты всех промежуточных узлов (intermadiate), и получившийся файл подключать как сертификат, не забывая подключить и закрытый ключ. Такой формат сертификата понимают все популярные сервера, и nginx, и postfix, и dovecot, и даже apache, ему тогда не нужно intermediate через keychain подключать отдельным файлом.
Так что рекомендую изначально правильно приготовить сертификат, а потом подключать его куда угодно.
А также не забывайте указывать путь к хранилищам корневых сертификатов smtp_tls_CAfile smtp_tls_CApath и smtpd_tls_CAfile smtpd_tls_CApath для клиента (sendmail, php mail()) и сервера (telnet, s_client) соответственно.
У меня в openSUSE для предполагаемого домена stf.pp.ua это выглядит так:
smtp_tls_CAfile = /etc/ssl/ca-bundle.pem
smtp_tls_CApath = /etc/ssl/certs
smtp_tls_cert_file = /etc/apache2/ssl.crt/stf.pp.ua.crt
smtp_tls_key_file = /etc/apache2/ssl.key/stf.pp.ua.keysmtpd_tls_CAfile = /etc/ssl/ca-bundle.pem
smtpd_tls_CApath = /etc/ssl/certs
smtpd_tls_cert_file = /etc/apache2/ssl.crt/stf.pp.ua.crt
smtpd_tls_key_file = /etc/apache2/ssl.key/stf.pp.ua.key
А также не забывайте и про dovecot, и обратите особое внимание на различия указания файлов сертификатов от файла и директории корневого хранилища, заключающиеся в наличии и отсутствии левой угловой скобки перед путём.
ssl_ca = </etc/apache2/ssl.crt/ilya.pp.ua.crt
ssl_cert = </etc/apache2/ssl.crt/ilya.pp.ua.crt
ssl_client_ca_dir = /etc/ssl/certs
ssl_client_ca_file = /etc/ssl/ca-bundle.pem
6 Для успешной отправки почты имя почтового сервера (myhostname) должен ссылаться на правильный, существующий домен, IP которого ссылается на IP этого сервера, а обратная зона, или PTR-запись, ссылается на этот домен. Установкой обратной зоны для вашего IP занимается ваш интернет-провайдер или хостер.
Если раньше это нужно было делать, чтобы письма не попадали в спам, то теперь не один современный почтовый сервер просто не примет почту от вас.
7 И после этого всего IP вашего сервера не должен содержаться в популярных spam/pbl - базах, проверить можно тут. https://2ip.ru/spam/?ip=
Удаление из каждого списка каждой базы это отдельный вопрос, но для этого у вас должен быть уже настроенный сервер с шифрованием способный как отправлять так и принимать почту.
Вот это самые распространённые ошибки новичков и трудности, встречаемые при настройке postfix + dovecot.
Ну и, чтобы кому-то было ещё больше "букав", а кому-то боле понятнее остольное, о чём я не сказал, приведу сокращённые примеры конфигурации виртуального сервера postfix/dovecot на passwd-file (БЕЗ SQL), вырезав некоторые специфичные для ОС параметры или не влияющие на основную работу сервера.
1 Логи systemd/rsyslog.
Даже если вы не хотите использовать systemd-journald, то вам всё равно придётся.
В моём случае я не создавал для него хранилища, предлагая ему хранить логи в оперативной памяти, максимум 4М, и перенаправлять их в rsyslog. В противном случае логов от postfix вы не увидите, если у вас напрочь отключен systemd-journald, так как по дефолту во многих ОС postfix направляет свои логи туда и перенаправить их на rsyslog или отдельный файл через конфиг нельзя. :-(
/etc/systemd/journald.conf
[Journal]
Storage=none
Compress=yes
SystemMaxUse=4M
SystemMaxFileSize=4M
RuntimeMaxUse=4M
RuntimeMaxFileSize=4M
ForwardToSyslog=yes
А также нужно убедится в наличии перенаправления логов почты из rsyslog в /var/log/mail*
/etc/rsyslog.conf
#
# email-messages
#
mail.* -/var/log/mail.log
mail.warning -/var/log/mail.warn
mail.err /var/log/mail.err
После перезагрузки systemd-journald и rsyslog логи будут появляться.
Также имейте ввиду, если вы используете только systemd-journald по умолчанию и вас всё устраивает, то вам, скорее всего, делать ничего из этого не нужно.2 Указание серверу имени хоста
Что бы не указывать вручную опцию myhostname, которое должно или совпадать с именем хоста, или быть его поддоменом, можно поручить postfix-у автоматически определить имя хоста (по умолчанию, если не указывать опцию myhostname).
Раньше это можно было сделать просто так
echo stf.pp.ua > /etc/HOSTNAME
Но с приходом Дяди Лёни этого уже не достаточно, так как оно с stf.pp.ua обрежется до stf.
Теперь ещё нужно в /etc/sysctl.conf добавить опцию kernel.hostname = stf.pp.ua
Только после этого postfix, как и любой другой сервер или приложение, будет правильно определять имя хоста.3 Системный пользователь vmail
Создаём, если он не был создан ранее, системного пользователя и группу vmail с uid и gid 303 и домашним каталогом /srv/vmail.
В дальнейшем от выбора имени (vmail), uid/gid (303) и домашнего каталога (/srv/vmail) будут зависеть другие параметры в конфигах и если вы хотите использовать иные параметры, то указывайте в дальнейшем их, там, где я указываю эти.
sudo groupadd -rg 303 vmail && sudo useradd -rc 'Виртуальная почта' -u 303 -g vmail -d /srv/vmail vmail
4 Виртуальные пользователи
Имена и пароли (ssha512) пользователей будем хранить в /etc/dovecot/users и добавлять командой от рута
echo info@stf.pp.ua:$(doveadm pw -s ssha512 -p Go6xDOhDCOhta6H6):::::: >> /etc/dovecot/users
где info@stf.pp.ua - полное имя пользователя (обязательно с доменом)
Go6xDOhDCOhta6H6 - пароль пользователя генерированный командой pwgen -s 16
>> /etc/dovecot/users - добавить запись в конец указанного файла.5 Виртуальные домены
ВСЕ виртуальные домены, обслуживаемые нашим сервером, должны быть указаны в опции virtual_mailbox_domains, и НЕ должны входить в опции mydestination и virtual_alias_domains
Опция virtual_alias_domains служат только для указания виртуальных псевдонимов, то есть доменов, которые обслуживает сервер, но в них нет пользователей из /etc/dovecot/users а только одни псевдонимы, которые ссылаются на домены других виртуальных пользователей которые есть в /etc/dovecot/users
myhostname = stf.pp.ua
mydomain = $myhostname
inet_interfaces = $myhostname, localhost
mydestination = localhost.$mydomain, localhostvirtual_alias_maps = hash:/etc/postfix/virtual
virtual_alias_domains =
virtual_mailbox_domains = $myhostname subdom.$myhostname other.domain.ua
alias_maps = hash:/etc/postfix/aliases
local_recipient_maps = $alias_maps
6 Виртуальные псевдонимы.
Это адреса на которые должна приходить почта, но не на свой ящик из /etc/dovecot/users, а перенаправляться любому другому виртуальному пользователю, указывается в файле /etc/postfix/virtual, который указывается в параметре virtual_alias_maps.
Например по спецификации, почта на postmaster и abuse должна приходить в любом домене.
# stf.pp.ua
postmaster@stf.pp.ua info@stf.pp.ua
abuse@stf.pp.ua info@stf.pp.ua# subdom.stf.pp.ua
postmaster@subdom.stf.pp.ua info@stf.pp.ua
abuse@subdom.stf.pp.ua info@stf.pp.ua
После изменения этого файла нужно проиндексировать базу и перезагрузить конфиг postfix-а.
sudo postmap hash:/etc/postfix/virtual && sudo systemctl reload postfix
7 Реальные псевдонимы.
Хотя в этой конфигурации обслуживаются только виртуальные пользователи и предыдущего шага будет вполне достаточно, но, на всякий случай, укажем псевдонимы и для реальных пользователей, указывается в файле /etc/postfix/aliases, который указывается в параметре alias_maps. Всё что нужно это в самом начале файла после root: указать имя локального пользователя ОС кому будет перенаправлятся вся служебная почта.
/etc/postfix/aliases
# Person who should get root's mail. Don't receive mail as root!
root: user
После изменения этого файла нужно проиндексировать базу и перезагрузить конфиг postfix-а.
sudo postalias hash:/etc/postfix/aliases && sudo systemctl reload postfix
8 Конфигурационные файлы postfix и dovecot
Ну и теперь осталось упомянуть о настройках транспорта, ограничений, привелегий и прочего, в чём проблем у меня никогда не возникало, по этому упоминать про это я не буду, а просто приведу урезанные конфиги.
postconf -p
alias_maps = hash:/etc/postfix/aliases
biff = no
compatibility_level = 2
disable_vrfy_command = yes
inet_interfaces = $myhostname, localhost
local_recipient_maps = $alias_maps
mydestination = localhost.$mydomain, localhost
mydomain = $myhostname
smtp_enforce_tls = yes
smtp_helo_timeout = 10s
smtp_rcpt_timeout = 10s
smtp_tls_CAfile = /etc/ssl/ca-bundle.pem
smtp_tls_CApath = /etc/ssl/certs
smtp_tls_cert_file = /etc/apache2/ssl.crt/stf.pp.ua.crt
smtp_tls_key_file = /etc/apache2/ssl.key/stf.pp.ua.key
smtp_tls_security_level = encrypt
smtp_tls_session_cache_database = btree:/var/lib/postfix/smtp_scache
smtp_tls_session_cache_timeout = 1d
smtp_use_tls = yes
smtpd_banner = $myhostname ESMTP $mail_name ($mail_version)
smtpd_data_restrictions = reject_unauth_pipelining, reject_multi_recipient_bounce
smtpd_enforce_tls = yes
smtpd_etrn_restrictions = reject
smtpd_helo_required = yes
smtpd_recipient_limit = 25
smtpd_recipient_restrictions = reject_invalid_helo_hostname, reject_non_fqdn_helo_hostname, reject_non_fqdn_sender, reject_non_fqdn_recipient, reject_unknown_sender_domain, reject_unknown_recipient_domain, reject_unknown_helo_hostname, reject_unknown_client_hostname, reject_rbl_client zen.spamhaus.org
smtpd_reject_unlisted_recipient = yes
smtpd_reject_unlisted_sender = yes
smtpd_relay_restrictions = permit_inet_interfaces, permit_sasl_authenticated, reject_unauth_destination
smtpd_sasl_auth_enable = yes
smtpd_sasl_local_domain = $myhostname
smtpd_sasl_path = private/auth
smtpd_sasl_type = dovecot
smtpd_tls_CAfile = /etc/ssl/ca-bundle.pem
smtpd_tls_CApath = /etc/ssl/certs
smtpd_tls_auth_only = yes
smtpd_tls_cert_file = /etc/apache2/ssl.crt/stf.pp.ua.crt
smtpd_tls_key_file = /etc/apache2/ssl.key/stf.pp.ua.key
smtpd_tls_received_header = yes
smtpd_tls_security_level = encrypt
smtpd_tls_session_cache_database = btree:/var/lib/postfix/smtpd_scache
smtpd_tls_session_cache_timeout = 1d
smtpd_use_tls = yes
stress = yes
strict_rfc821_envelopes = yes
virtual_alias_maps = hash:/etc/postfix/virtual
virtual_gid_maps = static:303
virtual_mailbox_base = /srv/vmail
virtual_mailbox_domains = $myhostname subdom.$myhostname
virtual_mailbox_lock = fcntl
virtual_minimum_uid = 303
virtual_transport = lmtp:unix:private/dovecot-lmtp
virtual_uid_maps = static:303
/etc/postfix/master.cf
#
# ==========================================================================
# service type private unpriv chroot wakeup maxproc command + args
# (yes) (yes) (no) (never) (100)
# ==========================================================================
25 inet n - n - - smtpd
587 inet n - n - - smtpd
pickup unix n - n 60 1 pickup
cleanup unix n - n - 0 cleanup
qmgr unix n - n 300 1 qmgr
tlsmgr unix - - n 1000? 1 tlsmgr
rewrite unix - - n - - trivial-rewrite
bounce unix - - n - 0 bounce
defer unix - - n - 0 bounce
trace unix - - n - 0 bounce
verify unix - - n - 1 verify
flush unix n - n 1000? 0 flush
proxymap unix - - n - - proxymap
proxywrite unix - - n - 1 proxymap
smtp unix - - n - - smtp
relay unix - - n - - smtp
showq unix n - n - - showq
error unix - - n - - error
retry unix - - n - - error
discard unix - - n - - discard
local unix - n n - - local
virtual unix - n n - - virtual
lmtp unix - - n - - lmtp
anvil unix - - n - 1 anvil
scache unix - - n - 1 scache receive_override_options=no_unknown_recipient_checks,no_header_body_checks,no_address_mappings
dovecot unix - n n - - pipe
flags=DRhu user=vmail:vmail argv=/usr/lib/dovecot/deliver -d ${recipient}
doveconf -nP
auth_cache_negative_ttl = 1 days
auth_cache_ttl = 1 days
first_valid_gid = 303
first_valid_uid = 303
last_valid_gid = 303
last_valid_uid = 303
mail_gid = vmail
mail_home = /srv/vmail/%d/%n
mail_location = maildir:~/Maildir
mail_uid = vmail
mbox_write_locks = fcntl
passdb {
args = scheme=ssha512 username_format=%u /etc/dovecot/users
driver = passwd-file
}
service auth {
unix_listener /var/spool/postfix/private/auth {
group = postfix
mode = 0660
user = postfix
}
unix_listener auth-userdb {
mode = 0600
user = vmail
}
}
service imap-login {
inet_listener imaps {
port = 993
ssl = yes
}
}
service lmtp {
unix_listener /var/spool/postfix/private/dovecot-lmtp {
mode = 0600
user = postfix
}
user = vmail
}
service pop3-login {
inet_listener pop3s {
port = 995
ssl = yes
}
}
ssl = required
ssl_ca = </etc/apache2/ssl.crt/stf.pp.ua.crt
ssl_cert = </etc/apache2/ssl.crt/stf.pp.ua.crt
ssl_cipher_list = ALL:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!PSK:!RC4:!ADH:!LOW@STRENGTH
ssl_client_ca_dir = /etc/ssl/certs
ssl_client_ca_file = /etc/ssl/ca-bundle.pem
ssl_dh_parameters_length = 2048
ssl_key = </etc/apache2/ssl.key/stf.pp.ua.key
ssl_options = no_compression
ssl_prefer_server_ciphers = yes
ssl_protocols = !SSLv2 !SSLv3
ssl_verify_client_cert = yes
userdb {
args = username_format=%u /etc/dovecot/users
driver = passwd-file
}
protocol lmtp {
postmaster_address = info@stf.pp.ua
}