Introduction
Set up a production-ready self-hosted email server with Postfix, Dovecot, anti-spam, DKIM/SPF/DMARC, and webmail. This comprehensive guide covers everything from design through implementation, testing, and deployment.
Set up a production-ready self-hosted email server with Postfix, Dovecot, anti-spam, DKIM/SPF/DMARC, and webmail.
Set up a production-ready self-hosted email server with Postfix, Dovecot, anti-spam, DKIM/SPF/DMARC, and webmail. This comprehensive guide covers everything from design through implementation, testing, and deployment.
Before sending any mail: set all DNS records. MX record: @ IN MX 10 mail.catb.in (points to your server). A record: mail.catb.in → your_server_ip. PTR record (reverse DNS): ask VPS provider to set IP → mail.catb.in. SPF TXT record: v=spf1 mx a ~all. DKIM: generate keys with OpenDKIM, add TXT record at selector._domainkey.catb.in. DMARC TXT record: _dmarc.catb.in v=DMARC1; p=reject; rua=mailto:dmarc@catb.in. Without these records, your email will be marked as spam or rejected.
10 components required for this project.
| # | Component | Purpose | Qty |
|---|---|---|---|
| 1 | VPS (Ubuntu 22.04, static IP, reverse DNS) | Email server host | x1 |
| 2 | Domain name (catb.in) | Email domain | x1 |
| 3 | Postfix MTA | Mail Transfer Agent (sending/receiving) | x1 |
| 4 | Dovecot IMAP server | Mail delivery and IMAP/POP3 | x1 |
| 5 | SpamAssassin | Spam filtering | x1 |
| 6 | ClamAV | Email virus scanning | x1 |
| 7 | OpenDKIM | DKIM email signing | x1 |
| 8 | Roundcube Webmail | Browser-based email client | x1 |
| 9 | Rspamd (alternative spam filter) | Modern, faster spam filter | x1 |
| 10 | MailHog (testing) | Email testing without sending real mail | x1 |
Follow these 3 steps carefully.
Before sending any mail: set all DNS records. MX record: @ IN MX 10 mail.catb.in (points to your server). A record: mail.catb.in → your_server_ip. PTR record (reverse DNS): ask VPS provider to set IP → mail.catb.in. SPF TXT record: v=spf1 mx a ~all. DKIM: generate keys with OpenDKIM, add TXT record at selector._domainkey.catb.in. DMARC TXT record: _dmarc.catb.in v=DMARC1; p=reject; rua=mailto:dmarc@catb.in. Without these records, your email will be marked as spam or rejected.
Postfix (MTA): handles sending and receiving SMTP. Configure main.cf: myhostname=mail.catb.in, mydomain=catb.in, mynetworks=127.0.0.1 (only allow local relay), smtpd_tls_cert_file=Let's Encrypt cert (TLS required), smtpd_sasl_auth_enable=yes (SMTP authentication with Dovecot SASL). Dovecot (MDA): handles IMAP/POP3, delivers mail to mailboxes. Configure mail_location, ssl_cert/key, auth mechanisms (PLAIN over TLS only), userdb/passdb (system users or MySQL).
Rspamd: modern spam filter with machine learning. Actions: reject (very high spam score), add spam header (medium score), accept (low score). DKIM signing: all outbound mail signed with private key — recipients can verify authenticity. SPF: receiving servers check if your IP is authorized to send for your domain. DMARC: tells receivers what to do if SPF/DKIM fail (reject/quarantine/none) and where to send aggregate reports. Check score on mail-tester.com (aim for 10/10).
Core code for email_server_test.sh:
#!/bin/bash # Email server configuration verification DOMAIN="catb.in" MAIL_HOST="mail.catb.in" echo "=== DNS Records Check ===" echo "MX record:" ; dig $DOMAIN MX +short echo "SPF record:" ; dig $DOMAIN TXT +short | grep spf echo "DMARC record:" ; dig _dmarc.$DOMAIN TXT +short echo "PTR record:" ; dig -x $(dig $MAIL_HOST A +short | head -1) +short echo "\\n=== Port Checks ===" nc -zv $MAIL_HOST 25 2>&1 | grep -c "succeeded" && echo "SMTP (25): OPEN" || echo "SMTP (25): CLOSED" nc -zv $MAIL_HOST 587 2>&1 | grep -c "succeeded" && echo "SUBMISSION (587): OPEN" nc -zv $MAIL_HOST 993 2>&1 | grep -c "succeeded" && echo "IMAPS (993): OPEN" echo "\\n=== TLS Certificate ===" echo | openssl s_client -connect $MAIL_HOST:993 2>/dev/null | openssl x509 -noout -dates echo "\\n=== Test SMTP Connection ===" telnet $MAIL_HOST 25
Test Self-Hosted Email Server by verifying each subsystem individually before full integration.
Verify power voltages, check ground connections, use serial monitor for debug.
An interactive simulator will be available here — simulate circuits and run code in-browser without hardware.