linuxlab.io
Учебники▾
  • Линукс и сети
    Файловая система, процессы, TCP/IP, BGP и OSPF
    →
  • Terraform и IaC
    HCL, state, plan/apply на sandbox LocalStack
    →
  • Git и GitHub
    Объектная модель, plumbing, ветвление, GitHub Actions
    →
Все учебники →
ЦеныО платформеВойтиСоздать аккаунт
/
  • Введение
  • Уроки
  • How it works
  • Симулятор
  • База знаний
  • Собеседование
Index
Categories
All entries
Footer
linuxlab-УчебникиЦеныО платформеКонфиденциальность и куки
Copyright © 2026 LinuxLab. Все права защищены.
home/linux/kb/Протоколы/smtp-mta

kb/protocols ── Протоколы ── intermediate

SMTP и MTA - доставка email

SMTP - текстовый протокол доставки почты. 25/tcp - server-to-server, 587 - submission (клиент с auth), 465 - implicit-TLS legacy. MX-запись в DNS, STARTTLS+SPF+DKIM+DMARC - стандартный набор.

view as markdownaka: smtp, mta, postfix, exim, mail-server, mail-relay

Зачем понимать SMTP

Простой текстовый протокол, но вокруг, лес: куча версий, расширений, 3 порта, anti-spam-стандарты (SPF/DKIM/DMARC), трёхслойная иерархия (MUA → MSA → MTA → MTA → MDA → MUA). Когда надо:

  • Поднять corp-mail-сервер (Postfix/Exim для outbound; Dovecot для IMAP)
  • Настроить relay-host для приложений ("отправляй уведомления через X")
  • Дебажить почему "письма не доходят" (это всегда DNS + SPF + DMARC)
  • Понять что показывает journalctl -u postfix при ошибке

Современные тренды: внутренние почтовики уходят в SaaS (Google Workspace, Microsoft 365). Self-hosted SMTP остаётся для outbound (заявки, нотификации) и в нишах где нельзя cloud (compliance, gov).

Три порта

ПортЧтоШифрование
25 (smtp)server-to-server, MTA-MTAopportunistic STARTTLS
587 (submission)клиент → его MTA, с аутентификациейSTARTTLS обязательный
465 (smtps)то же что 587 но implicit TLSTLS с handshake (legacy, RFC 8314 reissued его)
2525non-standard, иногда у hosted-relay (SendGrid и др)STARTTLS
  • 25 на исходящий из домашних/ISP-сетей часто заблокирован оператором (anti-spam). Оттуда шлём через 587 на свой MTA.
  • 587, современный для клиентов. Auth обязателен.
  • 465 был deprecated в 1998, возрождён в 2018 (RFC 8314) для клиентов, которым STARTTLS-handshake стартует в plaintext (можно downgrade-attack'ом убрать STARTTLS-extension).

SMTP-сессия (вживую)

$ telnet smtp.example.com 25
Trying 198.51.100.10...
Connected.
220 mail.example.com ESMTP Postfix
> EHLO client.example.org
250-mail.example.com Hello client
250-PIPELINING
250-SIZE 52428800
250-STARTTLS
250-AUTH PLAIN LOGIN
250 ENHANCEDSTATUSCODES
> MAIL FROM:<sender@example.org>
250 2.1.0 Ok
> RCPT TO:<rcpt@example.com>
250 2.1.5 Ok
> DATA
354 End data with <CR><LF>.<CR><LF>
> Subject: hello
>
> body
> .
250 2.0.0 Ok: queued as ABC123
> QUIT
221 2.0.0 Bye

Текстовый, можно дебажить пальцами. EHLO (вместо HELO) запрашивает расширения (ESMTP). STARTTLS, AUTH, SIZE, extensions.

DNS: MX-запись

Чтобы кто-то знал, на какой сервер слать почту для example.com:

example.com.   IN  MX  10  mail.example.com.
example.com.   IN  MX  20  backup-mail.example.com.
  • 10, 20, priority. Меньше = выше приоритет. MTA пробует в порядке возрастания priority.
  • Несколько MX той же priority = round-robin.

Проверка через cmd-dig:

bash
dig example.com MX +short

Если нет MX-записи, почта идёт на A/AAAA домена (RFC 5321 §5.1).

SPF, кто может слать от моего домена

TXT-запись в DNS:

example.com.  IN  TXT  "v=spf1 ip4:198.51.100.10 include:_spf.google.com -all"

Получающий MTA смотрит SPF-запись src-домена и проверяет: подключающийся IP, в разрешённом списке? Если нет, -all (hard fail) → отклонить.

Механизмы:

  • ip4:/ip6:, конкретные IP/подсети
  • a, любой A-record домена
  • mx, любой MX-target
  • include:other.com, наследовать SPF другого домена
  • ~all (soft fail), пометить как подозрительное
  • -all (hard fail), отклонить

SPF ломается на forwarding (forwarder ставит свой src, не оригинальный). Решение, DKIM.

DKIM, подпись писем

MTA подписывает выходящие письма приватным ключом, публичный лежит в DNS:

default._domainkey.example.com.  IN  TXT  "v=DKIM1; k=rsa; p=MIGfMA0..."

Получатель смотрит DKIM-Signature хедер, достаёт публичный ключ через DNS, проверяет подпись от headers + body. Если совпало письмо точно от этого домена и не модифицировано.

В отличие от SPF, DKIM-подпись переживает forwarding (если forwarder не правит body).

DMARC, политика для receiver'а

Оркестрирует SPF + DKIM:

_dmarc.example.com.  IN  TXT  "v=DMARC1; p=quarantine; rua=mailto:dmarc@example.com; pct=100"
  • p=none, только репорты, не действовать
  • p=quarantine, в спам
  • p=reject, отбросить
  • rua=, куда слать aggregate-репорты
  • pct=, на какой % писем применять политику (для постепенного rollout'а)

Минимальный требуемый сетап для outbound: SPF + DKIM + DMARC. Без них Gmail/Outlook/etc. с большой вероятностью бросят в спам.

Postfix vs Exim

ПризнакPostfixExim
Default гдеUbuntu, RHELDebian (исторически)
Конфигmain.cf + master.cf, Си-стильexim.conf, мощнее DSL
Архитектурамодульная, много мелких процессоводин большой бинарь
Сложность learning curveсредняявысокая
Production кто используетбольшинствоCambridge, kafka-mailing

Для нового сетапа, Postfix. Exim, если уже унаследовал.

Минимальный outbound через Postfix

/etc/postfix/main.cf:

ini
myhostname = mail.example.com
mydomain = example.com
myorigin = $mydomain
inet_interfaces = all
inet_protocols = ipv4
mydestination = $myhostname, localhost.$mydomain, localhost
# Relay - только из локальной сети (чтобы не быть open relay)
mynetworks = 127.0.0.0/8, 10.0.0.0/24
# TLS server
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          # opportunistic
smtpd_tls_loglevel = 1
# TLS client (для outbound)
smtp_tls_security_level = may
smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt
bash
postfix check                # синтаксис
systemctl reload postfix
postqueue -p                 # очередь
postsuper -d ALL deferred    # очистить deferred (осторожно!)

Когда что-то пошло не так

  • relay access denied, отправляешь не из mynetworks без auth. Либо добавь IP в mynetworks, либо требуй SMTP AUTH через 587.
  • Письма уходят, но в спам, нет/неправильный SPF/DKIM/DMARC. Проверка через https://mail-tester.com или Gmail "show original".
  • Connection timed out на 25, оператор блокирует исходящий 25. Используй 587 на relayhost.
  • Очередь deferred растёт, receiver greylisting (вернёт 451 на первую попытку, ждёт повтор). Норма для Gmail. mailq, посмотреть что застряло.
  • Helo command rejected: need fully-qualified hostname myhostname не FQDN или PTR-запись на IP не совпадает с EHLO.
  • SSL_connect:error на STARTTLS, устаревший cipher на одной стороне; smtpd_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1.
  • Письма back-to-self не доходят, mydestination не содержит локальный домен, MTA пытается забэкапить через DNS, MX резолвит в себя, петля.

§ команды

bash
dig example.com MX +short

MX-записи домена - первое что смотреть в email-routing

bash
dig example.com TXT +short | grep spf

SPF-запись - кому разрешено слать от этого домена

bash
dig default._domainkey.example.com TXT +short

DKIM публичный ключ для selector 'default' - проверка существования

bash
dig _dmarc.example.com TXT +short

DMARC-политика домена - reject/quarantine/none

bash
openssl s_client -starttls smtp -connect mail.example.com:25 -crlf

Подключиться с STARTTLS - проверить TLS-сертификат и доступность

bash
postqueue -p

Очередь Postfix - что застряло, почему (deferred reason)

bash
journalctl -u postfix -f --since '5 min ago'

Логи Postfix в реальном времени - первое место смотреть

§ см. также

  • dns-resolutionDNS resolutionРезолвинг имени → IP проходит через NSS: сначала `/etc/hosts`, потом DNS через `/etc/resolv.conf`. Порядок задаётся в `/etc/nsswitch.conf`.
  • tls-handshakeTLS handshakeTLS - слой шифрования поверх TCP. Перед передачей данных стороны делают handshake: обмениваются ключами, проверяют сертификат, выбирают cipher.
  • cmd-digdig - DNS-разведка с подробностямиdig - DNS-разведка. Запросить любую запись у любого сервера. +short - компактно, +trace - путь от корня, +dnssec - показать подписи. Современная замена nslookup для отладки.
  • sshSSH - secure shellSSH - зашифрованный канал к удалённому хосту: shell, копирование файлов, port-forwarding. Стандартный порт 22, аутентификация по ключам или паролю.
  • ldap-basicsLDAP - directory services основыLDAP - запрос к иерархическому справочнику. DN = координата объекта (cn=user,ou=People,dc=example,dc=com), bind = аутентификация, schema задаёт классы объектов и атрибуты. OpenLDAP/389-DS на Linux.
  • tls-certificatesTLS-сертификаты - X.509, цепочка доверия, Let's EncryptTLS cert - X.509 объект с public key + identity (CN/SAN) + подписью CA. Цепочка: leaf → intermediate → root (доверенный OS). Let's Encrypt = бесплатный CA через ACME (HTTP-01/DNS-01 challenge). В k8s - cert-manager.
  • gpg-pgpGPG/PGP - подпись, шифрование, web of trustGPG = open-source реализация OpenPGP. Пара ключей (RSA/ECDSA), публичный для verify/encrypt, приватный для sign/decrypt. keyring локально, web-of-trust между людьми. Используется в git-commit signing, package-signing (apt/rpm), email.
Footer
linuxlab-
Copyright © 2026 LinuxLab. Все права защищены.
Учебники
Цены
О платформе
Конфиденциальность и куки