Настройка postfix для отправки почты
Чтобы отправлять почту со своего сервера по smtp и исключить ограничения провайдеров почты для домена и попадание почты в спам. Для этого необходимо настроить по крайней мере запись SPF. Но лучше также настроить DKIM подпись и шифрование писем, для защиты от подмены содержимого.
PTR-запись
PTR вычисляется автоматически исходя из hostname сервера или hostname в списке /etc/hosts на хостинге.
Если указать на своем сервере в файле hosts определение IP адресов для имён, то при запросе обратной записи с этого сервера, он не обращается к ns, а сам разрешает этот запрос исходя из файлв hosts. Причем если несколько доменов соответствую одному адресу, то сервер несколько записей PTR.
на хостинге же для установки, например ruweb.net доступна одна PTR запись.
[flickr:id=52016617810]
Для установки hostname на ubuntu Прописываем в файл /etc/hostname
$ sudo nano /etc/hostname
sinyawskiy.ru
$ sudo hostnamectl set-hostname sinyawskiy.ru
Проверяем hostname
$ hostnamectl
Static hostname: sinyawskiy.ru
Icon name: computer-server
Chassis: server
Machine ID: 3224c2996d3e429baeeb9bbb12bb3fb0
Boot ID: 8ab9158c410d46b5b47d0a57c68db0e8
Operating System: Ubuntu 16.04.6 LTS
Kernel: Linux 4.4.0-146-generic
Architecture: x86-64
или просто
$ hostname
sinyawskiy.ru
hostname определяет имя компьютера внутри сети и может быть только одно. Если есть несколько записей NS, то надо прописать их в свой файл hosts
sudo nano /etc/hosts
127.0.0.1 localhost
# The following lines are desirable for IPv6 capable hosts
::1 localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
185.12.94.19 sinyawskiy.ru domain1.ru domain2.ru ...
Проверяем PTR запись
Для того, чтобы установить утилиту dig в Ubuntu sudo apt install bind9-dnsutils
$ dig -x 185.12.94.19
; <<>> DiG 9.16.1-Ubuntu <<>> -x 185.12.94.19
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 159
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 65494
;; QUESTION SECTION:
;19.94.12.185.in-addr.arpa. IN PTR
;; ANSWER SECTION:
19.94.12.185.in-addr.arpa. 571 IN PTR sinyawskiy.ru.
;; Query time: 0 msec
;; SERVER: 127.0.0.53#53(127.0.0.53)
;; WHEN: Чт апр 07 22:19:36 MSK 2022
;; MSG SIZE rcvd: 81
или
$ nslookup 185.12.94.19
19.94.12.185.in-addr.arpa name = sinyawskiy.ru.
или
$ host 185.12.94.19
19.94.12.185.in-addr.arpa domain name pointer sinyawskiy.ru.
Важно!
Как показала практика почтовые сервисы определяют соответствие hostname и IP-адреса по протоколу ICMP, то есть простым ping.
Поэтому файл host имеет большое значание. И важно чтобы первое место сразу после IP-адреса занимал ваш почтовый домен 185.12.94.19 sinyawskiy.ru domain1.ru
SPF-запись
SPF-запись, кто может посылать письма для указанного доменного имени.
Эту запись описывает стандарт RFC7208
sinyawskiy.ru. IN TXT "v=spf1 +a +mx -all"
-all
- отклоняем все если нет среди А записей и если нет среди MX записей (письмо отправленные от недоверенных хостов будут отклонены).
?all
- то на усмотрение получателя.
~all
- означает, что письма с вашего домена, должны приходить только с хостов указаных в записи SPF. Письма от других хостов будут отмечены как сомнительные (ненадёжные).
+all
- доверять всем.
- это стандартное поведение поэтому можно не указывать.
sinyawskiy.ru. IN TXT "v=spf1 a mx -all"
В стандарте указано, что хорошим тоном нужно завершать spf модификатором all или модификатором redirect.
Оставлю у себя возможность отправлять почту через яндекс(mx запись) и со своего постфикса (sinyawskiy.ru).
sinyawskiy.ru. IN TXT "v=spf1 a:sinyawskiy.ru mx redirect=_spf.yandex.net"
Теперь при отправке почты на gmail не попадает в спам. В заголовке письма, письмо прошло проверку.
ARC-Authentication-Results: i=1; mx.google.com;
spf=pass (google.com: best guess record for domain of root@sinyawskiy.ru designates 185.12.94.19 as permitted sender) smtp.mailfrom=root@sinyawskiy.ru
DMARC-запись
Запись говорит получателю, что делать если письмо не прошло проверку по SPF.
_dmarc.sinyawskiy.ru. IN TXT "v=DMARC1; p=reject;"
Теперь при отправке почты на gmail, gmail знает, что делать если письмо пришло не с этого домена.
ARC-Authentication-Results: i=1; mx.google.com;
spf=pass (google.com: domain of root@sinyawskiy.ru designates 185.12.94.19 as permitted sender) smtp.mailfrom=root@sinyawskiy.ru;
dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=sinyawskiy.ru
Создание dkim сертификатов
Создадим папку для созданных ключей.
mkdir ~/postfix_sinyawskiy_ru_keys/
cd ~/postfix_sinyawskiy_ru_keys/
Создаем приватный и публичный ключи
# openssl genrsa -out private_sinyawskiy_dkim_key.pem 1024
# openssl rsa -pubout -in private_sinyawskiy_dkim_key.pem -out public_sinyawskiy_dkim_key.pem
cat public_sinyawskiy_dkim_key.pem
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8AZO4ZkHCuX8t+UvVydEo85Gx
j3ZxSTzo6wZg8EljyI5315bAkFTh+1uQsSEmd2MIJIFmM03BzjnFmB72geEl1i+n
tzDQacC3F/ktr7rqgy/nxdWYT5XLMLUkOljJWVETg5qZeIyfSiZeW98xLmNfyyKq
wdVXBA1E6L+c+aK5sQIDAQAB
-----END PUBLIC KEY-----
Сгенерировать сертификаты подписи письма можно также при помощи opendkim-tools.
mkdir ~/opendkim_keys/
cd ~/opendkim_keys/
opendkim-genkey -t -s dkim -d sinyawskiy.ru
В папке появятся файлы. dkim.private
приватный ключ, для создания подписного заголовка и публичный ключ для создания записи в доменной зоне dkim.txt
. Более простой путь.
Запись-DKIM
Из публичного ключа надо сформировать DKIM TXT запись в DNS-зону. Важно убрать пробелы.
mail._domainkey.mydomain.ru. TXT "v=DKIM1; k=rsa; t=s; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8AZO4ZkHCuX8t+UvVydEo85Gxj3ZxSTzo6wZg8EljyI5315bAkFTh+1uQsSEmd2MIJIFmM03BzjnFmB72geEl1i+ntzDQacC3F/ktr7rqgy/nxdWYT5XLMLUkOljJWVETg5qZeIyfSiZeW98xLmNfyyKqwdVXBA1E6L+c+aK5sQIDAQAB
Редактирование DNS записи на хостинге nic.ru
[flickr:id=52015067857]
Online проверка DKIM-записи: https://www.dmarcanalyzer.com/dkim/dkim-checker/
Проверка того, что запись выгрузилась в зону.
$ dig txt default._domainkey.sinyawskiy.ru
После настройки NS записи DKIM и настройки postfix с opendkim (далее), в письме появится заголовок DKIM-Signature. А при отправке письма в gmail, сервис будет проверять эту подпись, и результат проверки появится в заголовке.
ARC-Authentication-Results: i=1; mx.google.com;
dkim=pass header.i=@sinyawskiy.ru header.s=default header.b=BRnFxMz0;
spf=pass (google.com: domain of root@sinyawskiy.ru designates 185.12.94.19 as permitted sender) smtp.mailfrom=root@sinyawskiy.ru;
dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=sinyawskiy.ru
[flickr:id=52015067852]
Установка postfix и opendkim
Установим необходимые пакеты
sudo apt-get install mailutils opendkim opendkim-tools
Настройка opendkim
Opendkim - это открытая реализация протокола dkim. Все параметры opendkim описаны в документации Чтобы opendkim работал, как промежуточный обработчик (фильтр) для postfix его надо настроить на внутренний TCP порт или UNIX сокет. Сокетные файлы создаются в postfix в специализированной директории. Настройка через TCP порт проще.
$ sudo nano /etc/default/opendkim
# комментируем сокет файл
#SOCKET="local:/var/run/opendkim/opendkim.sock"
# добавляем строку
SOCKET="inet:8891@localhost"
Теперь opendkim будет слушать на TCP localhost на порту 8891.
$ sudo nano /etc/opendkim.conf
#LogWhy yes # для более полного логирования при отладке
Syslog yes
#SyslogSuccess yes # для более полного логирования при отладке
Domain sinyawskiy.ru
KeyFile /home/als/postfix_sinyawskiy_ru_keys/private_sinyawskiy_dkim_key.pem
Selector default
RequireSafeKeys false # включится если папка хранения закрытого ключа небезопасна
# KeyTable и SigningTable используются только совместно
KeyTable refile:/etc/opendkim/KeyTable # для более полного логирования при отладке
SigningTable refile:/etc/opendkim/SigningTable # для более полного логирования при отладке
# Только при настройке relaxed/relaxed в gmail письма стали проходить проверку подписи
Canonicalization relaxed/relaxed
Mode sv
$ sudo mkdir -p /etc/opendkim
Файл мапинга доменов и внутренних имен (в opendkim)
$ sudo nano /etc/opendkim/SigningTable
Формат такой
<email_from_regexp> <internal_name>
Для моего случая
*@sinyawskiy.ru sinyawskiy
Файл маппинга внутренних имен (в opendkim) и подписей
$ sudo nano /etc/opendkim/KeyTable
Формат такой
<internal_name> <domen>:<selector>:<private_keyfile>
Для моего случая
sinyawskiy sinyawskiy.ru:default:/home/als/postfix_sinyawskiy_ru_keys/private_sinyawskiy_dkim_key.pem
Важно! Необходимо обратить внимание.
По-умолчанию в настройках opendkim.conf
включена опция OversignHeaders
.
С этой настройкой dkim подпись выглядит следующим образом:
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sinyawskiy.ru; s=default; t=1650350071; bh=aHt59uy3McEsxWhjNCVkMx16meY6Y2AtGLmw0MEYQ/o=; h=Subject:From:To:Date:From;
Порядок h=Subject:From:To:Date:From;
- OversignHeaders From
+ # OversignHeaders From
Я её выключаю потому, что с ней при отправке почты из django приложения в сервисе gmail письмо не проходит проверку. Видимо не хватает заголовка FROM.
Порядок становится таким - h=Subject:To:Date:From;
В Opendkim есть опции AutoRestart
и AutoRestartRate
AutoRestart Yes
AutoRestartRate 10/1h
Эти опции отвечают за то, что если произойдет ошибка, то сервис перезагружается. Если сервис перезагружается более чем 10 раз за 1 час, то фильтр который подписывает письма и добавляет заголовок dkim отключается.
Настройка postfix
Пошаговая настройка postfix включается следующей командой
sudo dpkg-reconfigure postfix
Конфигурационный файл postfix
$ sudo nano /etc/postfix/main.c
Для включения шифрования писем добавить свои сертификаты и опцию smtp_tls_security_level = may
без этого не шифровалось.
smtp_tls_security_level = may
smtpd_tls_cert_file=/etc/letsencrypt/live/www.sinyawskiy.ru/fullchain.pem
smtpd_tls_key_file=/etc/letsencrypt/live/www.sinyawskiy.ru/privkey.pem
Чтобы отправлял только с localhost
inet_interfaces = loopback-only
Чтобы использовал ipv4 адреса при подключении и отправке почты
inet_protocols = ipv4
Прописать доменное имя, если не прописалось при установке:
myhostname = sinyawskiy.ru
mydestination = $myhostname, sinyawskiy.ru, localhost.ru, localhost
В конец конфигурации добавить опции для работы с opendkim:
smtpd_milters = inet:127.0.0.1:8891
non_smtpd_milters = $smtpd_milters
milter_default_action = accept
Перезагрузить postfix и opendkim:
# service postfix restart
# service opendkim restart
Посмотреть все установленные настройки postfix
$ postconf -d
Проверка отправки почты
echo "Test body of the email" | mail -s "Test email subject" root
или на адрес yourname@hostname.com
echo "Test body of the email" | mail -s "Test email subject" yourname@hostname.com
В интерфейсе gmail видно, что postfix настроен и письмо зашифровалось.
[flickr:id=52016177368]
Настройка отправки почты postfix в django приложении
В настройках нужно прописать подключение почты к localhost на 25 порт.
settings.py
EMAIL_HOST = 'localhost'
EMAIL_PORT = 25
EMAIL_HOST_USER = ''
EMAIL_HOST_PASSWORD = ''
EMAIL_USE_TLS = False
Протестировать
(env) python manage.py shell
Проверка того, что настройки применились:
>>> from django.conf import settings
>>> settings.EMAIL_HOST
'localhost'
>>> settings.EMAIL_PORT
25
>>> settings.EMAIL_USE_TLS
False
>>>
>>> settings.EMAIL_USE_SSL
False
>>> settings.EMAIL_HOST_USER
''
>>> settings.EMAIL_HOST_PASSWORD
''
Проверка отправки почты
>>> from django.core.mail import send_mail
>>> send_mail('subject', 'message', 'info@sinyawskiy.ru', ['sinyawskiy@mail.ru'])
1