About us Guides Projects Contacts
Админка
please wait

Postfix is the most widely used Mail Transfer Agent (MTA) for Linux, handling outgoing email delivery with security and reliability. While full email hosting is complex, setting up Postfix for application email delivery is a common and essential task. This guide covers configuring Postfix for production use from a senior developer's perspective.

Why Postfix

Postfix offers significant advantages:

  1. Security: Designed with security as a priority
  2. Performance: Handles high email volumes efficiently
  3. Modular: Easy to integrate with spam filters and authentication
  4. Reliable: Battle-tested in production for decades
  5. Well-documented: Extensive documentation and community support

Installation

CentOS/RHEL

sudo dnf install postfix
sudo systemctl start postfix
sudo systemctl enable postfix

Ubuntu/Debian

sudo apt install postfix
# Select "Internet Site" during configuration
# Enter your domain name when prompted

Verify Installation

# Check status
sudo systemctl status postfix
# Check if listening
sudo netstat -tlnp | grep :25
# Send a test email
echo "Test email body" | mail -s "Test Subject" [email protected]

Basic Configuration

Main Configuration File

/etc/postfix/main.cf:

# Basic settings
myhostname = mail.example.com
mydomain = example.com
myorigin = $mydomain
# Network settings
inet_interfaces = all
inet_protocols = ipv4
# Trusted networks (localhost only for the sending server)
mynetworks = 127.0.0.0/8
# Destination domains
mydestination = $myhostname, localhost.$mydomain, localhost
# Relay settings (empty = no relay)
relayhost =
# Mailbox settings
home_mailbox = Maildir/
# Size limits
message_size_limit = 10485760 # 10 MB
mailbox_size_limit = 0 # Unlimited
# SMTP settings
smtpd_banner = $myhostname ESMTP
biff = no
append_dot_mydomain = no

Apply Changes

# Check configuration syntax
sudo postfix check
# Reload configuration
sudo postfix reload
# Or restart entirely
sudo systemctl restart postfix

TLS/SSL Encryption

Generate Certificates

Using Let's Encrypt (recommended):

sudo certbot certonly --standalone -d mail.example.com

Or self-signed for internal use:

sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout /etc/postfix/ssl/mail.key \
-out /etc/postfix/ssl/mail.crt \
-subj "/CN=mail.example.com"

Configure TLS

Add to /etc/postfix/main.cf:

# TLS settings
smtpd_tls_cert_file = /etc/letsencrypt/live/mail.example.com/fullchain.pem
smtpd_tls_key_file = /etc/letsencrypt/live/mail.example.com/privkey.pem
smtpd_tls_security_level = may
smtpd_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
# Outbound TLS
smtp_tls_security_level = may
smtp_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
smtp_tls_loglevel = 1

SMTP Authentication

Install SASL

# CentOS/RHEL
sudo dnf install cyrus-sasl cyrus-sasl-plain
# Ubuntu/Debian
sudo apt install libsasl2-modules sasl2-bin

Configure SASL

Create /etc/postfix/sasl/smtpd.conf:

pwcheck_method: saslauthd
mech_list: PLAIN LOGIN

Add to /etc/postfix/main.cf:

# SASL authentication
smtpd_sasl_auth_enable = yes
smtpd_sasl_security_options = noanonymous
smtpd_sasl_local_domain = $myhostname
smtpd_recipient_restrictions =
permit_sasl_authenticated,
permit_mynetworks,
reject_unauth_destination

Relay Through External SMTP

For better deliverability, relay through a trusted provider (SendGrid, Mailgun, AWS SES):

SendGrid Example

Add to /etc/postfix/main.cf:

relayhost = [smtp.sendgrid.net]:587
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_sasl_security_options = noanonymous
smtp_tls_security_level = encrypt

Create /etc/postfix/sasl_passwd:

[smtp.sendgrid.net]:587 apikey:your-sendgrid-api-key

Secure and hash:

sudo chmod 600 /etc/postfix/sasl_passwd
sudo postmap /etc/postfix/sasl_passwd
sudo systemctl restart postfix

AWS SES Example

relayhost = [email-smtp.us-east-1.amazonaws.com]:587
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_sasl_security_options = noanonymous
smtp_tls_security_level = encrypt
smtp_tls_CAfile = /etc/ssl/certs/ca-bundle.crt

SPF, DKIM, and DMARC

Essential for email deliverability:

SPF Record

Add a DNS TXT record:

example.com. TXT "v=spf1 mx ip4:YOUR_SERVER_IP include:_spf.google.com ~all"

DKIM with OpenDKIM

# Install
sudo dnf install opendkim opendkim-tools
# Generate keys
sudo opendkim-genkey -D /etc/opendkim/keys/example.com/ -d example.com -s mail
# Configure /etc/opendkim.conf
Domain example.com
Selector mail
KeyFile /etc/opendkim/keys/example.com/mail.private
Socket inet:8891@localhost
# Add to main.cf
milter_protocol = 6
milter_default_action = accept
smtpd_milters = inet:localhost:8891
non_smtpd_milters = inet:localhost:8891

Add a DNS TXT record:

mail._domainkey.example.com. TXT "v=DKIM1; k=rsa; p=<public-key-from-mail.txt>"

DMARC Record

Add a DNS TXT record:

_dmarc.example.com. TXT "v=DMARC1; p=quarantine; rua=mailto:[email protected]"

Docker Integration

Use Host Postfix from Container

In docker-compose.yml:

services:
app:
image: your-app
extra_hosts:
- "host.docker.internal:host-gateway"
environment:
MAIL_HOST: host.docker.internal
MAIL_PORT: 25

Postfix Container

services:
postfix:
image: boky/postfix
environment:
ALLOWED_SENDER_DOMAINS: example.com
RELAYHOST: "[smtp.sendgrid.net]:587"
RELAYHOST_USERNAME: apikey
RELAYHOST_PASSWORD: your-api-key
ports:
- "1025:587"

Application Integration

PHP (Laravel)

.env:

MAIL_MAILER=smtp
MAIL_HOST=localhost
MAIL_PORT=25
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
[email protected]
MAIL_FROM_NAME="${APP_NAME}"

Node.js (Nodemailer)

const nodemailer = require('nodemailer');
const transporter = nodemailer.createTransport({
host: 'localhost',
port: 25,
secure: false,
tls: {
rejectUnauthorized: false
}
});
async function sendEmail(to, subject, html) {
return transporter.sendMail({
from: '[email protected]',
to,
subject,
html
});
}

Python

import smtplib
from email.mime.text import MIMEText
def send_email(to, subject, body):
msg = MIMEText(body)
msg['Subject'] = subject
msg['From'] = '[email protected]'
msg['To'] = to
with smtplib.SMTP('localhost', 25) as server:
server.send_message(msg)

Monitoring and Logs

View Mail Queue

# Show queue
sudo postqueue -p
# Flush queue (retry all)
sudo postqueue -f
# Delete all queued mail
sudo postsuper -d ALL

View Logs

# CentOS/RHEL
sudo tail -f /var/log/maillog
# Ubuntu/Debian
sudo tail -f /var/log/mail.log
# Filter for errors
sudo grep -i error /var/log/maillog

Troubleshooting

Lock File Error

fatal: open lock file /var/lib/postfix/master.lock: unable to set exclusive lock

Solution:

sudo fuser /var/lib/postfix/master.lock
sudo kill <process_id>
sudo systemctl start postfix

Test Email Delivery

# Manual SMTP test
telnet localhost 25
EHLO localhost
MAIL FROM:<[email protected]>
RCPT TO:<[email protected]>
DATA
Subject: Test
Test message
.
QUIT

Check Email Headers

Use mail-tester.com to verify SPF, DKIM, and deliverability score.

Key Takeaways

  1. Start simple: Basic Postfix works for application email
  2. Use relays: SendGrid/SES for production deliverability
  3. TLS everywhere: Encrypt all connections
  4. SPF/DKIM/DMARC: Essential for inbox delivery
  5. Monitor queues: Check logs regularly
  6. Test thoroughly: Use mail-tester.com before going live

Postfix handles email delivery reliably—combine it with a reputable relay service for production applications that need guaranteed delivery.

 
 
 
Языки
Темы
Copyright © 1999 — 2026
ZK Interactive