O Postfix é o Mail Transfer Agent (MTA) mais utilizado em Linux, tratando da entrega de e-mail de saída com segurança e fiabilidade. Embora o alojamento completo de e-mail seja complexo, configurar o Postfix para entrega de e-mail de aplicações é uma tarefa comum e essencial. Este guia aborda a configuração do Postfix para utilização em produção, na perspetiva de um programador sénior.
Porquê o Postfix
O Postfix oferece vantagens significativas:
- Segurança: Concebido com a segurança como prioridade
- Desempenho: Lida eficientemente com volumes elevados de e-mail
- Modular: Fácil de integrar com filtros de spam, autenticação
- Fiável: Testado em produção ao longo de décadas
- Bem documentado: Documentação extensa e suporte da comunidade
Instalação
CentOS/RHEL
sudo dnf install postfix
sudo systemctl start postfix
sudo systemctl enable postfix
Ubuntu/Debian
sudo apt install postfix
# Selecione «Internet Site» durante a configuração
# Introduza o seu nome de domínio quando solicitado
Verificar a instalação
# Verificar o estado
sudo systemctl status postfix
# Verificar se está a escutar
sudo netstat -tlnp | grep :25
# Enviar e-mail de teste
echo "Test email body" | mail -s "Test Subject" [email protected]
Configuração básica
Ficheiro de configuração principal
/etc/postfix/main.cf:
# Definições básicas
myhostname = mail.example.com
mydomain = example.com
myorigin = $mydomain
# Definições de rede
inet_interfaces = all
inet_protocols = ipv4
# Redes de confiança (apenas localhost para o servidor de envio)
mynetworks = 127.0.0.0/8
# Domínios de destino
mydestination = $myhostname, localhost.$mydomain, localhost
# Definições de relay (vazio = sem relay)
relayhost =
# Definições de mailbox
home_mailbox = Maildir/
# Limites de tamanho
message_size_limit = 10485760 # 10 MB
mailbox_size_limit = 0 # Ilimitado
# Definições de SMTP
smtpd_banner = $myhostname ESMTP
biff = no
append_dot_mydomain = no
Aplicar alterações
# Verificar a sintaxe da configuração
sudo postfix check
# Recarregar a configuração
sudo postfix reload
# Ou reiniciar por completo
sudo systemctl restart postfix
Encriptação TLS/SSL
Gerar certificados
Com Let's Encrypt (recomendado):
sudo certbot certonly --standalone -d mail.example.com
Ou autoassinado para utilização interna:
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"
Configurar TLS
Adicionar a /etc/postfix/main.cf:
# Definições de TLS
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
# TLS de saída
smtp_tls_security_level = may
smtp_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
smtp_tls_loglevel = 1
Autenticação SMTP
Instalar SASL
# CentOS/RHEL
sudo dnf install cyrus-sasl cyrus-sasl-plain
# Ubuntu/Debian
sudo apt install libsasl2-modules sasl2-bin
Configurar SASL
Criar /etc/postfix/sasl/smtpd.conf:
pwcheck_method: saslauthd
mech_list: PLAIN LOGIN
Adicionar a /etc/postfix/main.cf:
# Autenticação SASL
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 através de SMTP externo
Para melhor capacidade de entrega, faça relay através de um fornecedor de confiança (SendGrid, Mailgun, AWS SES):
Exemplo SendGrid
Adicionar a /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
Criar /etc/postfix/sasl_passwd:
[smtp.sendgrid.net]:587 apikey:your-sendgrid-api-key
Proteger e gerar hash:
sudo chmod 600 /etc/postfix/sasl_passwd
sudo postmap /etc/postfix/sasl_passwd
sudo systemctl restart postfix
Exemplo AWS SES
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 e DMARC
Essenciais para a capacidade de entrega de e-mail:
Registo SPF
Adicionar registo DNS TXT:
example.com. TXT "v=spf1 mx ip4:YOUR_SERVER_IP include:_spf.google.com ~all"
DKIM com OpenDKIM
# Instalar
sudo dnf install opendkim opendkim-tools
# Gerar chaves
sudo opendkim-genkey -D /etc/opendkim/keys/example.com/ -d example.com -s mail
# Configurar /etc/opendkim.conf
Domain example.com
Selector mail
KeyFile /etc/opendkim/keys/example.com/mail.private
Socket inet:8891@localhost
# Adicionar ao main.cf
milter_protocol = 6
milter_default_action = accept
smtpd_milters = inet:localhost:8891
non_smtpd_milters = inet:localhost:8891
Adicionar registo DNS TXT:
mail._domainkey.example.com. TXT "v=DKIM1; k=rsa; p=<public-key-from-mail.txt>"
Registo DMARC
Adicionar registo DNS TXT:
_dmarc.example.com. TXT "v=DMARC1; p=quarantine; rua=mailto:[email protected]"
Integração com Docker
Utilizar o Postfix do host a partir do contentor
Em docker-compose.yml:
services:
app:
image: your-app
extra_hosts:
- "host.docker.internal:host-gateway"
environment:
MAIL_HOST: host.docker.internal
MAIL_PORT: 25
Contentor Postfix
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"
Integração com a aplicação
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)
Monitorização e logs
Ver a fila de correio
# Mostrar a fila
sudo postqueue -p
# Esvaziar a fila (tentar novamente todos)
sudo postqueue -f
# Eliminar todo o correio em fila
sudo postsuper -d ALL
Ver logs
# CentOS/RHEL
sudo tail -f /var/log/maillog
# Ubuntu/Debian
sudo tail -f /var/log/mail.log
# Filtrar por erros
sudo grep -i error /var/log/maillog
Resolução de problemas
Erro de ficheiro de bloqueio
fatal: open lock file /var/lib/postfix/master.lock: unable to set exclusive lock
Solução:
sudo fuser /var/lib/postfix/master.lock
sudo kill <process_id>
sudo systemctl start postfix
Testar a entrega de e-mail
# Teste SMTP manual
telnet localhost 25
EHLO localhost
MAIL FROM:<[email protected]>
RCPT TO:<[email protected]>
DATA
Subject: Test
Test message
.
QUIT
Verificar cabeçalhos de e-mail
Utilize o mail-tester.com para verificar SPF, DKIM e a pontuação de capacidade de entrega.
Principais conclusões
- Comece de forma simples: O Postfix básico funciona para e-mail de aplicações
- Use relays: SendGrid/SES para capacidade de entrega em produção
- TLS em todo o lado: Encripte todas as ligações
- SPF/DKIM/DMARC: Essenciais para a entrega na caixa de entrada
- Monitorize as filas: Verifique os logs regularmente
- Teste exaustivamente: Use o mail-tester.com antes de entrar em produção
O Postfix trata a entrega de e-mail de forma fiável — combine-o com um serviço de relay reputado para aplicações em produção que necessitam de entrega garantida.