
Сегодня рассмотрим как сделать небольшой локальный почтовый сервер для отправки оповещений по электронной почте. Отправку будем осуществлять с хоста VPS и соответственно нам понадобится, DKIM/SPF/DMARK и т.п. Внешнего доступа и авторизации не будет, так как этот почтовый сервис требуется исключительно для отправки оповещений с сайта, систем мониторинга и т.п.
Установка необходимых пакетов
Установку буду производить на Ubuntu Server 22.04, а если точнее то:
# lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 22.04.5 LTS
Release: 22.04
Codename: jammy
Для работы нам понадобится несколько пакетов.
# apt-get install opendkim opendkim-tools postfix mailutils
Базовая настройка почтового сервера
В Ubuntu имеется прекрасный мастер базовой настройки который позволяет создать простейшую конфигурацию почтового сервера для локального использования.

Если пройтись мастером и оставить все параметры по умолчанию, то мы получим конфигурационный файл вот такого содержания.
# See /usr/share/postfix/main.cf.dist for a commented, more complete version
# Debian specific: Specifying a file name will cause the first
# line of that file to be used as the name. The Debian default
# is /etc/mailname.
#myorigin = /etc/mailname
smtpd_banner = $myhostname ESMTP $mail_name (Ubuntu)
biff = no
# appending .domain is the MUA's job.
append_dot_mydomain = no
# Uncomment the next line to generate "delayed mail" warnings
#delay_warning_time = 4h
readme_directory = no
# See http://www.postfix.org/COMPATIBILITY_README.html -- default to 3.6 on
# fresh installs.
compatibility_level = 3.6
# TLS parameters
smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
smtpd_tls_security_level=may
smtp_tls_CApath=/etc/ssl/certs
smtp_tls_security_level=may
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination
myhostname = localhost
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
mydestination = $myhostname, localhost, localhost.localdomain, localhost
relayhost =
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = loopback-only
default_transport = error
relay_transport = error
inet_protocols = all
Естественно, что этому конфигурационному файлу требуется основательная доработка чем сейчас и займемся. Если сейчас попробовать просто как говорится в лоб отправить письмо:
# echo "Test mail" | mail chernousov@anton-c.ru
То естественно получим письмо и соответствующую запись в логе, о невозможности доставки.
Apr 4 01:33:03 localhost postfix/qmgr[1784]: AF82E41193: from=<root@localhost>, size=304, nrcpt=1 (queue active)
Apr 4 01:33:03 localhost postfix/error[2565]: AF82E41193: to=<chernousov@anton-c.ru>, relay=none, delay=0.04, delays=0.02/0.01/0/0.01, dsn=5.0.0, status=bounced (anton-c.ru)
Apr 4 01:33:03 localhost postfix/cleanup[2563]: B67CB41194: message-id=<20250404013303.B67CB41194@localhost>
Apr 4 01:33:03 localhost postfix/qmgr[1784]: B67CB41194: from=<>, size=2069, nrcpt=1 (queue active)
Apr 4 01:33:03 localhost postfix/bounce[2566]: AF82E41193: sender non-delivery notification: B67CB41194
Apr 4 01:33:03 localhost postfix/qmgr[1784]: AF82E41193: removed
Apr 4 01:33:03 localhost postfix/local[2567]: B67CB41194: to=<root@localhost>, relay=local, delay=0.02, delays=0/0.01/0/0.01, dsn=2.0.0, status=sent (delivered to mailbox)
Apr 4 01:33:03 localhost postfix/qmgr[1784]: B67CB41194: removed
Первое на что обращаем внимание, это адрес отправителя root@localhost и хотелось бы конечно получить там что-то более осмысленное и для этого создадим файл /etc/mailutils.conf следующего содержания.
address {
email-domain somedomain.com;
};
Немного причешем конфигурацию.
myorigin = no-reply.interlan.xyz
smtpd_banner = $myhostname ESMTP $mail_name (Ubuntu)
biff = no
append_dot_mydomain = no
readme_directory = no
compatibility_level = 2
smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination
myhostname = no-reply.interlan.xyz
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
mydestination = $myhostname, localhost, localhost.localdomain, localhost
relayhost =
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = loopback-only
default_transport = smtp
relay_transport = smtp
inet_protocols = all
Теперь моя почта попадает в спам, так как у меня нет DNS-записей для этого суб-домена и нам первым делом требуется MX/SPF и DMARK записи. В моем случае получается такая картина.
Настройка MX, DMARK и SPF записей DNS
Создаем первую DNS-запись типа А:
mail.interlan.xyz A 192.144.15.39

Создаем запись типа MX:
no-reply.interlan.xyz MX 10 mail.interlan.xyz

Аналогично создаем SPF и DMARK записи:
no-reply TXT v=spf1 +a +mx -all
_dmarc.no-reply TXT v=DMARC1; p=reject; sp=reject; ruf=mailto:chernousov@interlan.xyz; fo=1
Настройка DKIM подписей для исходящих писем
На эту тему я уже писал статью, но как говорится повторение мать учения.
# mkdir /etc/opendkim
# opendkim-genkey -D /etc/opendkim/ -b 512 --domain no-reply.interlan.xyz --selector dkim-interlan
# chown opendkim:opendkim /etc/opendkim/*
Прописываем в DNS сгенерированный открытый ключ.
# cat /etc/opendkim/dkim-interlan.txt
Проверяем.
# dig TXT dkim-interlan._domainkey.no-reply.interlan.xyz @8.8.8.8
Настраиваем конфигурационные файлы.
/etc/opendkim.conf
Syslog yes
UMask 007
Socket inet:10021@localhost
PidFile /var/run/opendkim/opendkim.pid
OversignHeaders From
TrustAnchorFile /usr/share/dns/root.key
UserID opendkim
Mode sv
SyslogSuccess yes
LogWhy yes
SendReports yes
ReportAddress "Domain DKIM Admin" <chernousov@interlan.xyz>
SoftwareHeader yes
Canonicalization relaxed/simple
Domain interlan.xyz
Selector default
MinimumKeyBits 512
KeyTable /etc/opendkim/KeyTable
SigningTable refile:/etc/opendkim/SigningTable
ExternalIgnoreList refile:/etc/opendkim/TrustedHosts
InternalHosts refile:/etc/opendkim/TrustedHosts
/etc/opendkim/KeyTable
dkim-interlan._domainkey.no-replay.interlan.xyz no-reply.interlan.xyz:dkim-interlan:/etc/opendkim/dkim-interlan.private
/etc/opendkim/SigningTable
*@no-reply.interlan.xyz dkim-interlan._domainkey.no-reply.interlan.xyz
/etc/opendkim/TrustedHosts
127.0.0.1
localhost
*.no-reply.interlan.xyz
Добавляем пользователя opendkim в группу postfix
# usermod -a -G opendkim postfix
Перезапускаем сервисы, активируем и проверяем статус
# systemctl restart opendkim
# systemctl restart postfix
# systemctl enable opendkim
# systemctl enable postfix
# systemctl status opendkim
В Postfix добавляем работу с opendkim
milter_default_action = accept
milter_protocol = 2
smtpd_milters = inet:localhost:10021
non_smtpd_milters = inet:localhost:10021
Проверяем корректность работы
Воспользуемся сервисом https://www.mail-tester.com/
Отправим тестовое письмо из консоли и проверим статус.
# echo "Test" | mail test-tyhmai8kv@srv1.mail-tester.com