Servidor de emails com Dovecot e MTA Sceo (projeto brasileiro)

Como criar um servidor de e-mails completo e avançado usando o Dovecot e o projeto brasileiro MTA Sceo com banco de dados MySQL. Técnicas antiDoS e antispam a nível de SMTP. Antivírus Clamav, antispam Spamassassin, Greylist e RBLs. Quota de espaço e controle do número de e-mails que cada cliente pode enviar.

[ Hits: 45.938 ]

Por: Lucas Priori em 08/10/2010


Técnicas diversas



Desempenho

O envio de e-mails não ficará instantâneo porque o Sceo esta rodando o antispam e antivírus. Se você quiser, pode incluir condições na frente das regras para não rodar antivírus ou antispam para sua rede local ( !Ip? "192.168.0.0/24" ) ou para clientes autenticados ( !Auth? ).

Outra coisa que pode fazer o envio de e-mails não ficar instantâneo é o fato do servidor demorar para resolver o nome do IP de uma rede local. Se a sua rede é muito grande e você não quer ficar colocando os nomes dos IPs em /etc/hosts, você pode mandar o Sceo não resolver o endereço reverso para IPs da rede local, assim:

Abra o /usr/local/sceo/sceo.conf:

# pico /usr/local/sceo/sceo.conf

Altere a opção Resolve_all deixando-a desativada, assim:

Resolve_all 0

Salve e saia do arquivo.

Edite o arquivo /usr/local/sceo/regras_conexao:

# pico /usr/local/sceo/regras_conexao

Digamos que a minha rede local seja 192.168.0.0/24. Acrescente a seguinte regra logo no inicio do arquivo:

!Ip? "192.168.0.0/24" Resolve!

Salve e feche o arquivo.

Reinicie o Sceo:

# /etc/rc.d/rc.sceo restart

Teste agora o tempo de envio de seu cliente de e-mail ao seu servidor SMTP.

Esta eu acho que esta é a sessão mais interessante. Aqui você aprenderá um pouco de como configurar o Sceo para se defender de lixo eletrônico, ataques etc.

Mas lembre-se de que o seu servidor JÁ ESTÁ configurado e pronto para funcionar e você não precisa colocar as regras descritas aqui.

Anti-DoS

Este tipo de ataque consiste em estabelecer muitas conexões em determinado serviço de um servidor fazendo-o negar novas conexões (Denial of Service).

Podemos tomar algumas medidas para dificultar ao máximo esse tipo de ataque.

No Linux, podemos ligar o tcp_syncookies para fazer o kernel só alocar recursos para atender a conexão se receber de volta o pacote SYN / ACK. (Para mais detalhes, procure em seu buscador por "Syn Flood DoS").

Execute o seguinte comando:

# echo 1 > /proc/sys/net/ipv4/tcp_syncookies

Esta feito. Não é preciso reiniciar nada. Se quiser você pode colocar o comando acima no seu rc.local:

# echo "echo 1 > /proc/sys/net/ipv4/tcp_syncookies" >> /etc/rc.d/rc.local

A opção passada acima já te da uma boa segurança, mas pode haver casos de tentativas de DoS onde as conexões sejam realmente estabelecidas e não apenas um Syn Flood e nestes casos o tcp_syncookies se torna inútil.

Para estes casos nós podemos fazer o Sceo bloquear o IP do atacante no Firewall do servidor automaticamente.

Crie então uma Chain chamada BLACKLIST em seu Firewall, pois é lá que incluiremos os IPs bloqueados:

# iptables -N BLACKLIST
# iptables -I INPUT -d ! 127.0.0.1 -j BLACKLIST


Obs.: Você deve colocar as linhas acima TAMBÉM em seu script de Firewall (geralmente /etc/rc.d/rc.firewall) para ele criar automaticamente esta Chain e chamá-la quando o servidor estiver ligando. Como eu não sei como é o seu Firewall eu passei regras meio genéricas. Se você entende de iptables e sacou o sentido da coisa, configure da forma correta em seu Firewall...

Nas regras de iptables acima eu primeiro criei uma Chain chamada BLACKLIST e na linha de baixo eu mandei inserir uma regra logo no inicio mandando o kernel processar a Chain BLACKLIST caso o IP de destino do pacote NÃO seja o localhost.

Agora vamos às configurações no Sceo.

Abra o arquivo /usr/local/sceo/sceo.conf:

# pico /usr/local/sceo/sceo.conf

Procure e altere as opções Limit_buf, Limit_cnx e Limit_time conforme os valores abaixo:

Limit_buf 100
Limit_cnx 20
Limit_time 2

Explicação:

O sistema de limites é ligado quando definimos um valor diferente de zero para Limit_buf, ela diz ao Sceo que ele deve analisar as ultimas 100 conexões a procura de IPs que estabeleceram no mínimo 20 conexões em um período inferior a 2 segundos entre uma conexão e outra. Estes valores variam bastante entre servidores com grande, médio ou baixo fluxo de emails. De início, use estes valores e fique de olho no Log que vamos "montar" para monitorarmos e depois altere os valores se quiser.

Certifique-se de que a opção Limit_rules esteja com o parâmetro "/usr/local/sceo/regras_limite". Este é o arquivo de regras que o Sceo vai executar caso um possível DoS tenha sido detectado.

Salve e saia do sceo.conf. Agora abra o arquivo /usr/local/sceo/regras_limite:

# pico /usr/local/sceo/regras_limite

Neste arquivo nós mandaremos o Sceo incluir uma regra no Firewall para bloquear o IP em questão, mas devemos tomar muito cuidado pois isto pode bloquear outros servidores que fazem parte de nossa rede ou de confiança e que geralmente entregam grandes quantidades de emails. No exemplo que darei abaixo eu vou mandar ele aceitar e parar de processar o regras_limite caso o IP seja de minha rede local ou de alguns outros servidores cujo IP eu escolhi aleatoriamente para o exemplo:

IPs locais: 127.0.0.1, 10.10.10.0/24
IPs de outros servidores: 240.240.240.2, 240.240.240.3 e 70.70.70.70

Coloque no arquivo o seguinte conteúdo:

Ip? "127.0.0.1" Accept!
Ip? "10.10.10.0/24" Accept!
Ip? "240.240.240.1" Accept!
Ip? "240.240.240.2" Accept!
Ip? "240.240.240.3" Accept!
Ip? "70.70.70.70" Accept!
Log! "/var/log/sceo/sceo_limit.log:%i Bloqueado"
Exec! "iptables -I BLACKLIST -s %i -j DROP"

O Sceo executa este arquivo de regras ainda com permissão de root, para depois descer para a permissão apontada pela opção "User" do arquivo sceo.conf.

Agora nós temos que agendar o Cron para zerar a Chain BLACKLIST 1 vez por dia para estes IPs não ficarem bloqueados para sempre ou até o próximo reboot do sistema. Acredite, isto é necessário para o Firewall não ficar lento com o tempo, porque um IP não deve ser punido para sempre e tudo isto foi criado apenas para impedir um tipo de ataque que acontece por um curto período do dia.

Acrescente a seguinte regra em seu Cron:

00 0 * * * iptables -F BLACKLIST

Reinicie o Sceo:

# /etc/rc.d/rc.sceo restart

Está feito. Se por acaso você quiser que o Sceo te mande um email a cada IP bloqueado, acrescente a seguinte linha de regra no final do regras_limite.

Obs.: As regras abaixo devem ficar em uma única linha e não esqueça de colocar o seu endereço de email no lugar.

Exec! "/usr/local/sceo/sceo_mail -to eu@meudominio.com.br -f eu@meudominio.com.br -su DoS_de_%i -sf /usr/local/sceo/aviso_DOS.eml"

Agora crie o arquivo /usr/local/sceo/aviso_DOS.eml com o seguinte conteúdo:

Uma tentativa de DoS foi detectada no servidor SMTP
e seu acesso foi bloqueado pelo Sceo e seu IP cortado
no Firewall

Verifique o Log: /var/log/sceo/sceo_limit.log
para maiores detalhes

Salve e saia do arquivo. Está feito!

Helo "Eu sou você"

É engraçado quando você esta olhando o Log de seu servidor e vê que IPs externos conectam-se e no comando "helo/ehlo" dizem ser você.

Digamos que o IP de seu servidor seja 240.240.240.1 e o FQDN seja mx1.meuservidor.net. Então você deve cortar qualquer conexão que mande um "helo 240.240.240.1" ou "helo [240.240.240.1]". Edite o arquivo /usr/local/sceo/regras_remetente:

# pico /usr/local/sceo/regras_remetente

E acrescente o seguinte conteúdo no final do arquivo:

!Ip? "127.0.0.1" !Ip? "240.240.240.1" Helo? "240.240.240.1" Reply! "550 Cai fora SPAMMER" Close!
!Ip? "127.0.0.1" !Ip? "240.240.240.1" Helo? "[240.240.240.1]" Reply! "550 Cai fora SPAMMER" Close!
!Ip? "127.0.0.1" !Ip? "240.240.240.1" Helo? "mx1.meuservidor.net" Reply! "550 Cai fora SPAMMER" Close!

Explicação:

Caso o IP conectado NÃO seja o 127.0.0.1 e 240.240.240.1 e no Helo ele mandar 240.240.240.1 ou [240.240.240.1] ou mx1.meuservidor.net, o Sceo responderá "550 Cai fora SPAMMER" e fechará a conexão.

Esta regra você pode colocar sem dó. Só spammer cai nela.

Blacklist via RBLs mundiais

Abra o arquivo regras_conexao:

# pico /usr/local/sceo/regras_conexao

Acrescente as regras abaixo no regras_conexao para fazer o Sceo fazer consultas em RBLs:

Ip? "127.0.0.1" Stop!

Rbl_test! "bl.spamcop.net zen.spamhaus.org b.barracudacentral.org"

!Rbl_resp? "0" Log! "/var/log/sceo/blacklist.log: Bloqueado %i %f %r %R->%T" Reply! "550 IP em Blacklist RBL %T" Close!

Eu separei por uma linha em branco as regras acima para você saber quais "comandos" devem ficar em uma única linha.

A primeira linha de regra: Ip? "127.0.0.1" Stop! faz o Sceo PARAR de processar o arquivo regras_conexao caso o IP conectado seja o 127.0.0.1. Você deve fazer isso para o IP local de Internet do servidor e também para o seu bloco de rede local.

Embora você tenha feito a checagem RBL no regras_conexão, você não precisa necessariamente bloquear a conexão aqui. Tenho caso de clientes que QUEREM receber SPAMs e eu não posso rodar Blacklist para ele. Como resolver isto, já que o endereço do remetente só é especificado bem depois?

SIMPLES! Digamos que o domínio do cliente que ama Spams seja "amospam.com.br". Então basta remover a linha (!Rbl_resp? "0" ...) ai do regras_conexao e recoloca-la no regras_destinatario da seguinte forma:

!Find_in_to? "@amospam.com.br" !Rbl_resp? "0" Log! "/var/log/sceo/blacklist.log: BLACKLIST_RBL %i %f %r %R->%T" Reply! " 505 IP em Blacklist RBL %T" Close!

Explicação:

Caso NÃO seja um email com destino ao domínio "amospam.com.br" o Sceo vai verificar qual foi a resposta das RBLs testadas durante o regras_conexao e cortar ou não a conexão.

É possível criar um arquivo texto contendo uma lista de domínios que amam Spam e fazer o Sceo consulta-lo. Mas este tutorial já esta ficando muito extenso e tenho mais coisas para passar. Você pode acessar o site oficial do Sceo e aprender tudo isso e muito mais no fórum de lá.

Blacklist local

Você pode montar a sua Blacklist local, contendo aqueles nomes de servidores, IPs ou remetentes que insistem em entregar aquelas incríveis promoções que adoramos receber.

Vou montar aqui uma blacklist contendo nomes de servidores.

Crie um arquivo texto contendo o nome ou parte do nome dos servidores a bloquear.

# pico /usr/local/sceo/blacklist_srvs.txt

Vou colocar alguns nomes como exemplo dentro do arquivo:

.hospedagemdespammers.ws
mx1.spamlandia.net
supermailmarketing.com.br
.spammersunidos.

Salve e saia do arquivo.

Edite o regras_conexao:

# pico /usr/local/sceo/regras_conexao

Acrescente a seguinte regra no fim do arquivo, em apenas uma única linha:

Find_strfile? "%e:/usr/local/sceo/blacklist_srvs.txt" Reply! "500 Host spammer. Blacklist" Close!

Limitar o número de destinatários por email de um remetente nulo

# pico /usr/local/sceo/regras_destinatario Acrescente o seguinte conteúdo logo no começo do arquivo:

From? "" Itest? "%n>1" Reply! "550 Muitos rcpts para um remetente nulo" Deny!

Só aceite remetentes internos se eles se autenticarem

Se o remetente é um cliente entregando mensagem em seu servidor, por que não autenticar-se? Muitos Spams nos chegam com o endereço de remetente igual ao do destinatário. Aceitando somente remetentes locais autenticados você impede este tipo de Spam.

# pico /usr/local/sceo/regras_remetente

Acrescente o seguinte conteúdo logo no começo do arquivo:

!Ip? "127.0.0.1" Internal_from? !Auth? Reply! "550 Voce precisa autenticar-se" Deny!

Inventando um SPF para o Yahoo

Muitos Spams nos chegam com endereço de remetente sendo @yahoo.com. Para piorar a situação o Yahoo NÃO descreve SPF em seu DNS para sabermos quem é que pode ou não enviar emails @yahoo.com.

Vamos então "inventar" um SPF para ele, baseado no FQDN que todos os MTAs do Yahoo tem usado para entregar emails. Isto não da 100% de certeza de que o email seja do Yahoo pois este nome pode ser forjado, mas dificulta bastante a prática de Spams que usam @yahoo como remetente.

Abra o arquivo /usr/local/sceo/regras_remetente:

# pico /usr/local/sceo/regras_remetente

Acrescente o seguinte conteúdo no início e em uma única linha:

Find_in_from? "@yahoo.com" !Find_in_reverse? "yahoo.com" Reply! "550 Voce nao parece pertencer a rede Yahoo. Desculpe" Deny!

Salve e saia do arquivo. Não é preciso reiniciar o Sceo. Você só precisa reiniciá-lo quando alterar o sceo.conf.

Recusando Helo diferente do FQDN

O correto é informar o FQDN durante o comando "helo/ehlo" do SMTP. Nós podemos recusar servidores que cometam esta transgressão. É uma medida meio radical mas cada caso é um caso.

Edite o arquivo regras_remetente:

# pico /usr/local/sceo/regras_remetente

Coloque a seguinte regra logo no início e em uma única linha:

!Ip? "127.0.0.1" !Ip? "240.240.240.1" !Cmp_reverse "%h" Reply! "500 CMD Helo recusado" Deny!

Lembre-se de colocar no lugar de 240.240.240.1 o IP do seu servidor ou então da sua rede.

Fazendo backup de todas as mensagens que passam pelo servidor

Vi que existe muita gente preocupada em manter um backup de todas as mensagens que passam pelo servidor e a técnica usada é copiar cada mensagem recebida por cada destinatário em outra caixa postal ou de tempos em tempos copiar o maildir inteiro do servidor ou até fazer uma copia do email em outro local com complicados scripts que rodam no MDA (procmail, maildrop, deliver etc). Mas se o seu servidor recebe uma mensagem de 2 Mb para 30 contas de emails locais, no final você estará fazendo backup de 60 Mb. Isto é totalmente desnecessário. Você pode fazer backup apenas de 1 mensagem de 2Mb e se precisar usa-la você sabe onde encontrar.

Vamos fazer um shell script para o backup:

Crie e edite o arquivo /usr/local/sceo/uteis/backup.sh:

# pico /usr/local/sceo/uteis/backup.sh

Acrescente o seguinte conteúdo:

#!/bin/sh

ANO=`date +%Y`
MES=`date +%b`
DIA=`date +%d`
mkdir -p /mnt/backup/mail/$ANO/$MES/$DIA > /dev/null
cp /var/spool/sceo/*$1 /mnt/backup/mail/$ANO/$MES/$DIA

Salve e feche o arquivo.

Dê permissão de execução:

# chmod 555 /usr/local/sceo/uteis/backup.sh

Crie o diretório de backup com permissão 777:

# mkdir /mnt/backup
# chmod 777 /mnt/backup


Abra o arquivo regras_data que é processado cada vez que um email inteiro é entregue:

# pico /usr/local/sceo/regras_data

Acrescente a seguinte regra no final:

Exec! "/usr/local/sceo/uteis/backup.sh %d"

Salve e feche o arquivo.

Pronto! O Sceo vai rodar o backup.sh cada vez que um email chegar e o script se encarrega de criar automaticamente a estrutura de backup para a data atual e armazena o arquivo de email e sua lista de destinatários lá.

Nos arquivos de fila do Sceo, os que começam o "c" indicam o conteúdo do email, ou seja, é o email completo contendo header e corpo e os que começam com "l" armazenam os destinatários daquele email.

Usando HITS para pontuar negativamente o host

Todas as técnicas de combate anti-spam passadas acima cortam o host conectado em qualquer transgressão, mas pode ser que ao invés de cortar logo de cara o host apenas por cometer um erro, você queira corta-lo se cometer dois ou mais erros.

Para isto nós usamos a ação Add_hits! para adicionar ou tirar pontos, e depois testamos a variável %H para cortar ou não a conexão.

Vou repassar algumas regras descritas em sessão anteriores de forma que usem o Hits.

Coloque as seguintes regras no regras_conexao:

Rbl_test! "bl.spamcop.net zen.spamhaus.org b.barracudacentral.org"
!Rbl_resp? "0" Add_hits! "1" Add_hits! "%R"

Se o Spammer for encontrado em alguma RBL, ele vai ganhar 2 ou mais pontos negativos. A variável %R retorna o número de RBLs em que ele foi encontrado, ou seja, eu adicionei 1 ponto negativo e logo em seguida mandei adicionar como ponto negativo o número de RBLs em que ele foi encontrado.

Salve e saia do arquivo.

Agora coloque as seguintes regras no final de regras_remetente (Estou levando em conta que você já esta com a regra de fazer o teste SPF --> Spf_test!, que foi configurada anteriormente no meio deste tutorial):

!Spf_resp? "1" Add_hits! "1"
!Ip? "127.0.0.1" !Ip? "240.240.240.1" Helo? "240.240.240.1" Add_hits! "2"
!Ip? "127.0.0.1" !Ip? "240.240.240.1" !Cmp_reverse "%h" Add_hits! "1"
Itest? "%H>2" Reply! "550 Voce acumulou muitos pontos negativos" Deny!

Salve e saia do arquivo.

Se por acaso o host conectado ganhar 3 pontos ou mais ele será negado para entregar emails. A condição Itest? verifica se o valor da variável %H é maior que 2, se for, o Sceo nega o host conectado.

É isso aí. Seu servidor de emails está terminado!

Espero ter ajudado e que tenha gostado do tutorial e que goste do projeto MTA Sceo.

Gostaria de receber dicas de melhorias, sinta-se a vontade para me mandar suas ideias, mudanças e correções.

Obrigado a todos.

Lucas Priori
lpriori@hospedaria.com.br

Site dos projetos e referências:
Página anterior    

Páginas do artigo
   1. Introdução
   2. Downloads
   3. Instalando o Sceo
   4. Instalando o Dovecot
   5. SPF e Greylist
   6. Antivírus Clamav
   7. Spamassassin
   8. Quota de envio
   9. Técnicas diversas
Outros artigos deste autor

Benchmark entre servidores de e-mails

Dividindo carga de saída de servidor SMTP (MTA Selor)

Servidor de e-mail no Linux com MTA Sceo

MTA Selor: Servidor de E-mails - Novo Projeto GPL

Leitura recomendada

Relay autenticado para Postfix no Debian

Migração Zimbra com Zextras Migration Tool

Integrando o Postfix + SpamAssassin + Fetchmail + Procmail + MS Exchange

Servidor de e-mail Postfix + MySQL + Dovecot + Cyrus

Qmail + Patches + Performance Tuning, the Debian AMD64 way

  
Comentários
[1] Comentário enviado por leoberbert em 10/10/2010 - 03:59h

Excelente Artigo...

Está de parabéns!

[2] Comentário enviado por fmpfmp em 15/10/2010 - 16:01h

Só faltou a instalação de um sistema de Webmail para completar o artigo.

[3] Comentário enviado por obernan em 13/12/2010 - 20:26h

Valeu brother, muito bom seu tuto, obrigado !!!!

[4] Comentário enviado por ricardoschet em 08/03/2013 - 13:35h

Uso e recomendo


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts