В этой статье я покажу, как настроить свой почтовый сервер для аккаунтов локальных пользователей без веб-морд, docker-ов, телеграм-помоек и LLM-высеров.
Жалкие отп^W^W Дисклеймер: я - админ локалхоста. В статье полно англицизмов и недопереведённых терминов.
Что происходит? Где я? Помогите!
Эта статья — перевод моего же поста, по сути копии вот этого немного устаревшего поста в другом блоге (архивная копия) (далее — «оригинальный гайд»), на который мне в своё время очень повезло наткнуться.
Будем настраивать почтовый сервер так, чтобы у каждого пользователя ОС была своя почта, а письма хранились в ~/Maildir.
Индигриенты ©
Понадобятся нам, собственно, сервер на arch linux с белым IP, доменное имя, сертификат и, желательно, reverse DNS.
Сервер должен быть исключительно и только на arch, на других дистрибутивах поднять почтовый сервер принципиально невозможно.
Reverse DNS нас интересует только тем, что позволяет по IP-адресу получить доменное имя, на этот адрес указывающее, а нужен он нам затем, чтобы у почтовых серверов, с которыми будет общаться наш сервер, была yet another проверка, уменьшающая вероятность попадания нашего сервера в спам-листы.
На самом по себе попадании в спам-листы мои полномочия всё, но для выхода из одного того, в который попадал я, достаточно было ткнуть мышкой одну кнопку на сайте спам-листа.
Вычитать reverse DNS для, например, 8.8.8.8 можно вот так (указывает оно на dns.google, точка в конце нас сейчас не интересует):
$ dig -x 8.8.8.8 | grep -vE "^$|^;" 8.8.8.8.in-addr.arpa. 75882 IN PTR dns.google.
Выставить reverse DNS можно либо в админке вашего домашнего провайдера или хостера, либо, как сделал я, написав e-mail в поддержку провайдера и попросив выставить нужное значение reverse DNS для вашего IP-адреса. ИЧСХ, мне сделали это за 15 минут без лишних вопросов, я сильно удивился.
Оригинальный гайд использует self-signed сертификат, я использую let’s encrypt, потому что мне даже думать лень о проблемах, связанных с самоподписными сертификатами. Когда-нибудь, думаю, подумаю о проблемах с let’s encrypt, но Леонид Каневский.
Перед тем, как отправлять письма со своего почтового сервера на реальные адреса внешних серверов прямо в процессе настройки своего сервера с мыслью «я, конечно, гайд не дочитал, но а вдруг оно уже работает», потренируйтесь на кошках, иначе есть риск загреметь в спам-листы.
После того как у вас всё заработает, или после последующих изменений конфигов, делайте бекапы. По крайней мере, dovecot не так давно сломал обратную совместимость конфигов. Если у вас под рукой есть бекап конфигов, вы можете откатить версию postfix/dovecot/whatever из /var/cache/pacman/pkg/, а уже потом, имея рабочую почту, спокойно разбираться с новой версией сломанного софта.
Ниже, как и в оригинальном гайде, пойдут однотипные главы с подглавами, в которых большинство содержимого — команды, показывающие значимые части конфигов, и их, команд, вывод. В оригинальном гайде, который я по сути слямзил, достаточно много поясняющих комментариев. Туда я вас за ними и приглашаю, а здесь будет минимум, необходимый для запуска сервера.
Что вообще делать со всем нижеизложенным? В каждой главе накатывать указанный софт, потом grep-ать по /etc/<tool-name>, в каких конфигах у вас лежит что-то похожее, и доводить эти конфиги до нужной кондиции.
Сертификаты
$ pacman -S certbot $ certbot -d mydomain.name
Если у вас это не работает или у вас нет веб-сервера, добро пожаловать в вики: https://wiki.archlinux.org/title/Certbot
Dovecot
https://wiki.archlinux.org/title/Dovecot
Установка
pacman -S dovecot
Настройка
Тип и расположение почты, «папки»
doveconf -n mail_path mail_driver namespace inbox
Вывод:
mail_path = ~/Maildir mail_driver = maildir namespace inbox { inbox = yes separator = / mailbox Drafts { special_use = "\\Drafts" } mailbox Junk { special_use = "\\Junk" } mailbox Trash { special_use = "\\Trash" } mailbox Sent { special_use = "\\Sent" } mailbox "Sent Messages" { special_use = "\\Sent" } }
Добавляем юзера dovecot в группу mail
usermod -aG mail dovecot id dovecot
Вывод:
uid=76(dovecot) gid=76(dovecot) groups=76(dovecot),12(mail)
SSL-сертификаты
SSL
doveconf ssl ssl_server_cert_file ssl_server_key_file ssl_server_dh_file
Вывод:
ssl = yes ssl_server_cert_file = /etc/letsencrypt/live/kostovsky.me/fullchain.pem ssl_server_key_file = /etc/letsencrypt/live/kostovsky.me/privkey.pem ssl_server_dh_file = /etc/dovecot/dh.pem
Аутентификация
doveconf -n userdb passdb
Вывод (имена секций здесь выбраны случайно: с некоторой версии dovecot потребовал их, имена, добавить, я и добавил):
userdb fuck_dovecot { driver = passwd } passdb fuck_dovecot { driver = pam }
cat /etc/pam.d/dovecot
Вывод:
#%PAM-1.0 auth include system-auth account include system-auth session include system-auth password include system-auth
Создаём юзера
Если вдруг у вас его ещё нет. Его логин и будет использоваться в почтовом адресе. У каждого «нормального» пользователя в системе будет свой почтовый ящик, а для логина в почту будет использоваться пароль этого пользователя в ОС.
useradd nikita -m passwd nikita
Весь итоговый конфиг
Спрятал под спойлер
doveconf -n
Output:
## 2.4.4 (8b687aa65c): /etc/dovecot/dovecot.conf ## OS: Linux 7.1.5-arch1-2 x86_64 ## Hostname: home ## 29 default setting changes since version 2.4.1 dovecot_config_version = 2.4.1 auth_mechanisms = plain dovecot_storage_version = 2.4.1 mail_driver = maildir mail_path = ~/Maildir protocols { imap = yes lmtp = yes } passdb fuck_dovecot { driver = pam } userdb fuck_dovecot { driver = passwd } service director { listen = * :: unix_listener login/director { } fifo_listener login/proxy-notify { } unix_listener director-userdb { } } service imap-login { inet_listener imap { } inet_listener imaps { } } service pop3-login { inet_listener pop3 { } inet_listener pop3s { } } service submission-login { inet_listener submission { } inet_listener submissions { } } namespace inbox { inbox = yes separator = / mailbox Drafts { special_use = "\\Drafts" } mailbox Junk { special_use = "\\Junk" } mailbox Trash { special_use = "\\Trash" } mailbox Sent { special_use = "\\Sent" } mailbox "Sent Messages" { special_use = "\\Sent" } } service lmtp { unix_listener lmtp { } } service imap { } service pop3 { } service submission { } service auth { unix_listener /var/spool/postfix/private/auth { group = postfix mode = 0666 user = postfix } } service auth-worker { } service dict { unix_listener dict { } } ssl_server { cert_file = /etc/letsencrypt/live/kostovsky.me/fullchain.pem dh_file = /etc/dovecot/dh.pem key_file = /etc/letsencrypt/live/kostovsky.me/privkey.pem }
Сервис
systemctl enable --now dovecot.service
Если вы используете ufw, загляните в оригинальный гайд, там есть дополнительные настройки и комментарии.
Инструментарий для тестирования
Postfix
https://wiki.archlinux.org/title/Postfix
Установка
pacman -S postfix
Каталоги
postconf -n | grep -E "directory\s"
Вывод:
command_directory = /usr/bin daemon_directory = /usr/lib/postfix/bin data_directory = /var/lib/postfix html_directory = no manpage_directory = /usr/share/man meta_directory = /etc/postfix queue_directory = /var/spool/postfix readme_directory = /usr/share/doc/postfix sample_directory = /etc/postfix shlib_directory = /usr/lib/postfix
Домен
postconf -n | grep ^my
Output:
mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain, mail.$mydomain mydomain = kostovsky.me myhostname = kostovsky.me myorigin = $mydomain
Aliases
postconf -n | grep -E "^alias|newaliases"
Вывод:
alias_database = $alias_maps alias_maps = lmdb:/etc/postfix/aliases newaliases_path = /usr/bin/newaliases
Catch-all email
«Всеперехватывающий»(?) адрес. Здесь автор оригинального гайда указал пользователя, который будет получать почту (в смысле спам), адресованную несуществующим в системе пользователям. У меня здесь пусто.
postconf -n luser_relay local_recipient_maps
Output:
local_recipient_maps =
Шифруемся с помощью TLS
Получение почты:
postconf -n | grep smtpd_ | grep tls
Вывод:
smtpd_sasl_tls_security_options = noanonymous smtpd_tls_auth_only = yes smtpd_tls_cert_file = /etc/letsencrypt/live/kostovsky.me/fullchain.pem smtpd_tls_key_file = /etc/letsencrypt/live/kostovsky.me/privkey.pem smtpd_use_tls = yes
Отправка почты:
postconf -n | grep smtp_ | grep tls
Вывод:
smtp_tls_security_level = may
Аутентификация/авторизация
Конфиг аутентификации postfix:
postconf -n | grep ^smtpd_sasl
Вывод:
smtpd_sasl_auth_enable = yes smtpd_sasl_local_domain = $mydomain smtpd_sasl_path = private/auth smtpd_sasl_security_options = noanonymous, noplaintext smtpd_sasl_tls_security_options = noanonymous smtpd_sasl_type = dovecot
Интеграция с аутентификацией dovecot
doveconf -n service/auth
Вывод:
service auth { unix_listener /var/spool/postfix/private/auth { group = postfix mode = 0666 user = postfix } }
Relay (шлюз?) и ограничения
postconf -n | grep -E "helo|relay"
Вывод:
smtpd_helo_required = yes smtpd_helo_restrictions = reject_invalid_helo_hostname, reject_non_fqdn_helo_hostname smtpd_relay_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination
Mail submission
Я не знаю, как и есть ли смысл переводить некоторые словосочетания, но перевод “mail submission” не так уж и необходим для настройки сервера.
postconf -M submission
Вывод:
submission inet n - n - - smtpd -o syslog_name=postfix/submission -o smtpd_tls_security_level=encrypt -o smtpd_sasl_auth_enable=yes -o smtpd_tls_auth_only=yes -o smtpd_reject_unlisted_recipient=no -o smtpd_relay_restrictions= -o smtpd_recipient_restrictions=permit_sasl_authenticated,reject -o milter_macro_daemon_name=ORIGINATING
DNS-запись TXT
drill -Q kostovsky.me TXT drill -Q smtp.kostovsky.me TXT
Вывод:
"v=spf1 a mx ip4:195.234.21.24 ~all" "v=spf1 a mx ip4:195.234.21.24 ~all"
Запись reverse DNS
drill -Q 195.234.21.24 -x
Вывод:
kostovsky.me.
Весь итоговый конфиг
Спрятал под спойлер
postconf -n
Вывод:
alias_database = $alias_maps alias_maps = lmdb:/etc/postfix/aliases command_directory = /usr/bin compatibility_level = 3.11 daemon_directory = /usr/lib/postfix/bin data_directory = /var/lib/postfix debug_peer_level = 2 debugger_command = PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin ddd $daemon_directory/$process_name $process_id & sleep 5 home_mailbox = Maildir/ html_directory = no inet_protocols = ipv4 local_recipient_maps = mail_owner = postfix mailbox_size_limit = 512000000 mailq_path = /usr/bin/mailq manpage_directory = /usr/share/man message_size_limit = 512000000 meta_directory = /etc/postfix milter_default_action = accept mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain, mail.$mydomain mydomain = kostovsky.me myhostname = kostovsky.me mynetworks = 10.66.66.0/24 myorigin = $mydomain newaliases_path = /usr/bin/newaliases non_smtpd_milters = $smtpd_milters queue_directory = /var/spool/postfix readme_directory = /usr/share/doc/postfix sample_directory = /etc/postfix sendmail_path = /usr/bin/sendmail setgid_group = postdrop shlib_directory = /usr/lib/postfix smtp_header_checks = regexp:/etc/postfix/smtp_header_checks smtp_tls_security_level = may smtpd_banner = exim smtpd_helo_required = yes smtpd_helo_restrictions = reject_invalid_helo_hostname, reject_non_fqdn_helo_hostname smtpd_milters = inet:localhost:8891, inet:localhost:8893 smtpd_relay_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination smtpd_sasl_auth_enable = yes smtpd_sasl_local_domain = $mydomain smtpd_sasl_path = private/auth smtpd_sasl_security_options = noanonymous, noplaintext smtpd_sasl_tls_security_options = noanonymous smtpd_sasl_type = dovecot smtpd_tls_auth_only = yes smtpd_tls_cert_file = /etc/letsencrypt/live/kostovsky.me/fullchain.pem smtpd_tls_key_file = /etc/letsencrypt/live/kostovsky.me/privkey.pem smtpd_use_tls = yes unknown_local_recipient_reject_code = 550
Сервис
systemctl enable --now postfix.service
Если вы используете ufw, загляните в оригинальный гайд, там есть настройки и комментарии.
Инструментарий для тестирования
https://check.spamhaus.org/results/?query=195.234.21.24 - hidden behind cloudflare
Особо упоротые могут быстренько проверить SMTP с помощью openssl:
openssl s_client -connect kostovsky.me:25 -starttls smtp
DomainKeys Identified Mail - DKIM
Установка
https://wiki.archlinux.org/title/OpenDKIM
pacman -S opendkim
Настройка
Минимальный конфиг
grep -v -e '^#' -e '^[[:space:]]*$' /etc/opendkim/opendkim.conf
Вывод:
Canonicalization relaxed/simple Domain kostovsky.me KeyFile /etc/opendkim/rig.private Selector rig Socket inet:8891@localhost Syslog Yes UserID opendkim:postfix
Генерация файлов ключей
Generate rig.private and rig.txt files.
opendkim-genkey --restrict --selector rig --domain kostovsky.me --directory /etc/opendkim
Интеграция с postfix
postconf -n | grep milter
Вывод:
milter_default_action = accept non_smtpd_milters = $smtpd_milters smtpd_milters = inet:localhost:8891, inet:localhost:8893
Общаться с postfix оно будет через сокет inet:localhost:8891.
DNS-запись TXT
cat /etc/opendkim/rig.txt
Вывод:
rig._domainkey IN TXT ( "v=DKIM1; k=rsa; s=email; " "p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDA8dfa8T7Hhn5/nWVivUpeBEs339fa9bCUHN7tqWxchzy5vBw/8Z3/9Pp8XIXo/0GnpOCu0Fh4P27tMnIdH5N4Sy3E/XcNHL7cRAB7gqKjEMuT2S49L7j3g19Dns7qN8rbArC7Krzq5mdHPHk1EqGsytGlv9CMD5gegpUsM7wd3QIDAQAB" ) ; ----- DKIM key rig for kostovsky.me
drill -Q rig._domainkey.kostovsky.me TXT
Вывод:
"v=DKIM1; k=rsa; s=email; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDA8dfa8T7Hhn5/nWVivUpeBEs339fa9bCUHN7tqWxchzy5vBw/8Z3/9Pp8XIXo/0GnpOCu0Fh4P27tMnIdH5N4Sy3E/XcNHL7cRAB7gqKjEMuT2S49L7j3g19Dns7qN8rbArC7Krzq5mdHPHk1EqGsytGlv9CMD5gegpUsM7wd3QIDAQAB"
Сервис
systemctl enable --now opendkim.service
Инструментарий для тестирования
https://dmarcian.com/dkim-inspector/ - вот, для примера, мой отчёт
Domain-based Message Authentication, Reporting and Conformance - DMARC
https://wiki.archlinux.org/title/OpenDMARC
Установка
pacman -S opendmarc
Настройка
Минимальный конфиг
grep -vE "^#|^\s*$" /etc/opendmarc/opendmarc.conf
Вывод:
AuthservID HOSTNAME IgnoreAuthenticatedClients true Socket inet:8893@localhost SPFSelfValidate true UMask 002
Интеграция с postfix
postconf -n | grep milter
Вывод:
milter_default_action = accept non_smtpd_milters = $smtpd_milters smtpd_milters = inet:localhost:8891, inet:localhost:8893
Общаться с postfix оно будет через сокет inet:localhost:8893.
DNS-запись TXT
drill -Q _dmarc.kostovsky.me TXT
Вывод:
"v=DMARC1; p=quarantine; rua=mailto:postmaster@kostovsky.me; ruf=mailto:forensic@kostovsky.me; adkim=s; aspf=s; fo=1; pct=25"
Сервис
systemctl enable --now opendmarc.service
Инструментарий для тестирования
Настройка Thunderbird
У меня весь гуй везде на английском, так что прошу извинить.
Outgoing server
“Account Settings”->“Edit outgoing server…”
Server Name: kostovsky.me
Port: 587
Connection security: STARTTLS
Authentication method: Normal password
User Name: nikita
Incoming server
“Server settings” section
Server Type: IMAP Mail Server
Server Name: kostovsky.me
Port: 993
User Name: nikita
Connection security: SSL/TLS
Authentication method: Normal password
Вот, вроде бы, всё и готово, но, пожалуйста, без резких движений. Шуруйте на mail-tester или подобный сервис и добивайтесь всех (значимых, содержимое письма не в счёт) зелёных галочек из всех, прежде чем отправить своё первое письмо на реальный внешний почтовый адрес.
Комментарии (11)

maxnoosphere
13.08.2026 14:27а как с доставляемостью писем с своего сервера? в крупные почтовые сервисы кладут в спам если нет нормальной репутации у домена?

naky Автор
13.08.2026 14:27Насколько я знаю, ни разу за ~4 года мои письма нигде не пропадали, то есть всё, что мне нужно, всегда доходило адресатам.
Возможно, что-то попадало кому-то в спам, но я о таком не слышал, да и кто мне будет отчитываться. По крайней мере, в гугловую почту моих знакомых всё нормально прилетает в Inbox, и на все нужные письма я всегда получал ответы.
Наличие своего домена в спам-листах можно проверить, например, здесь, а потом, в случае чего, нагуглить процедуру выхода из соответствующего спам-листа. Именно про репутацию ничего не скажу: даже как-то и не припомню, чтобы я её отдельно проверял, но spamhaus мне сейчас показывает
-1.5(нужно почистить лишние поддомены), mail-tester - все зелёные галочки, кроме двух замечаний: короткое содержимое тестового письма и отсутствие в нём ссылки для отписки от рассылки.Очень часто вижу мнения о том, что с личного сервера всё будет прилетать в спам, но то ли мне очень везёт, то ли это неправда: у меня уже третий IP после двух VPS (OVH и ещё один) и второй домен - ни единого разрыва. Я бы предложил не бояться и пробовать на себе, а на случай проблем с настройкой на гитхабе есть куча готовых решений с докер-образами для ленивых.

pr0l
13.08.2026 14:27как будто mailcow в докер контейнере сильно проще поднять.

naky Автор
13.08.2026 14:27Да, проще, и, возможно, работать оно будет лучше и безопаснее, именно mailcow у меня несколько знакомых и поднимали, но у меня особые тараканы:
чисто эстетически не люблю докер там, где можно обойтись без него: неприятно знать о лишнем оверхеде на личном сервере. Плюс поправить свои конфиги проще, чем адаптировать чужой докер-образ под себя (или очень разные докер-образы при наличии привычки держать каждый сервис в докере).
люблю управлять софтом через одно место - пакетный менеджер, пусть это даже будут кастомные PKGBUILD/ebuild-ы.
(одна из основных причин) спортивный интерес - поднять всё самому в наши дни, когда на каждом углу заявляют, что поднять свой почтовый сервер это сложно, почти невозможно: мол, нужно курить тонны мануалов и разбираться во всех протоколах на уровне разработчика. Оказывается, не так всё и сложно.
У докера есть свои плюсы вроде изоляции и низкого порога вхождения, но, например, от возни с DNS он вас не избавит, а это добрая половина работы по настройке, я бы сказал.
Так что описанный в статье вариант скорее для спартанцев или любознательных, а там на вкус и цвет.
xenon
К этому бы еще статью, как в 2026 сделать нормальный (и бесплатный) антиспам для входящей почты... Везде на больших почтовых провайдерах с этим уже все хорошо, но вот на своем бы научиться. Такое впечатление, что spamassassin, greylisting и DNSBL (и SURBL) - это вчерашний и позавчерашний день. Ясно сейчас как-то лучше можно. Хоть, блин, в нейронку кидай письма! :-)
max9
нет и никогда не было. бесплатный в контексте SA значит то, что вы его постоянно дообучаете и пишете правила руками, копаясь в спамерском говне
naky Автор
Мне кажется, без корпораций будет работать только распределённый подход вроде SponsorBlock. Недавно натыкался на некий Razor, но, к сожалению или к счастью, у меня никогда не было проблемы спама: 99% мусора режется отправкой в помойку всех писем с эмодзи в заголовке или в body, для чего достаточно простого regex-фильтра на клиенте, а у остального есть ссылка Unsubscribe. Если она редиректится через трекеры - достаточно прямого письма спамящей компании с просьбой прекратить (диких спамеров нынче не так много).
Если нужен одноразовый аккаунт, пользуюсь temp mail.
Иногда даже хочется, чтобы меня начали спамить, ведь тогда можно будет раскурить, наконец, системы фильтрации спама, но пока что всё довольно прозаично.
max9
неблагодарное занятие, поверьте