diff --git a/content/posts/mailserver-part-4-tls+dkim+spf+dmarс/featured.png b/content/posts/mailserver-part-4-tls+dkim+spf+dmarс/featured.png new file mode 100644 index 0000000..5e71a41 Binary files /dev/null and b/content/posts/mailserver-part-4-tls+dkim+spf+dmarс/featured.png differ diff --git a/content/posts/mailserver-part-4-tls+dkim+spf+dmarс/index.md b/content/posts/mailserver-part-4-tls+dkim+spf+dmarс/index.md new file mode 100644 index 0000000..8ec5094 --- /dev/null +++ b/content/posts/mailserver-part-4-tls+dkim+spf+dmarс/index.md @@ -0,0 +1,1201 @@ +--- +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 = +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 + +После этого сервером можно будет пользоваться без настройки почтовых клиентов. \ No newline at end of file