Real-world Challenges when Deploying a Mail Server on Linux
Have you ever “broken a sweat” because a script sending notifications from your local app works perfectly, but once deployed to a CentOS Stream 9 server, the emails vanish into thin air? Even worse, the emails might be delivered but end up sitting prominently in the customer’s SPAM folder with a glaring red warning: “This email was not encrypted.”
Earlier this year, I took on a task to set up a monitoring system for a partner on CentOS Stream 9. Everything from Zabbix to Prometheus was running smoothly until I configured the alerts. I thought installing Postfix and firing off the systemctl start command would be enough, but reality was much harsher. Tech giants like Gmail and Outlook are extremely strict nowadays. If your server lacks TLS encryption or has misaligned DNS records, 99% of your emails will be rejected at the first gate.
Why are your emails being rejected by the ‘Tech Giants’?
After several sleepless nights scouring logs at /var/log/maillog, I’ve identified 4 common reasons why Mail Servers on CentOS Stream 9 get blocked:
- Outdated Plain Text Protocol: Sending mail without TLS encryption is like sending a public postcard. Google will flag it as a risk immediately.
- Weak SMTP Auth: A server that doesn’t require authentication can easily become an “Open Relay.” Hackers will exploit your IP to spam globally, landing you on a blacklist within hours.
- Firewalld and SELinux Barriers: CentOS Stream 9 is highly secure. Sometimes the service is running, but ports 25, 465, or 587 are blocked, or SELinux prevents Postfix from reading certificate files.
- Empty DNS Records: Missing key records like A, MX, and SPF is the leading reason why emails are flagged as fraudulent.
Which Deployment Method Should You Choose?
When faced with this problem, DevOps engineers usually consider 3 main paths:
- Using a Relay (SendGrid, Mailgun): Fast and high Inbox delivery rates, but it costs money. If you’re sending high volumes of system mail (around 50,000/month), the cost can be significant.
- Using a Mail Suite (iRedMail, Zimbra): Full-featured but extremely resource-heavy. On a VPS with 1-2GB of RAM, installing these is a nightmare for system performance.
- Pure Postfix: The “go-to choice” for technical enthusiasts. It’s lightweight, highly customizable, and gives you total control over the email flow.
Deploying Postfix with TLS on CentOS Stream 9
Here is the actual process I applied to build a mail system that scores 10/10 on Mail-Tester.
1. System Preparation
First, set a proper FQDN hostname. In this example, I’ll use mail.itfromzero.vn.
hostnamectl set-hostname mail.itfromzero.vn
echo "127.0.0.1 mail.itfromzero.vn" >> /etc/hosts
2. Install Postfix and SASL
Use dnf for the installation. I also install cyrus-sasl for smoother user authentication handling.
dnf update -y
dnf install postfix cyrus-sasl cyrus-sasl-plain mailx -y
3. Optimize main.cf
Instead of using the long default file, back it up and focus on the core parameters. This configuration is minimal yet highly effective:
cp /etc/postfix/main.cf /etc/postfix/main.cf.bak
vi /etc/postfix/main.cf
Update the following lines to define your server’s identity:
myhostname = mail.itfromzero.vn
mydomain = itfromzero.vn
myorigin = $mydomain
inet_interfaces = all
inet_protocols = ipv4
mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain
home_mailbox = Maildir/
4. Enable TLS Security
Encryption is mandatory if you want to avoid the spam folder. A certificate from Let’s Encrypt is ideal. Note: Ensure the postfix user has permission to read the directory containing your keys.
# TLS configuration for enhanced security
smtpd_use_tls = yes
smtpd_tls_cert_file = /etc/pki/tls/certs/postfix.pem
smtpd_tls_key_file = /etc/pki/tls/private/postfix.key
smtpd_tls_security_level = may
smtp_tls_security_level = may
smtp_tls_loglevel = 1
5. Open Firewall Ports and Configure SELinux
This step is critical. If you forget to open the ports, mail will be stuck in the queue forever.
firewall-cmd --permanent --add-service=smtp
firewall-cmd --permanent --add-port={587,465}/tcp
firewall-cmd --reload
For SELinux, if you store certificates in a custom directory, you need to assign the correct label:
setsebool -P postfix_local_write_mail_spool on
chcon -t cert_t /path/to/your/cert.pem
6. Start and Verify the Results
Enable the service and check if port 25 is “listening” using the netstat command.
systemctl enable --now postfix
netstat -plnt | grep :25
Try sending a test email to see the results:
echo "TLS test content from CentOS 9" | mail -s "Postfix Test" [email protected]
Hard-earned Operational Lessons
During a system migration from CentOS 8 to CentOS Stream 9 for a client, I learned a painful lesson about Reverse DNS (PTR Record). No matter how perfect your Postfix configuration is, if your server IP doesn’t point back correctly to your domain mail.itfromzero.vn, Gmail will still flatly reject your emails.
A quick tip: always keep a terminal window running tail -f /var/log/maillog while debugging. Any authentication or connection errors will show up clearly there. Don’t rely on guesswork; let the logs guide you.
Hopefully, these insights help you feel more confident when setting up a Mail Server on modern Linux distributions. If you run into any stubborn bugs, feel free to leave a comment below!

