1201 lines
32 KiB
Markdown
1201 lines
32 KiB
Markdown
---
|
||
title: "Почтовый сервер на Debian 12: полное руководство от установки до production. Часть 4 - Шифрование и репутация отправителя"
|
||
date: 2026-04-19
|
||
draft: false
|
||
description: "Настройка TLS через Let's Encrypt, DKIM подписей, SPF и DMARC записей. Шифрование всех соединений SMTP/IMAP, повышение репутации отправителя для защиты от попадания в спам."
|
||
tags: ["tls", "ssl", "lets encrypt", "certbot", "dkim", "opendkim", "spf", "dmarc", "swaks"]
|
||
categories: ["Системное администрирование", "Электронная почта"]
|
||
series: ["Почтовый сервер на Debian 12"]
|
||
series_order: 4
|
||
---
|
||
|
||
# Шифрование и репутация отправителя
|
||
|
||
Почтовый сервер работает, защита от спама настроена. Но есть две критичные проблемы:
|
||
|
||
1. **Пароли передаются открытым текстом** - любой перехватчик трафика видит учетные данные
|
||
2. **Письма улетают в спам** - у Gmail/Outlook нет доверия к твоему серверу
|
||
|
||
Сейчас исправим: настроим шифрование всех соединений (TLS) и добавим цифровые подписи (DKIM + SPF + DMARC).
|
||
|
||
## Перед началом
|
||
|
||
У тебя должно быть:
|
||
- [Рабочий Postfix + Dovecot](/posts/mailserver-part-2-postfix-dovecot/)
|
||
- [Защита (Amavis, антивирус, антиспам)](/posts/mailserver-part-3-security)
|
||
- **Домен с доступом к DNS** (возможность добавлять TXT-записи)
|
||
- **Порты 80 и 443 открыты** (для валидации Let's Encrypt)
|
||
|
||
Проверь что сервер доступен по имени:
|
||
|
||
```bash
|
||
ping mail.example.com
|
||
```
|
||
|
||
Должен отвечать твой IP.
|
||
|
||
## Установка Let's Encrypt (Certbot)
|
||
|
||
Let's Encrypt выдает бесплатные SSL/TLS сертификаты на 90 дней с автоматическим продлением.
|
||
|
||
### Установка Certbot
|
||
|
||
```bash
|
||
sudo apt install -y certbot
|
||
```
|
||
|
||
### Получение сертификата
|
||
|
||
Certbot должен проверить что ты владеешь доменом. Используем **standalone** режим (временный веб-сервер на порту 80).
|
||
|
||
**Останови Apache/Nginx если запущены:**
|
||
|
||
```bash
|
||
sudo systemctl stop apache2 nginx
|
||
```
|
||
|
||
(Если их нет - игнорируй ошибку)
|
||
|
||
**Получи сертификат:**
|
||
|
||
```bash
|
||
sudo certbot certonly --standalone -d mail.example.com
|
||
```
|
||
|
||
**Замени** `mail.example.com` на свое полное имя хоста.
|
||
|
||
Certbot спросит:
|
||
- Email для уведомлений (укажи рабочий email)
|
||
- Согласие с Terms of Service (Yes)
|
||
- Подписка на новости (No)
|
||
|
||
Вывод:
|
||
|
||
```
|
||
- Congratulations! Your certificate and chain have been saved at:
|
||
/etc/letsencrypt/live/mail.example.com/fullchain.pem
|
||
Your key file has been saved at:
|
||
/etc/letsencrypt/live/mail.example.com/privkey.pem
|
||
Your certificate will expire on ... To obtain a new or
|
||
tweaked version of this certificate in the future, simply run
|
||
certbot again. To non-interactively renew *all* of your
|
||
certificates, run "certbot renew"
|
||
```
|
||
|
||
**Сертификат получен!** Срок действия: 90 дней.
|
||
|
||
### Права на ключи
|
||
|
||
Postfix и Dovecot должны читать приватный ключ:
|
||
|
||
```bash
|
||
sudo chmod 755 /etc/letsencrypt/live
|
||
sudo chmod 755 /etc/letsencrypt/archive
|
||
```
|
||
|
||
### Автообновление сертификата
|
||
|
||
Certbot автоматически создает cronjob для обновления. Проверь:
|
||
|
||
```bash
|
||
sudo systemctl status certbot.timer
|
||
```
|
||
|
||
Должен быть `active (running)`.
|
||
|
||
Тест автообновления:
|
||
|
||
```bash
|
||
sudo certbot renew --dry-run
|
||
```
|
||
|
||
Если вывод заканчивается на:
|
||
|
||
```
|
||
Congratulations, all simulated renewals succeeded:
|
||
/etc/letsencrypt/live/mail.example.com/fullchain.pem (success)
|
||
```
|
||
|
||
Автообновление настроено правильно.
|
||
|
||
## Настройка TLS для Postfix
|
||
|
||
Postfix будет использовать сертификат Let's Encrypt для шифрования SMTP соединений.
|
||
|
||
### Настройка main.cf
|
||
|
||
Открой:
|
||
|
||
```bash
|
||
sudo nano /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_auth_only=yes
|
||
smtpd_tls_protocols=!SSLv2,!SSLv3,!TLSv1,!TLSv1.1
|
||
smtpd_tls_ciphers=high
|
||
smtpd_tls_mandatory_protocols=!SSLv2,!SSLv3,!TLSv1,!TLSv1.1
|
||
smtpd_tls_mandatory_ciphers=high
|
||
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
|
||
smtpd_tls_loglevel = 1
|
||
|
||
# TLS для исходящих соединений
|
||
smtp_tls_security_level=may
|
||
smtp_tls_protocols=!SSLv2,!SSLv3,!TLSv1,!TLSv1.1
|
||
smtp_tls_ciphers=high
|
||
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
|
||
smtp_tls_loglevel = 1
|
||
```
|
||
|
||
**Замени** `mail.example.com` на свое имя хоста.
|
||
|
||
**Что настроили:**
|
||
|
||
**Входящие соединения (smtpd):**
|
||
- `smtpd_tls_security_level=may` - TLS опционально (старые клиенты без TLS смогут подключиться)
|
||
- `smtpd_tls_auth_only=yes` - SASL AUTH только через TLS (пароли не передаются открытым текстом)
|
||
- `smtpd_tls_protocols` - запретить устаревшие протоколы (SSLv2/v3, TLS 1.0/1.1)
|
||
- `smtpd_tls_ciphers=high` - только сильные шифры
|
||
|
||
**Исходящие соединения (smtp):**
|
||
- `smtp_tls_security_level=may` - пытаться использовать TLS при отправке на другие серверы
|
||
- Аналогичные ограничения по протоколам и шифрам
|
||
|
||
### Настройка master.cf для submission (порт 587)
|
||
|
||
Открой:
|
||
|
||
```bash
|
||
sudo nano /etc/postfix/master.cf
|
||
```
|
||
|
||
Найди секцию `submission inet` (должна быть из Части 2).
|
||
|
||
Убедись что есть:
|
||
|
||
```
|
||
submission inet n - y - - smtpd
|
||
-o syslog_name=postfix/submission
|
||
-o smtpd_tls_security_level=encrypt
|
||
-o smtpd_sasl_auth_enable=yes
|
||
-o smtpd_client_restrictions=permit_sasl_authenticated,reject
|
||
-o smtpd_recipient_restrictions=permit_sasl_authenticated,reject_unauth_destination
|
||
```
|
||
|
||
**Ключевое:** `-o smtpd_tls_security_level=encrypt` - **обязательное** шифрование на порту 587.
|
||
|
||
### Перезапуск Postfix
|
||
|
||
Проверь конфиг:
|
||
|
||
```bash
|
||
sudo postfix check
|
||
```
|
||
|
||
Если ошибок нет:
|
||
|
||
```bash
|
||
sudo postfix reload
|
||
sudo systemctl restart postfix
|
||
```
|
||
|
||
Проверь порты:
|
||
|
||
```bash
|
||
sudo ss -tulnp | grep master
|
||
```
|
||
|
||
Должно быть:
|
||
|
||
```
|
||
tcp LISTEN 0 100 0.0.0.0:25 ... master
|
||
tcp LISTEN 0 100 0.0.0.0:587 ... master
|
||
```
|
||
|
||
## Настройка TLS для Dovecot
|
||
|
||
Dovecot будет использовать тот же сертификат для IMAP.
|
||
|
||
### Настройка 10-ssl.conf
|
||
|
||
Открой:
|
||
|
||
```bash
|
||
sudo nano /etc/dovecot/conf.d/10-ssl.conf
|
||
```
|
||
|
||
Найди и измени:
|
||
|
||
```
|
||
ssl = required
|
||
ssl_cert = </etc/letsencrypt/live/mail.example.com/fullchain.pem
|
||
ssl_key = </etc/letsencrypt/live/mail.example.com/privkey.pem
|
||
|
||
ssl_min_protocol = TLSv1.2
|
||
ssl_cipher_list = HIGH:!aNULL:!MD5
|
||
ssl_prefer_server_ciphers = yes
|
||
```
|
||
|
||
**Замени** `mail.example.com` на свое имя хоста.
|
||
|
||
**Что настроили:**
|
||
|
||
- `ssl = required` - TLS обязателен (без шифрования нельзя)
|
||
- `ssl_min_protocol = TLSv1.2` - минимум TLS 1.2 (запретить старые)
|
||
- `ssl_cipher_list = HIGH` - только сильные шифры
|
||
|
||
### Настройка портов IMAPS
|
||
|
||
Открой:
|
||
|
||
```bash
|
||
sudo nano /etc/dovecot/conf.d/10-master.conf
|
||
```
|
||
|
||
Найди секцию `service imap-login` и настрой:
|
||
|
||
```
|
||
service imap-login {
|
||
inet_listener imap {
|
||
port = 0
|
||
}
|
||
inet_listener imaps {
|
||
port = 993
|
||
ssl = yes
|
||
}
|
||
}
|
||
```
|
||
|
||
**Что изменили:**
|
||
- `port = 0` для IMAP (143) - **отключили** незашифрованный IMAP
|
||
- `port = 993` для IMAPS - **включили** зашифрованный IMAP
|
||
|
||
### Перезапуск Dovecot
|
||
|
||
```bash
|
||
sudo systemctl restart dovecot
|
||
```
|
||
|
||
Проверь порты:
|
||
|
||
```bash
|
||
sudo ss -tulnp | grep dovecot
|
||
```
|
||
|
||
Должно быть:
|
||
|
||
```
|
||
tcp LISTEN 0 100 0.0.0.0:993 0.0.0.0:* users:(("dovecot",pid=...,fd=35))
|
||
```
|
||
|
||
**Порта 143 (IMAP) не должно быть** - только 993 (IMAPS).
|
||
|
||
## Тестирование TLS
|
||
|
||
### Тест 1: Проверка сертификата SMTP
|
||
|
||
```bash
|
||
openssl s_client -connect mail.example.com:587 -starttls smtp
|
||
```
|
||
|
||
В выводе должно быть:
|
||
|
||
```
|
||
...
|
||
Server certificate
|
||
-----BEGIN CERTIFICATE-----
|
||
...
|
||
-----END CERTIFICATE-----
|
||
subject=CN = mail.example.com
|
||
issuer=C = US, O = Let's Encrypt, CN = R3
|
||
...
|
||
```
|
||
|
||
И в конце:
|
||
|
||
```
|
||
Verify return code: 0 (ok)
|
||
```
|
||
|
||
**Код 0** - сертификат валиден.
|
||
|
||
Нажми `Ctrl+C` для выхода.
|
||
|
||
### Тест 2: Проверка сертификата IMAPS
|
||
|
||
```bash
|
||
openssl s_client -connect mail.example.com:993
|
||
```
|
||
|
||
Аналогично - должно быть `Verify return code: 0 (ok)`.
|
||
|
||
### Тест 3: Проверка что незашифрованный IMAP отключен
|
||
|
||
```bash
|
||
telnet mail.example.com 143
|
||
```
|
||
|
||
Должно быть:
|
||
|
||
```
|
||
Trying...
|
||
telnet: Unable to connect to remote host: Connection refused
|
||
```
|
||
|
||
**Правильно** - порт 143 закрыт, только 993 (IMAPS) работает.
|
||
|
||
## Установка OpenDKIM
|
||
|
||
DKIM (DomainKeys Identified Mail) - цифровая подпись исходящих писем. Получатель проверяет подпись через DNS и доверяет отправителю.
|
||
|
||
### Установка пакета
|
||
|
||
```bash
|
||
sudo apt install -y opendkim opendkim-tools
|
||
```
|
||
|
||
### Создание директорий и ключей
|
||
|
||
```bash
|
||
sudo mkdir -p /etc/opendkim/keys/example.com
|
||
cd /etc/opendkim/keys/example.com
|
||
```
|
||
|
||
**Замени** `example.com` на свой домен.
|
||
|
||
Генерация ключа:
|
||
|
||
```bash
|
||
sudo opendkim-genkey -s mail -d example.com
|
||
```
|
||
|
||
**Где:**
|
||
- `-s mail` - selector (имя ключа, можно любое, обычно `mail` или `default`)
|
||
- `-d example.com` - твой домен
|
||
|
||
Созданы файлы:
|
||
- `mail.private` - приватный ключ (хранится на сервере)
|
||
- `mail.txt` - публичный ключ (добавляется в DNS)
|
||
|
||
Права на приватный ключ:
|
||
|
||
```bash
|
||
sudo chown opendkim:opendkim mail.private
|
||
sudo chmod 600 mail.private
|
||
```
|
||
|
||
### Настройка opendkim.conf
|
||
|
||
Открой:
|
||
|
||
```bash
|
||
sudo nano /etc/opendkim.conf
|
||
```
|
||
|
||
Найди и измени/добавь:
|
||
|
||
```
|
||
# Логирование
|
||
Syslog yes
|
||
SyslogSuccess yes
|
||
LogWhy yes
|
||
|
||
# Режим работы
|
||
Mode sv
|
||
Canonicalization relaxed/simple
|
||
|
||
# Внутренние хосты
|
||
InternalHosts /etc/opendkim/TrustedHosts
|
||
|
||
# Сокет для Postfix
|
||
Socket inet:8891@localhost
|
||
|
||
# Подпись заголовков
|
||
SignatureAlgorithm rsa-sha256
|
||
OversignHeaders From
|
||
|
||
# Таблицы ключей и доменов
|
||
KeyTable /etc/opendkim/KeyTable
|
||
SigningTable refile:/etc/opendkim/SigningTable
|
||
```
|
||
|
||
**Что настроили:**
|
||
|
||
- `Mode sv` - sign (подписывать) и verify (проверять)
|
||
- `Socket inet:8891@localhost` - Postfix подключается сюда
|
||
- `SignatureAlgorithm rsa-sha256` - алгоритм подписи
|
||
- `KeyTable` и `SigningTable` - таблицы для поддержки нескольких доменов
|
||
|
||
### Создание KeyTable
|
||
|
||
```bash
|
||
sudo nano /etc/opendkim/KeyTable
|
||
```
|
||
|
||
Добавь:
|
||
|
||
```
|
||
mail._domainkey.example.com example.com:mail:/etc/opendkim/keys/example.com/mail.private
|
||
```
|
||
|
||
**Замени** `example.com` на свой домен (3 раза в строке).
|
||
|
||
**Формат:** `selector._domainkey.domain domain:selector:путь_к_ключу`
|
||
|
||
### Создание SigningTable
|
||
|
||
```bash
|
||
sudo nano /etc/opendkim/SigningTable
|
||
```
|
||
|
||
Добавь:
|
||
|
||
```
|
||
*@example.com mail._domainkey.example.com
|
||
*@mail.example.com mail._domainkey.example.com
|
||
```
|
||
|
||
**Замени** `example.com` на свой домен.
|
||
|
||
**Что настроили:**
|
||
- Первая строка - подписывать письма от `user@example.com`
|
||
- Вторая строка - подписывать письма от `user@mail.example.com`
|
||
|
||
Это покрывает оба варианта адресов.
|
||
|
||
### Настройка TrustedHosts
|
||
|
||
Создай файл:
|
||
|
||
```bash
|
||
sudo nano /etc/opendkim/TrustedHosts
|
||
```
|
||
|
||
Добавь:
|
||
|
||
```
|
||
127.0.0.1
|
||
localhost
|
||
192.168.0.0/16
|
||
10.0.0.0/8
|
||
|
||
*.example.com
|
||
example.com
|
||
mail.example.com
|
||
```
|
||
|
||
**Замени** `example.com` на свой домен.
|
||
|
||
Это список хостов/сетей которые могут отправлять через DKIM.
|
||
|
||
### Перезапуск OpenDKIM
|
||
|
||
```bash
|
||
sudo systemctl enable opendkim
|
||
sudo systemctl start opendkim
|
||
sudo systemctl status opendkim
|
||
```
|
||
|
||
Должен быть `active (running)`.
|
||
|
||
Проверь сокет:
|
||
|
||
```bash
|
||
sudo ss -tulnp | grep 8891
|
||
```
|
||
|
||
Должно быть:
|
||
|
||
```
|
||
tcp LISTEN 0 4096 127.0.0.1:8891 0.0.0.0:* users:(("opendkim",pid=...,fd=3))
|
||
```
|
||
|
||
## Интеграция OpenDKIM с Postfix
|
||
|
||
Postfix должен отправлять письма через OpenDKIM для подписи.
|
||
|
||
### Настройка main.cf
|
||
|
||
Открой:
|
||
|
||
```bash
|
||
sudo nano /etc/postfix/main.cf
|
||
```
|
||
|
||
Добавь в конец:
|
||
|
||
```
|
||
# DKIM
|
||
milter_default_action = accept
|
||
milter_protocol = 6
|
||
smtpd_milters = inet:localhost:8891
|
||
non_smtpd_milters = inet:localhost:8891
|
||
```
|
||
|
||
**Что настроили:**
|
||
|
||
- `smtpd_milters` - письма от клиентов идут через OpenDKIM
|
||
- `non_smtpd_milters` - письма от локальных процессов тоже идут через OpenDKIM
|
||
- `milter_default_action = accept` - если OpenDKIM недоступен, письма все равно отправляются
|
||
|
||
### Перезапуск Postfix
|
||
|
||
```bash
|
||
sudo postfix reload
|
||
```
|
||
|
||
## DNS записи для DKIM
|
||
|
||
OpenDKIM создал публичный ключ в файле `mail.txt`.
|
||
|
||
Посмотри:
|
||
|
||
```bash
|
||
sudo cat /etc/opendkim/keys/example.com/mail.txt
|
||
```
|
||
|
||
Вывод:
|
||
|
||
```
|
||
mail._domainkey IN TXT ( "v=DKIM1; h=sha256; k=rsa; "
|
||
"p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA..." )
|
||
```
|
||
|
||
**Скопируй строку** `p=MIIBIjAN...` (весь ключ, может быть многострочный).
|
||
|
||
### Добавление записи в DNS
|
||
|
||
Зайди в панель управления DNS своего домена (Cloudflare, reg.ru, и т.д.).
|
||
|
||
Добавь **TXT запись:**
|
||
|
||
**Имя (Name):**
|
||
```
|
||
mail._domainkey
|
||
```
|
||
|
||
**Значение (Value):**
|
||
```
|
||
v=DKIM1; h=sha256; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...
|
||
```
|
||
|
||
**Важно:**
|
||
- Убери скобки `( )` и кавычки `"`
|
||
- Оставь только `v=DKIM1; h=sha256; k=rsa; p=...` одной строкой
|
||
- TTL: 3600 или по умолчанию
|
||
|
||
### Проверка DNS
|
||
|
||
Подожди 5-10 минут для распространения DNS.
|
||
|
||
Проверь:
|
||
|
||
```bash
|
||
dig mail._domainkey.example.com TXT +short
|
||
```
|
||
|
||
Должно вернуть:
|
||
|
||
```
|
||
"v=DKIM1; h=sha256; k=rsa; p=MIIBIjAN..."
|
||
```
|
||
|
||
Если пусто - подожди еще, DNS может распространяться до 24 часов.
|
||
|
||
## DNS записи SPF
|
||
|
||
SPF (Sender Policy Framework) - список серверов которым разрешено отправлять письма от твоего домена.
|
||
|
||
### Добавление SPF записи
|
||
|
||
В DNS добавь **TXT запись:**
|
||
|
||
**Имя (Name):**
|
||
```
|
||
@
|
||
```
|
||
|
||
(или пусто, или `example.com` - зависит от провайдера DNS)
|
||
|
||
**Значение (Value):**
|
||
```
|
||
v=spf1 mx ~all
|
||
```
|
||
|
||
**Что означает:**
|
||
|
||
- `v=spf1` - версия SPF
|
||
- `mx` - серверы из MX записи могут отправлять
|
||
- `~all` - soft fail для остальных (помечать как подозрительное, но не отклонять)
|
||
|
||
### Проверка SPF
|
||
|
||
```bash
|
||
dig example.com TXT +short
|
||
```
|
||
|
||
Должно быть:
|
||
|
||
```
|
||
"v=spf1 mx ~all"
|
||
```
|
||
|
||
## DNS записи DMARC
|
||
|
||
DMARC (Domain-based Message Authentication, Reporting & Conformance) - политика обработки писем которые не прошли SPF/DKIM проверку.
|
||
|
||
### Добавление DMARC записи
|
||
|
||
В DNS добавь **TXT запись:**
|
||
|
||
**Имя (Name):**
|
||
```
|
||
_dmarc
|
||
```
|
||
|
||
**Значение (Value):**
|
||
```
|
||
v=DMARC1; p=none; rua=mailto:postmaster@example.com
|
||
```
|
||
|
||
**Замени** `postmaster@example.com` на свой email для отчетов.
|
||
|
||
**Что означает:**
|
||
|
||
- `v=DMARC1` - версия DMARC
|
||
- `p=none` - политика: не отклонять письма, только собирать статистику
|
||
- `rua=mailto:...` - email для агрегированных отчетов
|
||
|
||
**После тестирования** можно ужесточить до `p=quarantine` (в спам) или `p=reject` (отклонять).
|
||
|
||
### Проверка DMARC
|
||
|
||
```bash
|
||
dig _dmarc.example.com TXT +short
|
||
```
|
||
|
||
Должно быть:
|
||
|
||
```
|
||
"v=DMARC1; p=none; rua=mailto:postmaster@example.com"
|
||
```
|
||
|
||
## Тестирование DKIM подписи
|
||
|
||
Для тестирования нужен инструмент который эмулирует реального пользователя с почтовым клиентом.
|
||
|
||
### Установка swaks
|
||
|
||
**swaks** (Swiss Army Knife for SMTP) - инструмент для тестирования SMTP с авторизацией.
|
||
|
||
```bash
|
||
sudo apt install -y swaks
|
||
```
|
||
|
||
### Тест 1: Отправка письма самому себе
|
||
|
||
```bash
|
||
swaks --to admin@example.com \
|
||
--from admin@example.com \
|
||
--auth-user admin@example.com \
|
||
--auth-password 'пароль_admin' \
|
||
--server 127.0.0.1 \
|
||
--port 587 \
|
||
--tls \
|
||
--header "Subject: DKIM Test Internal" \
|
||
--body "Testing DKIM signature"
|
||
```
|
||
|
||
**Замени:**
|
||
- `admin@example.com` - на своего пользователя
|
||
- `пароль_admin` - на реальный пароль пользователя
|
||
|
||
Проверь что письмо подписано:
|
||
|
||
```bash
|
||
sudo cat /var/mail/example.com/admin/new/* | grep -i "DKIM-Signature"
|
||
```
|
||
|
||
Должно быть:
|
||
|
||
```
|
||
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=example.com;
|
||
s=mail; t=...;
|
||
bh=...;
|
||
h=From:To:Subject:Date;
|
||
b=...
|
||
```
|
||
|
||
**Наличие заголовка DKIM-Signature** - письмо подписано.
|
||
|
||
### Тест 2: Отправка на внешний ящик (Gmail/Yandex)
|
||
|
||
Отправь письмо на свой Gmail или Yandex:
|
||
|
||
```bash
|
||
swaks --to your-email@gmail.com \
|
||
--from admin@example.com \
|
||
--auth-user admin@example.com \
|
||
--auth-password 'пароль_admin' \
|
||
--server 127.0.0.1 \
|
||
--port 587 \
|
||
--tls \
|
||
--header "Subject: DKIM External Test" \
|
||
--body "Testing DKIM, SPF, DMARC"
|
||
```
|
||
|
||
Открой письмо в Gmail → **Show original** → смотри заголовки.
|
||
|
||
Должно быть:
|
||
|
||
```
|
||
DKIM: 'PASS' with domain example.com
|
||
SPF: 'PASS' with IP <ip-твоего-сервера>
|
||
DMARC: 'PASS'
|
||
```
|
||
|
||
**Все три теста PASS** - конфигурация правильная.
|
||
|
||
### Тест 3: Полная проверка через mail-tester.com
|
||
|
||
**Mail-tester** - сервис который выставляет оценку от 0 до 10/10 на основе:
|
||
- DKIM подпись
|
||
- SPF проверка
|
||
- DMARC политика
|
||
- Blacklist проверка
|
||
- Содержимое письма
|
||
- PTR запись
|
||
|
||
**Лимит:** 3 бесплатных теста в день.
|
||
|
||
#### Шаг 1: Получи тестовый адрес
|
||
|
||
Зайди на https://www.mail-tester.com. На странице будет **тестовый адрес** типа:
|
||
|
||
```
|
||
test-abc123xyz@srv1.mail-tester.com
|
||
```
|
||
|
||
**Этот адрес уникальный** и меняется при каждом посещении страницы.
|
||
|
||
#### Шаг 2: Отправь письмо
|
||
|
||
```bash
|
||
swaks --to test-abc123xyz@srv1.mail-tester.com \
|
||
--from admin@example.com \
|
||
--auth-user admin@example.com \
|
||
--auth-password 'пароль_admin' \
|
||
--server 127.0.0.1 \
|
||
--port 587 \
|
||
--tls \
|
||
--header "Subject: Mail Server Test" \
|
||
--body "Testing complete mail server configuration"
|
||
```
|
||
|
||
**Замени** `test-abc123xyz@srv1.mail-tester.com` на адрес со страницы mail-tester.com.
|
||
|
||
#### Шаг 3: Проверь результат
|
||
|
||
**Подожди 10-20 секунд**, обнови страницу mail-tester.com (или нажми кнопку **"Затем проверьте оценку"**).
|
||
|
||
**Целевая оценка: 9-10/10**
|
||
|
||
Если **PTR запись не настроена** у провайдера - будет **8-9/10** (это нормально на этапе настройки).
|
||
|
||
#### Что должно быть в отчёте:
|
||
|
||
**DKIM:**
|
||
```
|
||
DKIM signature: PASS
|
||
Domain: example.com
|
||
Selector: mail
|
||
```
|
||
|
||
**SPF:**
|
||
```
|
||
SPF check: PASS
|
||
IP authorized to send mail for example.com
|
||
```
|
||
|
||
**DMARC:**
|
||
```
|
||
DMARC policy: PASS
|
||
Alignment: pass (From Domain = DKIM Domain)
|
||
```
|
||
|
||
**Not blacklisted:**
|
||
```
|
||
Your IP is not blacklisted
|
||
```
|
||
|
||
**Если оценка < 8/10:**
|
||
|
||
Смотри **что не прошло** в отчёте:
|
||
|
||
1. **DKIM FAIL** → Проверь DNS `mail._domainkey.example.com` TXT
|
||
2. **SPF FAIL** → Проверь SPF `example.com` TXT = `v=spf1 mx ~all`
|
||
3. **DMARC FAIL** → From Domain не совпадает с DKIM Domain (проверь SigningTable)
|
||
4. **Blacklisted** → IP в блэклисте, проверь на https://mxtoolbox.com/blacklists.aspx
|
||
5. **No PTR** → Настрой reverse DNS у провайдера (даёт -1 балл, не критично)
|
||
6. **SpamAssassin high score** → Проверь содержимое письма
|
||
|
||
### Альтернатива: MXToolbox Email Health
|
||
|
||
Если mail-tester.com недоступен:
|
||
|
||
Зайди на https://mxtoolbox.com/emailhealth/
|
||
|
||
Получи тестовый адрес, отправь через swaks аналогично.
|
||
|
||
## Автоматическое обновление сертификата
|
||
|
||
Let's Encrypt сертификаты действуют 90 дней. Certbot автоматически обновляет их через systemd timer.
|
||
|
||
### Проверка таймера
|
||
|
||
```bash
|
||
sudo systemctl status certbot.timer
|
||
```
|
||
|
||
Должен быть `active (running)`.
|
||
|
||
Посмотри когда следующий запуск:
|
||
|
||
```bash
|
||
sudo systemctl list-timers | grep certbot
|
||
```
|
||
|
||
Вывод:
|
||
|
||
```
|
||
Mon 2026-04-20 10:06:40 MSK 12h left Sun 2026-04-19 17:55:37 MSK 4h 8min ago certbot.timer certbot.service
|
||
```
|
||
|
||
### Настройка хука для перезапуска сервисов
|
||
|
||
После обновления сертификата Postfix и Dovecot должны перезапуститься.
|
||
|
||
Создай хук:
|
||
|
||
```bash
|
||
sudo nano /etc/letsencrypt/renewal-hooks/deploy/reload-services.sh
|
||
```
|
||
|
||
Добавь:
|
||
|
||
```bash
|
||
#!/bin/bash
|
||
systemctl reload postfix
|
||
systemctl restart dovecot
|
||
```
|
||
|
||
Права на выполнение:
|
||
|
||
```bash
|
||
sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-services.sh
|
||
```
|
||
|
||
Теперь после каждого обновления сертификата Postfix и Dovecot автоматически перезапустятся.
|
||
|
||
### Тест обновления
|
||
|
||
```bash
|
||
sudo certbot renew --dry-run
|
||
```
|
||
|
||
Если вывод:
|
||
|
||
```
|
||
Congratulations, all simulated renewals succeeded
|
||
```
|
||
|
||
Автообновление настроено правильно.
|
||
|
||
## Проверка открытых портов
|
||
|
||
Убедись что нужные порты открыты в firewall:
|
||
|
||
```bash
|
||
sudo ufw status
|
||
```
|
||
|
||
Должно быть:
|
||
|
||
```
|
||
25/tcp ALLOW Anywhere
|
||
587/tcp ALLOW Anywhere
|
||
993/tcp ALLOW Anywhere
|
||
80/tcp ALLOW Anywhere (для Let's Encrypt)
|
||
443/tcp ALLOW Anywhere (для будущего RoundCube)
|
||
```
|
||
|
||
Если чего-то нет:
|
||
|
||
```bash
|
||
sudo ufw allow 587/tcp
|
||
sudo ufw allow 993/tcp
|
||
sudo ufw allow 80/tcp
|
||
sudo ufw allow 443/tcp
|
||
```
|
||
|
||
## PTR (Reverse DNS)
|
||
|
||
PTR запись критично важна для репутации почтового сервера.
|
||
|
||
### Что такое PTR
|
||
|
||
Reverse DNS (rDNS) - сопоставление IP адреса с доменным именем.
|
||
|
||
Проверка:
|
||
|
||
```bash
|
||
dig -x ваш-IP-адрес +short
|
||
```
|
||
|
||
Должно вернуть:
|
||
|
||
```
|
||
mail.example.com
|
||
```
|
||
|
||
### Настройка PTR
|
||
|
||
PTR запись **настраивается у хостинг-провайдера**, не в DNS панели домена.
|
||
|
||
**Обратись в техподдержку провайдера** с запросом:
|
||
|
||
```
|
||
Прошу настроить PTR (reverse DNS) запись:
|
||
IP: ваш-IP-адрес
|
||
PTR: mail.example.com
|
||
```
|
||
|
||
Обычно настройка применяется за 1-24 часа.
|
||
|
||
### Проверка после настройки
|
||
|
||
```bash
|
||
dig -x ваш-IP-адрес +short
|
||
```
|
||
|
||
Должно вернуть `mail.example.com`.
|
||
|
||
**Без PTR записи** письма могут попадать в спам у большинства серьезных провайдеров.
|
||
|
||
## Типичные проблемы
|
||
|
||
### Let's Encrypt не может получить сертификат
|
||
|
||
Ошибка:
|
||
|
||
```
|
||
Failed authorization procedure. mail.example.com (http-01): ...
|
||
```
|
||
|
||
**Причины:**
|
||
|
||
1. **Порт 80 закрыт** - проверь `sudo ufw status`, открой `sudo ufw allow 80/tcp`
|
||
2. **DNS не указывает на сервер** - проверь `dig mail.example.com +short`, должен быть твой IP
|
||
3. **Другой веб-сервер занимает порт 80** - останови его перед запуском certbot
|
||
|
||
Проверь доступность:
|
||
|
||
```bash
|
||
curl http://mail.example.com
|
||
```
|
||
|
||
Должен отвечать (или 404, главное что порт открыт).
|
||
|
||
---
|
||
|
||
### Postfix не запускается после настройки TLS
|
||
|
||
Проверь логи:
|
||
|
||
```bash
|
||
sudo journalctl -u postfix -n 50
|
||
```
|
||
|
||
Частые ошибки:
|
||
|
||
**"permission denied" на ключах:**
|
||
|
||
```bash
|
||
sudo chmod 755 /etc/letsencrypt/live
|
||
sudo chmod 755 /etc/letsencrypt/archive
|
||
sudo systemctl restart postfix
|
||
```
|
||
|
||
**Неправильный путь к сертификату:**
|
||
|
||
Проверь что путь в `main.cf` совпадает с выводом `certbot certificates`.
|
||
|
||
---
|
||
|
||
### OpenDKIM не подписывает письма
|
||
|
||
Проверь что OpenDKIM запущен:
|
||
|
||
```bash
|
||
sudo systemctl status opendkim
|
||
```
|
||
|
||
Проверь логи:
|
||
|
||
```bash
|
||
sudo journalctl -u opendkim -n 50
|
||
```
|
||
|
||
Частые ошибки:
|
||
|
||
**"can't open private key":**
|
||
|
||
```bash
|
||
sudo chown opendkim:opendkim /etc/opendkim/keys/example.com/mail.private
|
||
sudo chmod 600 /etc/opendkim/keys/example.com/mail.private
|
||
sudo systemctl restart opendkim
|
||
```
|
||
|
||
**Postfix не подключается к OpenDKIM:**
|
||
|
||
Проверь сокет:
|
||
|
||
```bash
|
||
sudo ss -tulnp | grep 8891
|
||
```
|
||
|
||
Если пусто - OpenDKIM не слушает. Проверь `Socket` в `/etc/opendkim.conf`.
|
||
|
||
---
|
||
|
||
### DKIM проверка не проходит (DKIM: FAIL)
|
||
|
||
**Причины:**
|
||
|
||
1. **Публичный ключ не в DNS**
|
||
|
||
Проверь:
|
||
|
||
```bash
|
||
dig mail._domainkey.example.com TXT +short
|
||
```
|
||
|
||
Если пусто - добавь запись, подожди распространения DNS.
|
||
|
||
2. **Selector не совпадает**
|
||
|
||
В `/etc/opendkim/KeyTable` должно быть `mail._domainkey.example.com`.
|
||
В DNS запись должна быть `mail._domainkey.example.com`.
|
||
|
||
3. **Публичный ключ неправильный**
|
||
|
||
Проверь что в DNS точно тот ключ из `/etc/opendkim/keys/example.com/mail.txt` (без скобок и кавычек).
|
||
|
||
---
|
||
|
||
### SPF проверка не проходит (SPF: FAIL)
|
||
|
||
Проверь SPF запись:
|
||
|
||
```bash
|
||
dig example.com TXT +short
|
||
```
|
||
|
||
Должно быть:
|
||
|
||
```
|
||
"v=spf1 mx ~all"
|
||
```
|
||
|
||
Если письмо отправляется с IP который НЕ в MX:
|
||
|
||
```
|
||
v=spf1 mx ip4:ваш-IP ~all
|
||
```
|
||
|
||
Добавь IP явно.
|
||
|
||
---
|
||
|
||
### Письма все равно попадают в спам
|
||
|
||
Проверь через DKIM Validator (см. "Тест 3" выше).
|
||
|
||
Типичные проблемы:
|
||
|
||
1. **PTR запись отсутствует** - настрой у провайдера
|
||
2. **IP в блэклистах** - проверь на https://mxtoolbox.com/blacklists.aspx
|
||
3. **Нет DMARC** - добавь `_dmarc` TXT запись
|
||
4. **Содержимое письма спамное** - SpamAssassin дает много баллов
|
||
|
||
Дай серверу поработать 1-2 недели - репутация IP растет постепенно.
|
||
|
||
---
|
||
|
||
### Certbot не обновляет сертификат автоматически
|
||
|
||
Проверь таймер:
|
||
|
||
```bash
|
||
sudo systemctl status certbot.timer
|
||
```
|
||
|
||
Если `inactive (dead)`:
|
||
|
||
```bash
|
||
sudo systemctl enable certbot.timer
|
||
sudo systemctl start certbot.timer
|
||
```
|
||
|
||
Проверь что хук работает:
|
||
|
||
```bash
|
||
sudo certbot renew --dry-run
|
||
```
|
||
|
||
В выводе должно быть:
|
||
|
||
```
|
||
Running deploy hook command: /etc/letsencrypt/renewal-hooks/deploy/reload-services.sh
|
||
```
|
||
|
||
## Что получилось
|
||
|
||
Сейчас у тебя:
|
||
|
||
**Работает:**
|
||
- Все соединения зашифрованы (TLS 1.2+)
|
||
- Пароли не передаются открытым текстом
|
||
- Письма подписываются DKIM
|
||
- SPF защищает от подделки домена
|
||
- DMARC контролирует политику
|
||
- Сертификаты автоматически обновляются каждые 90 дней
|
||
|
||
**Репутация:**
|
||
- Gmail/Outlook доверяют твоим письмам
|
||
- Вероятность попадания в спам снижена на 80-90%
|
||
- SPF, DKIM, DMARC - все на месте
|
||
- (PTR добавит еще +10% после настройки у провайдера)
|
||
|
||
**Проблемы:**
|
||
- Нет веб-интерфейса для работы с почтой
|
||
- Пользователи хранятся в файлах (не масштабируется)
|
||
- Нет удобного управления ящиками
|
||
|
||
Это **production-ready сервер** с шифрованием и репутацией.
|
||
|
||
## Следующий шаг
|
||
|
||
В следующей части добавим веб-интерфейс:
|
||
- RoundCube webmail (работа с почтой через браузер)
|
||
- Apache + PHP 8.2
|
||
- Плагины для смены паролей и фильтров Sieve
|
||
- Интеграция с Postfix/Dovecot
|
||
|
||
После этого сервером можно будет пользоваться без настройки почтовых клиентов. |