Postfix — самый широко используемый Mail Transfer Agent (MTA) для Linux, обеспечивающий безопасную и надёжную доставку исходящей электронной почты. Хотя полноценный email-хостинг — задача сложная, настройка Postfix для отправки писем приложениями является распространённой и важной практикой. В этом руководстве рассматривается конфигурация Postfix для использования в production с точки зрения senior-разработчика.
Почему Postfix
Postfix предлагает существенные преимущества:
- Безопасность: спроектирован с приоритетом на безопасность
- Производительность: эффективно обрабатывает большие объёмы писем
- Модульность: легко интегрируется со спам-фильтрами и аутентификацией
- Надёжность: десятилетиями проверен в production
- Хорошая документация: обширная документация и поддержка сообщества
Установка
CentOS/RHEL
sudo dnf install postfix
sudo systemctl start postfix
sudo systemctl enable postfix
Ubuntu/Debian
sudo apt install postfix
# Во время настройки выберите «Internet Site»
# При появлении запроса введите имя вашего домена
Проверка установки
# Проверить статус
sudo systemctl status postfix
# Проверить, слушает ли порт
sudo netstat -tlnp | grep :25
# Отправить тестовое письмо
echo "Test email body" | mail -s "Test Subject" [email protected]
Базовая конфигурация
Основной файл конфигурации
/etc/postfix/main.cf:
# Базовые настройки
myhostname = mail.example.com
mydomain = example.com
myorigin = $mydomain
# Сетевые настройки
inet_interfaces = all
inet_protocols = ipv4
# Доверенные сети (только localhost для отправляющего сервера)
mynetworks = 127.0.0.0/8
# Домены назначения
mydestination = $myhostname, localhost.$mydomain, localhost
# Настройки relay (пусто = без relay)
relayhost =
# Настройки почтовых ящиков
home_mailbox = Maildir/
# Ограничения по размеру
message_size_limit = 10485760 # 10 MB
mailbox_size_limit = 0 # Без ограничений
# Настройки SMTP
smtpd_banner = $myhostname ESMTP
biff = no
append_dot_mydomain = no
Применить изменения
# Проверить синтаксис конфигурации
sudo postfix check
# Перезагрузить конфигурацию
sudo postfix reload
# Или полностью перезапустить
sudo systemctl restart postfix
TLS/SSL-шифрование
Сгенерировать сертификаты
С использованием Let's Encrypt (рекомендуется):
sudo certbot certonly --standalone -d mail.example.com
Или самоподписанный — для внутреннего использования:
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout /etc/postfix/ssl/mail.key \
-out /etc/postfix/ssl/mail.crt \
-subj "/CN=mail.example.com"
Настроить TLS
Добавьте в /etc/postfix/main.cf:
# Настройки TLS
smtpd_tls_cert_file = /etc/letsencrypt/live/mail.example.com/fullchain.pem
smtpd_tls_key_file = /etc/letsencrypt/live/mail.example.com/privkey.pem
smtpd_tls_security_level = may
smtpd_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
# Исходящий TLS
smtp_tls_security_level = may
smtp_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
smtp_tls_loglevel = 1
SMTP-аутентификация
Установить SASL
# CentOS/RHEL
sudo dnf install cyrus-sasl cyrus-sasl-plain
# Ubuntu/Debian
sudo apt install libsasl2-modules sasl2-bin
Настроить SASL
Создайте /etc/postfix/sasl/smtpd.conf:
pwcheck_method: saslauthd
mech_list: PLAIN LOGIN
Добавьте в /etc/postfix/main.cf:
# Аутентификация SASL
smtpd_sasl_auth_enable = yes
smtpd_sasl_security_options = noanonymous
smtpd_sasl_local_domain = $myhostname
smtpd_recipient_restrictions =
permit_sasl_authenticated,
permit_mynetworks,
reject_unauth_destination
Релей через внешний SMTP
Для лучшей доставляемости используйте релей через доверенного провайдера (SendGrid, Mailgun, AWS SES):
Пример SendGrid
Добавьте в /etc/postfix/main.cf:
relayhost = [smtp.sendgrid.net]:587
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_sasl_security_options = noanonymous
smtp_tls_security_level = encrypt
Создайте /etc/postfix/sasl_passwd:
[smtp.sendgrid.net]:587 apikey:your-sendgrid-api-key
Защитите и создайте хэш:
sudo chmod 600 /etc/postfix/sasl_passwd
sudo postmap /etc/postfix/sasl_passwd
sudo systemctl restart postfix
Пример AWS SES
relayhost = [email-smtp.us-east-1.amazonaws.com]:587
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_sasl_security_options = noanonymous
smtp_tls_security_level = encrypt
smtp_tls_CAfile = /etc/ssl/certs/ca-bundle.crt
SPF, DKIM и DMARC
Критически важно для доставляемости:
SPF-запись
Добавьте DNS TXT-запись:
example.com. TXT "v=spf1 mx ip4:YOUR_SERVER_IP include:_spf.google.com ~all"
DKIM с OpenDKIM
# Установка
sudo dnf install opendkim opendkim-tools
# Сгенерировать ключи
sudo opendkim-genkey -D /etc/opendkim/keys/example.com/ -d example.com -s mail
# Настроить /etc/opendkim.conf
Domain example.com
Selector mail
KeyFile /etc/opendkim/keys/example.com/mail.private
Socket inet:8891@localhost
# Добавить в main.cf
milter_protocol = 6
milter_default_action = accept
smtpd_milters = inet:localhost:8891
non_smtpd_milters = inet:localhost:8891
Добавьте DNS TXT-запись:
mail._domainkey.example.com. TXT "v=DKIM1; k=rsa; p=<public-key-from-mail.txt>"
DMARC-запись
Добавьте DNS TXT-запись:
_dmarc.example.com. TXT "v=DMARC1; p=quarantine; rua=mailto:[email protected]"
Интеграция с Docker
Использовать host Postfix из контейнера
В docker-compose.yml:
services:
app:
image: your-app
extra_hosts:
- "host.docker.internal:host-gateway"
environment:
MAIL_HOST: host.docker.internal
MAIL_PORT: 25
Контейнер Postfix
services:
postfix:
image: boky/postfix
environment:
ALLOWED_SENDER_DOMAINS: example.com
RELAYHOST: "[smtp.sendgrid.net]:587"
RELAYHOST_USERNAME: apikey
RELAYHOST_PASSWORD: your-api-key
ports:
- "1025:587"
Интеграция с приложением
PHP (Laravel)
.env:
MAIL_MAILER=smtp
MAIL_HOST=localhost
MAIL_PORT=25
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
[email protected]
MAIL_FROM_NAME="${APP_NAME}"
Node.js (Nodemailer)
const nodemailer = require('nodemailer');
const transporter = nodemailer.createTransport({
host: 'localhost',
port: 25,
secure: false,
tls: {
rejectUnauthorized: false
}
});
async function sendEmail(to, subject, html) {
return transporter.sendMail({
from: '[email protected]',
to,
subject,
html
});
}
Python
import smtplib
from email.mime.text import MIMEText
def send_email(to, subject, body):
msg = MIMEText(body)
msg['Subject'] = subject
msg['From'] = '[email protected]'
msg['To'] = to
with smtplib.SMTP('localhost', 25) as server:
server.send_message(msg)
Мониторинг и логи
Просмотр очереди почты
# Показать очередь
sudo postqueue -p
# Сбросить очередь (повторить все попытки)
sudo postqueue -f
# Удалить всю почту из очереди
sudo postsuper -d ALL
Просмотр логов
# CentOS/RHEL
sudo tail -f /var/log/maillog
# Ubuntu/Debian
sudo tail -f /var/log/mail.log
# Отфильтровать ошибки
sudo grep -i error /var/log/maillog
Устранение неполадок
Ошибка lock-файла
fatal: open lock file /var/lib/postfix/master.lock: unable to set exclusive lock
Решение:
sudo fuser /var/lib/postfix/master.lock
sudo kill <process_id>
sudo systemctl start postfix
Тест доставки почты
# Ручной тест SMTP
telnet localhost 25
EHLO localhost
MAIL FROM:<[email protected]>
RCPT TO:<[email protected]>
DATA
Subject: Test
Test message
.
QUIT
Проверка заголовков письма
Используйте mail-tester.com для проверки SPF, DKIM и оценки доставляемости.
Ключевые выводы
- Начните с простого: базового Postfix достаточно для отправки писем приложением
- Используйте релей: SendGrid/SES для доставляемости в production
- TLS везде: шифруйте все соединения
- SPF/DKIM/DMARC: необходимы для попадания во «Входящие»
- Мониторьте очереди: регулярно проверяйте логи
- Тщательно тестируйте: используйте mail-tester.com перед запуском
Postfix надёжно обеспечивает доставку почты — в production-приложениях, где требуется гарантированная доставка, сочетайте его с авторитетным relay-сервисом.