Własny serwer mailowy: Postfix + Dovecot + SPF/DKIM/DMARC na Debianie 12
Pełny tutorial postawienia własnego serwera mailowego na Debian 12 z Postfix, Dovecot, OpenDKIM, SPF i DMARC. Konfiguracja krok po kroku, troubleshoot, realne pułapki.
Własny serwer mailowy to dziś rzadkość. Google Workspace i Microsoft 365 są tanie i bezpieczne — dla 90% ludzi to lepszy wybór. Ale są sytuacje, gdy własny serwer ma sens: regulacje RODO, custom integracje, duża skala. Ten post to kompletny tutorial, z którym postawisz serwer w 4-6h.
Wymagania wstępne
- Serwer Debian 12 (lub Ubuntu 24.04) z publicznym IPv4
- Domena ze skonfigurowanym NS (własny nameserver lub zarządzany)
- Reverse DNS (PTR) — musisz mieć możliwość jego ustawienia (DigitalOcean, Hetzner, OVH — tak; tani hosting — często nie)
- Otwarte porty: 25 (SMTP), 587 (submission), 993 (IMAPS)
PTR record to krytyczna sprawa. Bez niego Twoje maile trafiają do spamu. Sprawdź zanim zaczniesz:
# Sprawdź reverse DNSdig -x 1.2.3.4 +short# Powinno zwrócić np. "mail.example.com"Jeśli zwraca coś innego (np. “static.1-2-3-4.provider.com”) — napisz do supportu providera i poproś o zmianę PTR.
Instalacja pakietów
sudo apt updatesudo apt install postfix postfix-policyd-spf-python \ dovecot-core dovecot-imapd dovecot-lmtpd \ opendkim opendkim-tools \ certbotPodczas instalacji Postfix zapyta o:
- General type: Internet Site
- System mail name: example.com (twoja domena)
Konfiguracja Postfix
main.cf
Edytuj /etc/postfix/main.cf:
smtpd_banner = $myhostname ESMTP $mail_namebiff = noappend_dot_mydomain = noreadme_directory = no
# Hostname i domenamyhostname = mail.example.commydomain = example.commyorigin = $mydomainmydestination = $myhostname, localhost.$mydomain, localhost, $mydomain
# Siećmynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128inet_interfaces = allinet_protocols = ipv4
# SASL (dla klientów pocztowych)smtpd_sasl_type = dovecotsmtpd_sasl_path = private/authsmtpd_sasl_auth_enable = yessmtpd_sasl_security_options = noanonymoussmtpd_sasl_local_domain = $myhostname
# TLS (szyfrowanie)smtpd_tls_cert_file = /etc/letsencrypt/live/mail.example.com/fullchain.pemsmtpd_tls_key_file = /etc/letsencrypt/live/mail.example.com/privkey.pemsmtpd_tls_security_level = encryptsmtpd_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1smtpd_tls_ciphers = highsmtpd_tls_exclude_ciphers = aNULL, eNULL, EXPORT, DES, RC4, MD5, PSK, SRP, DSS, AECDH, ADH
# Ograniczenia antyspamowesmtpd_helo_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_invalid_helo_hostname, reject_non_fqdn_helo_hostnamesmtpd_sender_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_non_fqdn_sender, reject_unknown_sender_domainsmtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_non_fqdn_recipient, reject_unknown_recipient_domain, reject_unauth_destination, check_policy_service unix:private/policyd-spf
# Relay restrictions (krytyczne - chroni przed open relay)smtpd_relay_restrictions = permit_mynetworks, permit_sasl_authenticated, defer_unauth_destination
# Aliasalias_maps = hash:/etc/aliasesalias_database = hash:/etc/aliasesvirtual_mailbox_maps = hash:/etc/postfix/virtualvirtual_mailbox_domains = example.comvirtual_transport = lmtp:unix:private/dovecot-lmtpKluczowe ustawienia, które robią różnicę:
-
smtpd_relay_restrictionszdefer_unauth_destination— chroni przed open relay. NIGDY nie usuwaj tego. Testuj konfigurację na https://www.mail-tester.com. -
smtpd_tls_protocolsz wykluczeniem starych TLS — bez tego serwer akceptuje SSLv3 (podatny na POODLE). Wykluczenie!TLSv1.1i starszych = bezpieczeństwo. -
check_policy_service unix:private/policyd-spf— włącza sprawdzanie SPF (o tym za chwilę).
master.cf
Dodaj do /etc/postfix/master.cf (na końcu):
# Dovecot SASLsubmission 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
# PolicyD SPFpolicyd-spf unix - n n - 0 spawn user=policyd-spf argv=/usr/bin/policyd-spfWeryfikacja Postfix
# Sprawdź składnięsudo postfix check
# Przeładuj konfiguracjęsudo systemctl reload postfix
# Sprawdź statussudo systemctl status postfixKonfiguracja Dovecot
/etc/dovecot/dovecot.conf
protocols = imap lmtplisten = *, ::/etc/dovecot/conf.d/10-mail.conf
mail_location = maildir:~/Maildirmail_privileged_group = mail/etc/dovecot/conf.d/10-auth.conf
disable_plaintext_auth = yesauth_mechanisms = plain login/etc/dovecot/conf.d/10-master.conf
service auth { unix_listener /var/spool/postfix/private/auth { mode = 0660 user = postfix group = postfix }}
service lmtp { unix_listener /var/spool/postfix/private/dovecot-lmtp { mode = 0600 user = postfix group = postfix }}Tworzenie użytkownika
# Użytkownik systemowy (bez /bin/sh dla bezpieczeństwa)sudo useradd -m -s /usr/sbin/nologin jansudo passwd janHasło to zarazem hasło do IMAP/SMTP. Dla większego bezpieczeństwa użyj virtual users (patrz: dalsza rozbudowa), ale to poza zakresem tego tutoriala.
Konfiguracja OpenDKIM
DKIM podpisuje każdą wiadomość kryptograficznie. Bez niego Gmail i inni traktują Cię podejrzliwie.
Generowanie kluczy
sudo mkdir -p /etc/opendkim/keys/example.comcd /etc/opendkim/keys/example.comsudo opendkim-genkey -s default -d example.comsudo chown opendkim:opendkim default.private default.txt/etc/opendkim.conf
Domain example.comKeyFile /etc/opendkim/keys/example.com/default.privateSelector default
# StandardCanonicalization relaxed/simpleMode svSubDomains noAutoRestart yesAutoRestartRate 10/1MBackground yesDNSTimeout 5UserID opendkim:opendkim
# SocketSocket inet:12301@localhost/etc/default/opendkim
SOCKET="inet:12301@localhost"Dodanie do Postfix
W /etc/postfix/main.cf dodaj:
milter_protocol = 2milter_default_action = acceptsmtpd_milters = inet:localhost:12301non_smtpd_milters = inet:localhost:12301Restart i test
sudo systemctl restart opendkimsudo systemctl restart postfixDNS Records
Dodaj następujące rekordy w DNS domeny:
A record dla mail.example.com
mail.example.com. 3600 A 1.2.3.4MX record
example.com. 3600 MX 10 mail.example.com.SPF record (TXT)
example.com. 3600 TXT "v=spf1 mx ~all"~all oznacza soft fail — maile z innych serwerów są podejrzane, ale
nie odrzucane. Bezpieczniejsze niż -all na początku.
DKIM record (TXT)
Pobierz klucz publiczny:
sudo cat /etc/opendkim/keys/example.com/default.txtDodaj do DNS:
default._domainkey.example.com. 3600 TXT "v=DKIM1; k=rsa; p=MIGfMA0GCSq..."DMARC record (TXT)
_dmarc.example.com. 3600 TXT "v=DMARC1; p=quarantine; rua=mailto:dmarc@example.com; pct=100"p=quarantine oznacza: jeśli SPF+DKIM fail, mail trafia do spamu.
rua= to adres do raportów (kto próbuje podszywać się pod Twoją
domenę).
SSL/TLS z Let’s Encrypt
# Stop Postfix/Dovecot temporarily (potrzebny port 80)sudo systemctl stop postfix dovecot
# Pobierz certsudo certbot certonly --standalone -d mail.example.com
# Start usługisudo systemctl start postfix dovecot
# Test auto-renewalsudo certbot renew --dry-runCertbot automatycznie odnowi certyfikat (skrypt w /etc/cron.d/certbot).
Postfix i Dovecot automatycznie użyją nowego certyfikatu po restarcie
— warto dodać do crona:
0 3 1 * * /usr/bin/systemctl reload postfix dovecotTestowanie
1. mail-tester.com
Wyślij maila z jan@example.com na adres podany na mail-tester.com.
Powinien dostać 9+/10. Jeśli <7 — masz coś źle.
2. Wysyłka na Gmail
Wyślij maila na swoje konto Gmail. Sprawdź Show original — powinny być:
SPF: PASSDKIM: PASSDMARC: PASS
3. Wysyłka na własny adres
# Sprawdź czy mail dochodzi lokalnieecho "Test" | mail -s "Test" jan@example.commailq # kolejkasudo tail -f /var/log/mail.log # logi4. Test TLS
# Sprawdź czy submission używa TLSopenssl s_client -connect mail.example.com:587 -starttls smtpTroubleshooting
Mail nie dochodzi, logi: “relay denied”
smtpd_relay_restrictions nie pozwala. Sprawdź czy klient się
autoryzuje (SASL).
SPF=neutral mimo rekordu
Częsty błąd: PTR wskazuje na 1-2-3-4.provider.com zamiast
mail.example.com. Bez prawidłowego reverse DNS SPF nie przejdzie.
DKIM=FAIL
Klucz publiczny w DNS nie zgadza się z prywatnym. Sprawdź:
# Lokalny kluczsudo cat /etc/opendkim/keys/example.com/default.private | head -1
# DNSdig TXT default._domainkey.example.com +shortMaile trafiają do spamu mimo 10/10 na mail-tester
Dwa powody:
- Nowa domena — Gmail/Outlook traktują nowe domeny podejrzanie przez pierwsze 2-4 tygodnie. Rozwiązanie: wysyłaj regularnie prawidłowe maile, “rozgrzej” domenę.
- Treść maila — za dużo linków, brak tekstu alternatywnego, capital letters w subject. Popraw treść.
Hardening produkcyjny
-
Fail2ban — automatyczny ban IP po 3 nieudanych próbach logowania:
Terminal window sudo apt install fail2bansudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local# Włącz jail dla postfix i dovecotsudo systemctl enable --now fail2ban -
Postscreen — Postfix ma wbudowany anti-spam. Dodaj do master.cf:
smtpd pass - - - - - smtpd-o smtpd_proxy_filter=127.0.0.1:10025 -
Monitoring — Prometheus + Grafana + node_exporter dla metryk systemowych, sprawdzanie kolejki Postfix cronem.
-
Backup konfiguracji —
/etc/postfix/,/etc/dovecot/,/etc/opendkim/. Bez tego po awarii odtwarzanie zajmuje 6h.
Co dalej
Jeśli potrzebujesz postawienia serwera mailowego w polskiej chmurze (DigitalOcean, Hetzner) z pełną konfiguracją SPF/DKIM/DMARC i monitoringiem — napisz do mnie. Robota na 1-2 dni, koszt od 1500 PLN.
Najczęściej zadawane pytania
Czy warto stawiać własny serwer mailowy w 2025?
Dlaczego mój mail trafia do spamu mimo poprawnej konfiguracji?
Czy potrzebuję IPv6 dla serwera mailowego?
Jak zabezpieczyć Postfix przed open relay?
Powiązane posty
- linux
BTRFS + snapshoty na Arch Linux / CachyOS: poradnik krok po kroku
Pełny tutorial konfiguracji BTRFS z subvolume @ i @home, snapshotami Timeshift i Snapper, kompresją zstd. Dla Arch Linux, CachyOS i Manjaro. Działające komendy.
5 min - devops
Cloudflare dla WordPressa: pełna optymalizacja wydajności i bezpieczeństwa
Jak skonfigurować Cloudflare (Free/Pro) dla WordPressa krok po kroku: cache, APO, WAF, Bot Fight Mode, page rules, CDN. Realne wyniki pomiarów i konfiguracja dla Polski.
7 min