You pointed your MX records to Fedora and nothing arrived
You update your domain MX records to point at a fresh Fedora server and expect mail to flow. Instead, the connection drops at port 25, or messages bounce with a relay denied error. You installed Postfix and Dovecot, but the defaults are locked down tight. That is by design. Fedora ships mail servers in a neutral state so they do not accidentally become open relays on the internet.
What is actually happening
Postfix is the mail transfer agent. It accepts incoming messages, routes them, and hands them off to a local delivery agent. Dovecot is the IMAP and POP3 server. It stores the messages and lets clients like Thunderbird or Outlook pull them down. The two services talk to each other through a local socket or port 25. If either side is misconfigured, mail stops moving. Think of Postfix as the postal truck and Dovecot as the mailbox. The truck delivers, the mailbox holds. Both need to be unlocked and pointed at the same address.
Fedora does not enable network listening by default. It binds to localhost only. It also leaves TLS certificates unset and disables plaintext authentication over unencrypted connections. You need to adjust those defaults, open the firewall, and tell SELinux to allow the services to read and write mail spools.
The fix
Start with the packages. Fedora includes both in the default repositories. Run the install command and enable the services immediately.
sudo dnf install postfix dovecot dovecot-imapd -y
# WHY: pulls the MTA, the IMAP server, and the core IMAP protocol module
sudo systemctl enable --now postfix dovecot
# WHY: starts both services now and registers them to boot automatically
Configure Postfix next. Edit /etc/postfix/main.cf. Never edit files in /usr/lib/postfix/. Those ship with the package and get overwritten on updates. Always modify /etc/ copies.
# /etc/postfix/main.cf
inet_interfaces = all
# WHY: tells Postfix to listen on every network interface instead of localhost only
inet_protocols = ipv4
# WHY: restricts to IPv4 unless you explicitly need IPv6 routing
mydestination = $myhostname, localhost.$mydomain, localhost
# WHY: defines which domains this server considers local for delivery
smtpd_tls_cert_file = /etc/pki/tls/certs/postfix.pem
# WHY: points to your TLS certificate for encrypted SMTP sessions
smtpd_tls_key_file = /etc/pki/tls/private/postfix.key
# WHY: points to the matching private key for the certificate
smtpd_tls_security_level = may
# WHY: allows clients to upgrade to TLS but does not force it on legacy software
Reload Postfix after saving. The service reads the configuration file on reload, not on restart.
sudo postfix reload
# WHY: applies main.cf changes without dropping active connections
Configure Dovecot. Edit /etc/dovecot/dovecot.conf. Change the listener directive to match your network setup.
# /etc/dovecot/dovecot.conf
protocols = imap
# WHY: disables POP3 and LMTP unless you explicitly need them
listen = *, ::
# WHY: binds Dovecot to all IPv4 and IPv6 interfaces
ssl = required
# WHY: forces encrypted connections for all IMAP sessions
ssl_cert = </etc/pki/dovecot/certs/dovecot.pem
# WHY: loads the certificate file for TLS handshakes
ssl_key = </etc/pki/dovecot/private/dovecot.key
# WHY: loads the private key that matches the certificate
Authentication needs a separate tweak. Edit /etc/dovecot/conf.d/10-auth.conf.
# /etc/dovecot/conf.d/10-auth.conf
disable_plaintext_auth = yes
# WHY: blocks username/password transmission over unencrypted connections
auth_mechanisms = plain login
# WHY: enables standard IMAP authentication methods clients expect
Open the firewall. Fedora uses firewalld by default. Add the services and reload the runtime configuration.
sudo firewall-cmd --permanent --add-service=smtp
# WHY: allows incoming port 25 for standard mail delivery
sudo firewall-cmd --permanent --add-service=smtps
# WHY: allows incoming port 465 for implicit TLS submission
sudo firewall-cmd --permanent --add-service=imaps
# WHY: allows incoming port 993 for encrypted IMAP retrieval
sudo firewall-cmd --reload
# WHY: applies the persistent rules to the active firewall immediately
Handle SELinux. Fedora enforces mandatory access control. Dovecot needs permission to read user mail directories.
sudo setsebool -P dovecot_read_mail 1
# WHY: grants Dovecot persistent access to read mail spools under /var/mail
sudo restorecon -Rv /var/mail
# WHY: resets file contexts to match the expected SELinux policy
Restart Dovecot to pick up the new configuration and SELinux context.
sudo systemctl restart dovecot
# WHY: reloads all conf.d files and reinitializes the IMAP listener
Run journalctl -xeu dovecot.service to verify the service started cleanly. The x flag adds explanatory text and the e flag jumps to the end. Most sysadmins type that combination muscle-memory style.
Check the system before you debug. Half the time the symptom is gone after a clean restart.
Verify it worked
Test SMTP delivery first. Use swaks for a reliable command-line test.
sudo dnf install swaks -y
# WHY: provides a lightweight SMTP testing tool with verbose output
swaks --to user@yourdomain.com --server localhost --port 25
# WHY: sends a test message to localhost and prints the full transaction log
Test IMAP authentication next. Dovecot ships a built-in diagnostic command.
doveadm auth test user@yourdomain.com password123
# WHY: validates credentials against the configured auth mechanisms without network traffic
Check the mail log for routing decisions.
journalctl -xeu postfix.service | grep -i "status=sent"
# WHY: filters the journal for successful delivery confirmations
If the test message arrives in the local mailbox and the auth test returns OK, your stack is operational.
Run journalctl -xe first. Read the actual error before guessing.
Common pitfalls and what the error looks like
SELinux blocks Dovecot from reading mail spools. You see dovecot: imap-login: Disconnected (auth failed, 1 attempts) in the logs. The denial shows up in journalctl -t setroubleshoot with a one-line summary. Read those before disabling SELinux. Run sudo setsebool -P dovecot_read_mail 1 and restorecon to fix it.
The firewall drops port 993. Your IMAP client hangs on connection. Run sudo firewall-cmd --list-all to verify the imaps service is active. Reload the firewall after every rule change. Otherwise the runtime config and the persistent config diverge.
Postfix refuses relay with 554 5.7.1 <user>: Relay access denied. This happens when mynetworks does not include the client IP or when relay_domains is empty. Add the trusted network to mynetworks in main.cf and reload Postfix.
Mismatched TLS certificates cause SSL handshake failed or certificate verify failed. Ensure the certificate and key paths in both Postfix and Dovecot point to valid files. Check expiration with openssl x509 -in /etc/pki/tls/certs/postfix.pem -noout -dates.
Snapshot the system before the upgrade. Future-you will thank you.
When to use this versus alternatives
Use Postfix and Dovecot when you need full control over mail routing, local delivery, and IMAP storage. Use a cloud provider when you want to avoid managing SPF, DKIM, and DMARC records yourself. Use OpenSMTPD when you prefer a simpler configuration syntax and do not need Dovecot's plugin ecosystem. Stay on the default Postfix stack when you are running a standard Linux server and want the widest community support.
Trust the package manager. Manual file edits drift, snapshots stay.