Linux

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_senders

5. Подключите 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-pager

8. Тест: разрешённый 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-фильтром.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *