Postfix: защита от поддельного From — sender login, SPF, DKIM и DMARC
Поддельный From: и подмена SMTP envelope sender — разные вещи. Поэтому защита Postfix должна состоять из двух частей: контролировать, от каких адресов разрешено отправлять авторизованным пользователям, и отдельно проверять входящую почту через SPF/DKIM/DMARC. Ниже — рабочая конфигурация и команды проверки.
1. Сначала сохраните текущую конфигурацию
postconf -n > /root/postfix-before-sender-policy.txt
postconf -M > /root/postfix-master-before.txt
cp -a /etc/postfix /root/postfix-backup-$(date +%F)2. Проверьте, что SMTP AUTH действительно включён
postconf smtpd_sasl_auth_enable smtpd_sasl_type smtpd_sasl_path
postconf -M | grep -E '^(submission|submissions|smtps)/'Ограничение sender/login имеет смысл прежде всего на submission-порту, где клиент уже аутентифицирован.
3. Создайте карту разрешённых отправителей
Сначала посмотрите, какие типы lookup-таблиц поддерживает ваш Postfix:
postconf -m
postconf default_database_typeПример файла /etc/postfix/controlled_envelope_senders:
user@example.com user@example.com
helpdesk@example.com user@example.com,admin@example.com
billing@example.com billing@example.com
@example.net admin@example.comЛевая колонка — envelope sender из команды SMTP MAIL FROM, правая — SASL login, которым разрешено использовать этот адрес.
4. Соберите lookup-таблицу
Если используется тип по умолчанию:
postmap /etc/postfix/controlled_envelope_sendersЕсли явно используете LMDB:
postmap lmdb:/etc/postfix/controlled_envelope_sendersПроверьте lookup до перезагрузки Postfix:
postmap -q user@example.com /etc/postfix/controlled_envelope_senders
postmap -q helpdesk@example.com /etc/postfix/controlled_envelope_senders5. Подключите smtpd_sender_login_maps
В /etc/postfix/main.cf добавьте карту того типа, который реально поддерживает ваша система. Например:
smtpd_sender_login_maps = lmdb:/etc/postfix/controlled_envelope_senders
smtpd_sender_restrictions = reject_authenticated_sender_login_mismatch, reject_unknown_sender_domainЕсли у вас уже есть smtpd_sender_restrictions, не заменяйте список целиком — аккуратно встроите новую проверку с учётом порядка правил.
6. Более безопасный вариант — применять правило только к submission
Чтобы не ломать входящую почту на 25 порту, ограничение sender/login удобно задавать именно сервису submission в master.cf. Пример фрагмента:
submission inet n - y - - smtpd
-o syslog_name=postfix/submission
-o smtpd_tls_security_level=encrypt
-o smtpd_sasl_auth_enable=yes
-o smtpd_sender_login_maps=lmdb:/etc/postfix/controlled_envelope_senders
-o smtpd_sender_restrictions=reject_authenticated_sender_login_mismatch
-o smtpd_relay_restrictions=permit_sasl_authenticated,rejectСохраните только те параметры, которые соответствуют вашей существующей submission-конфигурации. Не копируйте этот блок поверх уже настроенного master.cf.
7. Проверяем конфигурацию и reload
postfix check
postconf -n | grep -E 'sender_login|sender_restrictions'
postconf -M | grep -E '^(submission|submissions|smtps)/'
postfix reload
journalctl -u postfix -n 100 --no-pager8. Тест: разрешённый From
С отдельной тестовой машины отправьте письмо через 587 с учёткой user@example.com и разрешённым envelope sender:
swaks --server mail.example.com --port 587 --tls \
--auth LOGIN --auth-user user@example.com --auth-password 'TEST_PASSWORD' \
--from user@example.com --to test-recipient@example.netНе используйте рабочий пароль в shell history на общем сервере: для теста лучше временная учётка или интерактивный способ передачи секрета.
9. Тест: запрещённый From
swaks --server mail.example.com --port 587 --tls \
--auth LOGIN --auth-user user@example.com --auth-password 'TEST_PASSWORD' \
--from director@example.com --to test-recipient@example.netЕсли director@example.com не принадлежит этому SASL login, Postfix должен отклонить отправку на этапе sender restrictions.
10. Смотрим результат в логах
journalctl -u postfix --since '10 min ago' --no-pager | grep -E 'sender|SASL|reject|mismatch'11. Но это не защищает видимый заголовок From полностью
smtpd_sender_login_maps контролирует envelope sender. Видимый заголовок From: может отличаться. Для строгой проверки header From на submission нужен отдельный Milter/контент-фильтр. Для входящей почты задача обычно решается через SPF, DKIM и DMARC.
12. Проверьте SPF/DKIM/DMARC своего домена
dig +short TXT example.com
dig +short TXT selector._domainkey.example.com
dig +short TXT _dmarc.example.comЕсли DMARC ещё не настроен, начинайте с мониторинга, например p=none, соберите отчёты, найдите все легальные источники отправки и только потом переходите к quarantine/reject.
13. Как расследовать письмо «от себя к себе»
# найдите сообщение в логах по адресу/queue ID
journalctl -u postfix --since '24 hours ago' --no-pager | grep 'user@example.com'
# если письмо ещё в очереди
postcat -q QUEUE_ID- посмотрите
Received:; - проверьте
Authentication-Results:; - сравните header
From:и envelope sender; - проверьте SPF/DKIM/DMARC;
- убедитесь, что письмо не было отправлено через реально скомпрометированную SMTP-учётку.
Критерий успеха: авторизованный пользователь может отправлять только от разрешённых envelope-адресов, попытка использовать чужой sender отклоняется, а входящий spoofing собственного домена определяется SPF/DKIM/DMARC-фильтром.