Estou tentando entender exatamente como um e-mail é processado pelo Postfix – e alguns dos detalhes mais sutis das transações de e-mail SMTP. Meu objetivo de curto prazo é depurar um cliente SMTP proprietário (código binário, fechado), mas primeiro pensei em examinar o que acontece em uma transação SMTP bem-sucedida.
Pretendo bloquear o SMTP de saída (porta 25) em nosso firewall LAN, então configurei o Postfix como um servidor de correio interno para aceitar e-mails de software cliente local (primitivo) que só pode enviar e-mail via SMTP não autenticado (pela porta 25).
Ativei a depuração do smtpd
processo do Postfix anexando o -v
sinalizador detalhado master.cf
conforme descrito em Solução de problemas com logs do Postfix . Em seguida, enviei um e-mail de minha própria estação de trabalho usando Cygwin Mutt com sSMTP (uma implementação mínima de sendmail
).
Os logs do Postfix mostram que depois que a RCPT TO:
linha foi processada com sucesso e o endereço do destinatário foi aceitável, o Postfix smtpd
atribuiu à transação um ID de fila e respondeu ao cliente SMTP (sSMTP) com um arquivo 250 OK
.
No entanto, em vez de emitir um DATA
comando, o cliente SMTP emitiu um RSET
para redefinir/interromper a transação de correio atual e o Postfix respondeu com um 250 OK
.
Eu fiz algumas pesquisas sobre o que esse comando faz e, sem surpresa, o Simple Mail Transfer Protocol, RFC 2821 forneceu as informações mais abrangentes:
Este comando especifica que a transação de correio atual será abortada. Qualquer remetente, destinatário e dados de correio armazenados DEVEM ser descartados e todos os buffers e tabelas de estado limpos. O receptor DEVE enviar uma resposta "250 OK" a um comando RSET sem argumentos. Um comando de reinicialização pode ser emitido pelo cliente a qualquer momento. É efetivamente equivalente a um NOOP (ou seja, se não tem efeito) se emitido imediatamente após EHLO, antes de EHLO ser emitido na sessão, após um indicador de fim de dados ter sido enviado e confirmado ou imediatamente antes de um QUIT. Um servidor SMTP NÃO DEVE fechar a conexão como resultado do recebimento de um RSET; essa ação é reservada para QUIT (consulte a seção 4.1.1.10).
Como o EHLO implica algum processamento e resposta adicionais por parte do servidor, o RSET normalmente será mais eficiente do que reemitir esse comando, mesmo que a semântica formal seja a mesma.
Há circunstâncias, contrárias ao objetivo desta especificação, nas quais um servidor SMTP pode receber uma indicação de que a conexão TCP subjacente foi fechada ou redefinida. Para preservar a robustez do sistema de correio, os servidores SMTP DEVEM estar preparados para essa condição e DEVEM tratá-la como se um QUIT tivesse sido recebido antes que a conexão desaparecesse.
Tudo o que foi dito acima aconteceu no espaço de um segundo, então não deve haver problemas com tempos limite.
No segundo seguinte, o cliente enviou outro, RSET
mas o cliente esperou 10s inteiros antes de reiniciar com MAIL FROM:
, RCPT TO:
mas desta vez ele segue e emite o DATA
comando e a transação é concluída (tudo no mesmo segundo de acordo com os logs).
Essencialmente, estou me perguntando por que um cliente SMTP interromperia sua própria transação emitindo RSET
comandos em vez de um DATA
comando.
Notas:
Posso editar a pergunta para incluir a extração do arquivo de log de email, mas com a
-v
depuração, eles são muito detalhados e não quero sobrecarregar as pessoas com uma mangueira de dados irrelevantes.Pesquisei o código-fonte sSMTP, mas não encontrei nenhuma menção a
RSET
.
TLDR
Eu estava me perguntando por que um cliente SMTP interromperia sua própria transação emitindo comandos RSET em vez do comando DATA. A resposta curta é que não; este é um sintoma de que as conexões SMTP estão sendo interceptadas pelo software antivírus.
Log do cliente
Ativei a opção Debug na configuração do sSMTP, mas levei algum tempo para descobrir como instalar e configurar o syslog no Cygwin para que as mensagens dos processos do Cygwin fossem registradas em
/var/log/messages
vez do visualizador de eventos do Windows.No entanto, ele registrou apenas o primeiro comando
MAIL FROM:
e ;RCPT TO:
não havia indicação de que esses comandos foram enviados mais de uma vez - ou quesSMTP
já enviaram umRSET
comando.Conforme mencionado na minha pergunta, verifiquei o código-fonte sSMTP, mas não há código para enviar um
RSET
comando.Symantec Interceptação de tráfego SMTP
O usuário masegaloeh sugeriu que o software antivírus pode estar modificando os pacotes SMTP – e ele estava certo: desabilitei temporariamente o Symantec Endpoint Protection em meu computador e as transações SMTP prosseguiram normalmente.
Depois de reativar o Symantec Endpoint Protection, monitorei as conexões TCP usando o utilitário TCPView do Windows Sysinternals e pude ver que o
ccSvcHst.exe
processo da Symantec estava fazendo proxy de todo o tráfego TCP cuja porta de destino é 25.Fiz um telnet para a porta 25 no servidor de e-mail (o netcat não funcionaria corretamente, possivelmente devido à interceptação da Symantec) para enviar um e-mail de teste usando manualmente os comandos SMTP. Ao mesmo tempo, abri outra janela de terminal com uma conexão SSH com o host de e-mail durante a execução
sudo tail -F /var/log/maillog
para monitorar simultaneamente o que o servidor SMTP estava vendo.A interceptação realizada pelo proxy da Symantec é sutil. Do ponto de vista do cliente de e-mail, há muito pouca indicação de que ele não está se comunicando diretamente com o servidor SMTP. A maioria dos comandos é passada para o servidor de correio conforme eles são enviados e as respostas são as esperadas. Não foi até eu inserir o
DATA
comando que o proxy da Symantec começou a mudar as coisas: ele respondeu com:Isso parece normal, mas, na realidade, a resposta do meu servidor Postfix deveria ter sido
Além disso: na verdade, ele não passou o
DATA
comando para o Postfix até que eu concluí o corpo da mensagem e o segui com um arquivoQUIT
.Observação: enquanto eu digitava o conteúdo da mensagem de teste, o proxy da Symantec manteve ativa sua conexão com o servidor Postfix emitindo
NOOP
comandos.Lidando com clientes SMTP com bugs
Mencionei em minha pergunta que meu objetivo final era solucionar problemas de um cliente de e-mail proprietário (binário, de código fechado) usado por minha organização. Eu descobri que esse cliente é realmente bugado: ele envia um comando inválido
HELO
(sem nenhum nome de host) e simplesmente desiste e sai depois de ser educadamente informado pelo servidor SMTP que sua sintaxe está errada – mesmo que eu tenha configurado o Postfix para não exigir umHELO
(válido ou não).Resolvi esse problema instalando um novo servidor com o CentOS 7, que vem com uma versão do Postfix recente o suficiente para que eu possa desabilitar completamente as verificações HELO do postfix (semelhante a como o MS Exchange simplesmente ignora comandos HELO inválidos).
Uso geral do RSET
Eu também estava pensando sobre o uso geral de
RSET
em transações SMTP e encontrei o seguinte no RFC 821 original para SMTP:RSET
seria usado se descobrisse que o endereço de e-mail do destinatário era para um usuário inexistente. A seguinte transação SMTP é um exemplo de Cenário de Transação SMTP Abortada .Reutilização de conexões SMTP
Os clientes SMTP podem usar a mesma conexão SMTP para enviar várias mensagens para o mesmo destino. Esse recurso é denominado cache de conexão SMTP pelo Postfix. Ao usar esse recurso de desempenho, o Postfix envia um
RSET
antes de cadaMAIL FROM
comando para verificar se a conexão SMTP ainda pode ser usada (consulte Cache de conexão do Postfix ).