BOMBOLOM.COM

(correio) Diagnóstico de problemas SMTP

Por Helder Guerreiro.

Hoje em dia o mail é usado como ferramenta de comunicação para quase tudo dentro de uma empresa. Eu penso que muitas vezes o mail é abusado, mal utilizado e de uma forma geral usado de forma muito insegura e irrefletida. No entanto não é disso que quero falar hoje.

O facto é que ao ser tão utilizado, os problemas que surgem devido a não se conseguir enviar ou receber um mail tomam proporções deveras grandes. É claro que o utilizador raramente lê as mensagens de erro, quando o faz não as sabe interpretar ou então, pior ainda, está a utilizar o Outlook em cujo caso as mensagens estão para além de qualquer humano entendimento. Assim ficamos limitados a tentar simular o problema.

É claro que se devem de analisar todas as mensagens de erro, verificar os logs do servidor SMTP, IMAP, POP3, etc. No entanto, muitas vezes, é muito fácil descobrir o que se passa se olharmos directamente às respostas do servidor. O que quero mostrar neste artigo é como se processa uma conversa SMTP típica e como a podemos usar para resolver problemas.

Envio de uma mensagem por SMTP

Os servidores de SMTP podem ter comportamentos diferentes conforme sejam contactados de uma rede privada, ou do exterior. Normalmente os servidores de SMTP aceitam ligações das redes internas sem fazerem mais verificações, enquanto que das redes externas poderão apenas aceitar correio para uma lista de domínios pré-definidos ou de utilizadores autenticados. Actualmente a tendência é apertar este crivo de modo a exigir autenticação mesmo de dentro de redes internas.

O SMTP, como o nome indica, trabalha em texto simples com um conjunto muito reduzido de comandos. Para falarmos com o servidor SMTP basta fazermos telnet para a porta 25.

Envio sem autenticação

O primeiro passo consiste na ligação ao servidor (a azul estão as respostas do servidor):

$ telnet smtp.example.com 25
Trying xxx.xxx.xxx.xxx...
Connected to smtp.example.com.
Escape character is '^]'.
220-smtp.example.com ESMTP Exim 4.69 #1 Tue, 10 Feb 2009 19:42:41 +0100
220-We do not authorize the use of this system to transport unsolicited,
220 and/or bulk e-mail.

Notar que o servidor indica que suporta ESMTP.

A seguir é necessário 'cumprimentar' o servidor! A sério. Esta fase é necessária para que o cliente de mail possa saber quais são as capacidades do servidor. Isso faz-se com o comando 'EHLO' que é uma deformação de HELO usada pelo protocolo ESMTP, que vem extender o SMTP:

EHLO example.com
250-xxx.xxx.xxx.xxx Hello bombolom.com [yyy.yyy.yyy.yyy]
250-SIZE 13631488
250-PIPELINING
250-AUTH PLAIN LOGIN
250-STARTTLS
250 HELP

O servidor proporciona-nos informação adicional:

Existem mais capacidades, que variam de servidor para servidor e conforma as suas próprias configurações. Os clientes de mail são supostos saber interpretar as linhas com as capacidades e aproveita-las da melhor forma possível (pois, pois...).

Este servidor especificamente também tem uma ajuda (um bocadinho fraca!) incorporada:

HELP
214-Commands supported:
214 AUTH STARTTLS HELO EHLO MAIL RCPT DATA NOOP QUIT RSET HELP

Como se pode ver o número de comandos é muito reduzido, daqui o facto do protocolo se chamar protocolo de transferência de correio SIMPLES.

Agora estamos prontos para iniciar o envio da mensagem. Vamos identificar o remetente:

MAIL From: <o_papa@vaticano.com>
250 OK

Notar que não há qualquer obrigação quanto ao remetente utilizado. Convém o domínio existir dado que isto pode ser verificado, mas nem isso é obrigatório na maior parte das vezes! - Notar que isto só por si não nos garante ficarmos anónimos dado que na informação sobre o transporte do correio que é acrescentada aos cabeçalhos das mensagens está informação sobre o endereço IP de origem, bem como sobre os servidores de SMTP pelos quais a mensagem circulou até chegar ao destino. Moral da história, não utilizar endereços de retorno falso para manter a privacidade, não funciona. (Já agora, eu sei que o TDL do Vaticano não é '.com' mas julgo que assim a coisa é mais verdadeira...)

Depois indicamos o destinatário:

RCPT To: <exemplo@example.com>
250 Accepted

E finalmente entramos com a nossa mensagem:

DATA
354 Enter message, ending with "." on a line by itself
Subject: Teste sem autenticacao

Nao ha autenticacao...
.
250 OK id=1LWxbt-0000F6-0Z

O '250 OK' indica-nos que a mensagem foi enviada com sucesso. Estas mensagens variam de servidor para servidor, por exemplo o Postfix responde com:

250 2.0.0 Ok: queued as 2AFF2181

Notar também que no exemplo não utilizei caracteres acima de ASCII 128 dado que alguns servidores não suportam estes caracteres. Quando isso acontece estes têm '8BITMIME' entre as suas capacidades (devolvidas pelo comando EHLO).

Resta-nos abandonar a ligação:

QUIT
221 smtp.example.com closing connection
Connection closed by foreign host.

("Connection closed by foreign host." - é resposta do programa de telnet...)

Isto tudo junto fica:

$ telnet smtp.example.com 25
Trying xxx.xxx.xxx.xxx...
Connected to smtp.example.com.
Escape character is '^]'.
220-smtp.example.com ESMTP Exim 4.69 #1 Tue, 10 Feb 2009 19:42:41 +0100
220-We do not authorize the use of this system to transport unsolicited,
220 and/or bulk e-mail.
EHLO example.com
250-xxx.xxx.xxx.xxx Hello bombolom.com [yyy.yyy.yyy.yyy]
250-SIZE 13631488
250-PIPELINING
250-AUTH PLAIN LOGIN
250-STARTTLS
250 HELP
MAIL From: <o_papa@vaticano.com>
250 OK
RCPT To: <exemplo@example.com>
250 Accepted
DATA
354 Enter message, ending with "." on a line by itself
Subject: Teste sem autenticacao

Nao ha autenticacao...
.
250 OK id=1LWxbt-0000F6-0Z
QUIT
221 smtp.example.com closing connection
Connection closed by foreign host.

Envio com autenticação PLAIN

Como referi antes, cada vez mais é exigido que nos autentiquemos para enviar mensagens. Isto é feito, especialmente, para combater o abuso feito pelos spammers e pelo malware que lhes está associado.

A conversa com o servidor é em tudo idêntica à anterior, com a excepção que nos vamos autenticar. Logo após termos enviado o comando EHLO, isto faz-se da seguinte forma:

AUTH PLAIN
334
AG5vbWUgZG8gdXRpbGl6YWRvcgBwYWxhdnJhIHBhc3Nl
235 Authentication succeeded

A linha 'AG5vbWUgZG8gdXRpbGl6YWRvcgBwYWxhdnJhIHBhc3Nl' não é mais do que a cadeia de caracteres '\0nome do utilizador\0palavra passe' codificada em base 64. Por exemplo usando o python podemos fazer isto com:

$ python
Python 2.5 (release25-maint, Jul 20 2008, 20:47:25)
[GCC 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import base64
>>> base64.b64encode('\0nome do utilizador\0palavra passe')
'AG5vbWUgZG8gdXRpbGl6YWRvcgBwYWxhdnJhIHBhc3Nl'

Agora pode-se finalizar a conversa como fizemos anteriormente.

Envio com autenticação LOGIN

A o esquema de autenticação LOGIN utiliza-se da mesma forma que o anterior, a diferença é que o nome de utilizador e a palavra passe vão residir em linhas diferentes. Por exemplo:

(1) AUTH LOGIN
(2) 334 VXNlcm5hbWU6
(3) bm9tZSBkbyB1dGlsaXphZG9y
(4) 334 UGFzc3dvcmQ6
(5) cGFsYXZyYSBwYXNzZQ==
(6) 235 Authentication succeeded

Na linha (1) invocamos o comando. Como resposta, na linha (2) temos 'VXNlcm5hbWU6' que não é mais do que 'Username:' codificado em base 64. Na linha (3) passamos o nome de utilizador em base 64 e na (4) é-nos respondido 'UGFzc3dvcmQ6' ou seja 'Password:'! Respondemos com a palavra passe, mais uma vez, em base 64.

Estabelecer uma ligação encriptada

Finalmente, resta-nos mostrar como estabelecer uma ligação encriptada.

Em primeiro lugar devemos verificar se o servidor remoto suporta TLS. Isto faz-se com o comando EHLO, como se mostrou mais atrás. Se o servidor tiver a capacidade STARTTLS, então pudemos estabelecer ligações encriptadas para este destino.

A seguir vamos utilizar o programa 'openssl' para estabelecer a ligação:

$ openssl s_client -starttls smtp -crlf -connect smtp.example.com:25

(Este comando está disponível no pacote 'openssl', tanto no Debian como no Kubuntu.)

O que isto faz é ligar da forma normal à porta 25 do servidor e a seguir invoca o comando 'STARTTLS' após o que estamos numa ligação encriptada. Notar que vamos ter muito mais respostas associadas ao canal seguro, no entanto os comando vão trabalhar exactamente da mesma forma que anteriormente.

Alternativamente, é possível ligar directamente à porta 465 (smtps) - se o servidor o suportar. Neste caso TODA a comunicação vai ser encriptada desde o princípio. Neste caso basta fazer:

$ openssl s_client -crlf -connect smtp.example.com:465

Lista de erros

Para entender o que se passa numa ligação SMTP é necessário compreender as mensagens de erro do servidor. Os seus significados são os seguintes (do RFC2821):

500 Erro de sintaxe, comando não reconhecido
    (Isto pode incluir erros tais como linha demasiado grande)
501 Erro de sintaxe nos parâmetros ou argumentos
502 Comando não implementado (ver secção 4.2.4)
503 Má sequência de comandos
504 Parâmetro de comando não implementado

211 Estado do sistema, ou resposta de ajuda do sistema
214 Mensagem de ajuda
    (Informação em como utilizar o receptor ou o significado de
    um comando não standard em particular; esta resposta apenas 
    é útil ao utilizador humano)

220 <domínio> Serviço pronto
221 <domínio> O serviço está a fechar o canal de transmissão
421 <domínio> O serviço não está disponível, a fechar o canal
    de transmissão (Isto pode ser a resposta a qualquer comando se o 
    serviço souber que tem de se desligar)

250 A acção que foi pedida foi concluída com êxito.
251 O utilizador não é local, vou reenviar para <caminho de 
    re-envio> (ver secção 3.4)
252 Não consigo verificar (VRFY) o utilizador, mas vou aceitar a 
    mensagem e tentar entrega-la (ver secção 3.5.3)
450 A acção pedida não foi executada: A caixa postal não está 
    disponível (por exemplo a caixa postal pode estar desempenhar 
    outra função e não puder receber correio de momento)
550 A acção pedida não foi executada: a caixa postal não está 
    disponível de forma definitiva (por exemplo a caixa postal 
    não foi encontrada, não há acesso à caixa postal, ou o comando
    foi rejeitado por questões de política)
451 A acção pedida foi abortada: erro no processamento 
551 O utilizador não é local; por favor tente <caminho de
    re-envio> (ver secção 3.4)
452 A acção pedida não foi executada: espaço de armazenamento
    do sistema é insuficiente
552 A acção pedida foi abortada: a alocação de espaço de 
    armazenamento do sistema foi ultrapassada
553 A acção pedida não foi executada: o nome da caixa postal não é
    permitido (por exemplo sintaxe incorrecto no nome da caixa postal)
354 Inicie a introdução de dados; acabe com <CRLF>.<CRLF>
554 Transmissão falhada (ou, no caso de ser uma resposta obtida na
    abertura de uma ligação, "Não há serviço de SMTP aqui")

Notar que temos de uma forma geral:

Recursos

Conclusão

Com base no anterior, podemos muito facilmente diagnosticar problemas a nível de envio e recebimento de mensagens. Notar que em regra o utilizador final não recebe por SMTP directamente para a sua caixa postal o seu correio, em vez disso utiliza-se vários sistemas intermédios para tratar e filtrar o correio (por exemplo servidores POP3 ou IMAP,programas como o procmail, etc). Os problemas podem surgir em qualquer destas fases pelo que devemos dar atenção a todos os passos.

Com problemas nestes sistemas, o que eu faço é, após ter ouvido o utilizador tento repetir todo o processo, muitas vezes usando as técnicas aqui descritas, de modo a puder ver na fonte os erros que podem surgir.

10.02.2009 | Ler mais | Comentários | Tags ,

Voltar à Página principal | Made with PyBlosxom