image1 image2 image3 image4 image5 image6 image7 image8 image9 image10

O dia em que sofri um ataque de DDoS

Terror da Internet, os ataques de DDoS ficaram em evidência ultimamente por causa dos grupos AnonOps e LuzSec, que atacaram vários sites usando essa técnica.  

DDoS nada mais é que um ataque do tipo "estouro de boiada".  Utilizando máquinas contaminadas, usa-se um programa "administrador" que envia o agendamento do ataque, com data e horário, para uma máquina de destino.  No caso esse destino foi num dos servidores que administro.  Por acaso onde está o serviço do http://eri.cx entre outros.

O ataque não foi dirigido diretamente à mim, mas um dos sites hospedados lá (não, não foi pro eri.cx).  Durante um ataque DDoS, isso não importa muito pois tudo que está hospedado no servidor é afetado juntamente.  Ou os serviços tornam-se indisponíveis ou a máquina pode travar, o que não deveria acontecer.   Mas um ataque DDoS não abre brechas pra invasão ou algo do gênero.

Felizmente conseguimos mitigar o ataque e minizar seus efeitos com algumas medidas bem simples, que são descritos aqui.

Comecei a suspeitar que algo estava errado quando recebi a mensagem abaixo, da lista de discussão que é mantida nesse servidor.

 

From: Mail Delivery System <Este endereço de email está sendo protegido de spambots. Você precisa do JavaScript ativado para vê-lo.>
Date: 2011/7/1
Subject: Undelivered Mail Returned to Sender
To: Este endereço de email está sendo protegido de spambots. Você precisa do JavaScript ativado para vê-lo.


This is the mail system at host domain.server.com.

I'm sorry to have to inform you that your message could not
be delivered to one or more recipients. It's attached below.

For further assistance, please send mail to postmaster.

If you do so, please include this problem report. You can
delete your own text from the attached returned message.

                  The mail system

<Este endereço de email está sendo protegido de spambots. Você precisa do JavaScript ativado para vê-lo.>: Command time limit exceeded: "/var/lib/mailman/mail/mailman
   post list"

Imediatamente tentei conectar no servidor e... nada.  Página web igualmente fora do ar.  Achei que poderia ser algum problema de hardware ou mesmo da máquina virtual.  Entrei em contato com a pessoa que tinha o acesso console na máquina e pedi para verificar o que estava acontecendo.

Momentos depois recebi o contato da pessoa avisando que a máquina estava travada e não conseguia dar boot: ela voltava a travar instantes depois.  Nesse momento imaginei que podia ser um ataque.

Pedi então para dar boot em "single mode" e desabilitar acesso ao apache e mysql e tentar o boot normalmente.  Felizmente deu certo, pois ataques DDoS são fortes em volume, mas não muito inteligentes e refinados.

Utilizando o tcpdump, demos uma olhada no tipo de tráfego que chega e vimos que o ataque era direcionado prioritariamente à porta 80 (web):

17:57:01.220234 IP 115.214.63.123.2844 > server.80: Flags [.], ack 1863118067, win 65306, length 0
17:57:01.237522 IP 115.214.63.123.2844 > server.80: Flags [F.], seq 0, ack 1, win 65306, length 0
17:57:01.237582 IP server.80 > 115.214.63.123.2844: Flags [.], ack 1, win 6432, length 0
17:57:01.241481 IP 86.96.227.91.39237 > server.80: Flags [.], ack 1882163284, win 65535, length 0
17:57:01.241527 IP 86.96.227.91.39237 > server.80: Flags [P.], seq 0:285, ack 1, win 65535, length 285
17:57:01.241573 IP server.80 > 86.96.227.91.39237: Flags [.], ack 285, win 6432, length 0
17:57:01.269729 IP server.80 > 86.96.227.91.39237: Flags [.], seq 1:1461, ack 285, win 6432, length 1460
17:57:01.269774 IP server.80 > 86.96.227.91.39237: Flags [P.], seq 1461:2802, ack 285, win 6432, length 
1341

Vários pedidos de início de conexão, sem resposta.

O efeito do ataque pode ser visto nesse gráfico, entre as semanas 26 e 27:

Olhando nos logs do apache, pudemos identificar qual o domínio que estava sob ataque.  Confirmamos com tcpdump também que boa parte do ataque buscava tal domínio pelo DNS, verificando o tráfego na porta 53.  Então tomei a primeira providência para mitigar o ataque: troquei os IPs do domínio no DNS para 127.0.0.1 (loopback).

Como anúncios de DNS demoram um pouco para serem propagados, essa solução começou a mostrar um pouco mais de eficiência somente depois de 1 hora.  Mas isso reduziu o ataque na ordem de 60%, ou até mais.

O DNS seria suficiente, mas o ataque poderia voltar buscando somente o IP e esse truque não iria ajudar muito.  Então comecei a olhar como estava configurado o servidor Apache, pois um servidor Unix (ou Linux no caso) não pode travar por conta de um ataque desses, a menos que tenha alguma configuração incorreta.

Como o gráfico mostra, o servidor Apache com suas configurações padrão não foi afetado pelo ataque.  Vários processos foram criados, mas finalizados em seguida.

Tentei então verificar como estava o sistema durante o ataque, para tentar identificar o que o ataque tinha ocasionado para travar.

Como os gráficos mostram, o ataque não causou nenhum uso excessivo de CPU ou do sistema.  Nada que pudesse levar a máquina ao travamento.  Mas o servidor travava com o serviço do Apache ligado.  Então resolvi olhar os parâmetros TCP do sistema.

Essa imagem me deu a noção clara que os recursos de redes estavam sendo usados em excesso.  Mas mesmo isso não deveria causar o travamento de servidor.

Então resolvi olhar como estava o firewall.

 

A imagem que ajudou a entender o problema foi a de ipconntrack.  Como o netfilter (iptables) utiliza um modo "stateful", cada pacote que entra no sistema ocupa uma posição de memória, para poder identificar (e liberar) as conexões restantes vindas dessa origem.  Como o sistema estava sob ataque, a posição era alocada, mas ficava parada aguardando o fim da conexão, que não acontecia.  Pra piorar a situação, o firewall alocava memória e recursos do sistema em kernel level, motivo pelo qual o sistema travava.

Para mitigar esse problema, alteramos os parâmetros de kernel com sysctl da seguinte forma:

 

net.netfilter.nf_conntrack_generic_timeout=5
net.netfilter.nf_conntrack_tcp_timeout_syn_sent=120
net.netfilter.nf_conntrack_tcp_timeout_syn_recv=10
net.netfilter.nf_conntrack_tcp_timeout_established=10
net.netfilter.nf_conntrack_tcp_timeout_fin_wait=5
net.netfilter.nf_conntrack_tcp_timeout_close_wait=3
net.netfilter.nf_conntrack_tcp_timeout_last_ack=10
net.netfilter.nf_conntrack_tcp_timeout_time_wait=5
net.netfilter.nf_conntrack_tcp_timeout_close=10
net.netfilter.nf_conntrack_tcp_timeout_max_retrans=300
net.netfilter.nf_conntrack_tcp_timeout_unacknowledged=300
net.netfilter.nf_conntrack_tcp_loose=1
net.netfilter.nf_conntrack_tcp_be_liberal=0
net.netfilter.nf_conntrack_tcp_max_retrans=3
net.netfilter.nf_conntrack_udp_timeout=30
net.netfilter.nf_conntrack_udp_timeout_stream=180
net.netfilter.nf_conntrack_icmp_timeout=30
net.netfilter.nf_conntrack_icmpv6_timeout=30
net.netfilter.nf_conntrack_frag6_timeout=60
net.netfilter.nf_conntrack_frag6_low_thresh=196608
net.netfilter.nf_conntrack_frag6_high_thresh=262144
net.netfilter.nf_conntrack_acct=1
net.netfilter.nf_conntrack_events=1
net.netfilter.nf_conntrack_events_retry_timeout=15
net.netfilter.nf_conntrack_max=15876
net.netfilter.nf_conntrack_count=254
net.netfilter.nf_conntrack_buckets=4096
net.netfilter.nf_conntrack_checksum=1
net.netfilter.nf_conntrack_log_invalid=0
net.netfilter.nf_conntrack_expect_max=64
net.core.somaxconn=128
net.ipv4.netfilter.ip_conntrack_generic_timeout=5
net.ipv4.netfilter.ip_conntrack_tcp_timeout_syn_sent=120
net.ipv4.netfilter.ip_conntrack_tcp_timeout_syn_sent2=120
net.ipv4.netfilter.ip_conntrack_tcp_timeout_syn_recv=20
net.ipv4.netfilter.ip_conntrack_tcp_timeout_established=10
net.ipv4.netfilter.ip_conntrack_tcp_timeout_fin_wait=5
net.ipv4.netfilter.ip_conntrack_tcp_timeout_close_wait=3
net.ipv4.netfilter.ip_conntrack_tcp_timeout_last_ack=10
net.ipv4.netfilter.ip_conntrack_tcp_timeout_time_wait=5
net.ipv4.netfilter.ip_conntrack_tcp_timeout_close=10
net.ipv4.netfilter.ip_conntrack_tcp_timeout_max_retrans=300
net.ipv4.netfilter.ip_conntrack_tcp_loose=1
net.ipv4.netfilter.ip_conntrack_tcp_be_liberal=0
net.ipv4.netfilter.ip_conntrack_tcp_max_retrans=3
net.ipv4.netfilter.ip_conntrack_udp_timeout=30
net.ipv4.netfilter.ip_conntrack_udp_timeout_stream=180
net.ipv4.netfilter.ip_conntrack_icmp_timeout=30
net.ipv4.netfilter.ip_conntrack_max=15876
net.ipv4.netfilter.ip_conntrack_count=254
net.ipv4.netfilter.ip_conntrack_buckets=4096
net.ipv4.netfilter.ip_conntrack_checksum=1
net.ipv4.netfilter.ip_conntrack_log_invalid=0
net.nf_conntrack_max=15876

O padrão de timeout para TCP é de 2 horas.  Alterei para alguns segundos.  Com isso pudemos reiniciar todos os serviços e mitigar totalmente o ataque, tendo a certeza que o servidor não travaria novamente.

 

2017  helio.loureiro.eng.br   globbersthemes joomla templates