NOTA: Este artigo apresenta uma alternativa ao envio autenticado direto pela aplicação com PHPMailer. Nesta abordagem, a autenticação SMTP é centralizada no Postfix do servidor, permitindo que aplicações que utilizam mail() enviem e-mails por um relay autenticado sem alterações no código.
Objetivo
Configurar o Postfix local como relay SMTP autenticado para aplicações PHP, como WordPress, que usam a função mail().
Fluxo:
WordPress / aplicação PHP
↓ mail()
/usr/sbin/sendmail
↓
Postfix local
↓ SMTP autenticado + TLS
Relay SMTP externo
Este procedimento é para envio de e-mails por aplicações locais. Não configura um servidor para receber e-mails da internet.
1. Instalar dependências
sudo apt update
sudo apt install -y postfix libsasl2-modules ca-certificates
2. Configurar o Postfix
Edite: /etc/postfix/main.cf
Relay SMTP na porta 587 (opção recomendada):
# Relay SMTP externo. Colchetes evitam consulta DNS MX.
relayhost = [smtp.exemplo.com]:587
# Autenticação no relay.
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = ${default_database_type}:/etc/postfix/sasl_passwd
smtp_sasl_security_options = noanonymous
# STARTTLS obrigatório.
smtp_tls_security_level = encrypt
Relay SMTP na porta 465 (use esta opção somente se o provedor exigir SMTPS/TLS implícito)
relayhost = [smtp.exemplo.com]:465
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = ${default_database_type}:/etc/postfix/sasl_passwd
smtp_sasl_security_options = noanonymous
smtp_tls_security_level = encrypt
smtp_tls_wrappermode = yes
NOTA 1: A porta liberada no relayhost precisa ser idêntica à chave configurada no arquivo sasl_passwd. A porta 465 exige smtp_tls_wrappermode = yes; sem ela, o Postfix tentará usar STARTTLS em uma conexão que já deveria iniciar com TLS.
NOTA 2: Não configure diretivas smtpd_* para este cenário. Elas se aplicam ao Postfix recebendo conexões SMTP, não ao Postfix enviando e-mails para o relay.
3. Configurar as credenciais SMTP
Crie ou edite: /etc/postfix/sasl_passwd
[smtp.exemplo.com]:587 usuario@smtp.exemplo.com:senha-ou-app-password
Para porta 465:
[smtp.exemplo.com]:465 usuario@smtp.exemplo.com:senha-ou-app-password
Proteja o arquivo e gere o mapa do Postfix:
sudo chown root:root /etc/postfix/sasl_passwd
sudo chmod 600 /etc/postfix/sasl_passwd
sudo postmap /etc/postfix/sasl_passwd
sudo chmod 600 /etc/postfix/sasl_passwd.*
O uso de ${default_database_type}
evita assumir que o servidor usa hash, lmdb ou outro formato de mapa. O tipo disponível pode ser conferido com postconf -m, e alterações no arquivo exigem nova execução de postmap.
Nunca armazene esse arquivo em repositórios Git, diretórios web ou backups acessíveis a clientes.
4. Validar e recarregar o Postfix
sudo postfix check
sudo systemctl reload postfix
sudo systemctl status postfix --no-pager
Conferir a configuração efetiva:
sudo postconf -n | grep -E 'relayhost|smtp_sasl|smtp_tls'
5. Validar a integração com PHP
Em Linux, o PHP usa o binário sendmail para implementar mail(). O valor esperado normalmente é:
sendmail_path= /usr/sbin/sendmail -t -i
Validar no PHP CLI:
php -i | grep sendmail_path
E no PHP-FPM:
php-fpm8.5 -i | grep sendmail_path
Caso necessário, ajuste o php.ini do PHP-FPM:
sendmail_path= /usr/sbin/sendmail -t -i
Em seguida:
sudo systemctl reload php8.5-fpm
O PHP CLI e o PHP-FPM podem carregar arquivos php.ini diferentes; a validação deve ser feita no contexto do pool que executa a aplicação. O valor padrão documentado pelo PHP é /usr/sbin/sendmail -t -i
6. Testar o envio
Crie temporariamente o arquivo /tmp/test-mail.php:
<?php
declare(strict_types=1);
$sent = mail(
'destinatario@exemplo.com',
'Teste de envio via PHP mail()',
"E-mail de teste enviado em " . gmdate('c') . "\n",
implode("\r\n", [
'From: Sistema <noreply@seudominio.com>',
'Reply-To: suporte@seudominio.com',
'Content-Type: text/plain; charset=UTF-8',
])
);
var_dump($sent);
Execute usando o usuário do pool PHP-FPM do site:
sudo -u <usuario-do-pool> php /tmp/test-mail.php
Remova o arquivo após o teste:
rm -f /tmp/test-mail.php
bool(true) confirma apenas que o PHP entregou a mensagem ao Postfix local. A confirmação de entrega ao relay deve ser verificada nos logs.
7. Verificar logs e fila
Em instalações com rsyslog:
sudo tail -f /var/log/mail.log
Em instalações baseadas apenas em journald:
sudo journalctl -u postfix -f
Verificar a fila:
sudo postqueue -p
Forçar nova tentativa após corrigir uma configuração:
sudo postqueue -f
Sucesso esperado no log:
status=sent (250 2.0.0 OK)
O Ubuntu normalmente registra eventos do Postfix em /var/log/mail.log.
Requisitos da aplicação
A aplicação deve enviar com um endereço From autorizado pelo provedor SMTP, por exemplo:
noreply@seudominio.com
No WordPress, recomenda-se definir globalmente um remetente válido via configuração do próprio sistema, plugin de SMTP compatível ou filtro wp_mail_from.
Evite usar remetentes automáticos como:
www-data@hostname-interno
root@servidor
Eles podem ser rejeitados pelo relay ou prejudicar SPF, DKIM, DMARC e entregabilidade.
Problemas comuns
| Erro | Causa provável |
| SASL authentication failed | Usuário, senha, app password ou política SMTP inválida |
| Must issue a STARTTLS command first | Porta 587 configurada sem TLS obrigatório |
| Falha TLS na porta 465 | Ausência de smtp_tls_wrappermode = yes |
| Connection timed out | Porta bloqueada por firewall ou hospedagem |
| status=deferred | Falha temporária de rede, DNS, TLS ou relay |
| mail() retorna true, mas não entrega | Consultar /var/log/mail.log e postqueue -p |
| Relay rejeita o remetente | O endereço From não é autorizado pela conta SMTP |
AVISO LEGAL: Os procedimentos descritos neste documento devem ser executados de acordo com o contexto de cada sistema, de forma a evitar impactos negativos à segurança, disponibilidade, integridade e privacidade de dados. A Nevolus se reserva o direito de modificar a qualquer tempo e sem aviso prévio as informações aqui apresentadas a fim de refletir o lançamento de novos serviços, atualizações físicas e operacionais, e evolução do estado-da-arte da tecnologia.
