Assine a Lista Dicas-L
Receba diariamente por email as dicas
de informática publicadas neste site
Para se descadastrar, clique aqui.
Case - Bloqueando um HTTP DDoS com ModSecurity, Ossec e Iptables
Colaboração: Alexandro Silva
Data de Publicação: 05 de maio de 2011
Recentemente tive uma experiência pra lá de interessante e estressante. Num dia que aparentava estar muito tranquilo me avisam que detectaram uma lentidão muito grande ao acessar o site de um cliente.
Verificando algumas informações do sistema detectei cerca de 14000 conexões na porta 80 o que me deixou um pouco espantando porque era uma situação totalmente atipica
netstat awt | grep 80 | wc -l 14345
Isto estava causando um crash no servidor de banco porque ele não estava conseguindo dar vazão a tantas tentativas ocorrendo simultaneamente.
1ª ação - Parar o serviço respirar fundo e tentar isolar o problema.
Como neste mesmo servidor existiam outros sites inicialmente tive que detectar qual era o site alvo, após alguns testes encontrei o infame.
2ª ação - Mover o site para outro servidor e substituir o ip.
Movi o site para outra máquina evitando que os outros sites fossem afetados, porém quando liberei a porta 80 para o mundo o inferno começou novamente. O load average do servidor conseguiu chegar a 300 em questão de minutos.
3ª ação - Estudar o log e tomar as medidas cabiveis
Numa rápida olhada no log do apache detectei a assinatura do ataque
111.111.111.111 - - [26/Apr/2011:17:01:00 -0300] "GET /?WWW.ATARDE.COM.BR HTTP/1.0" 400 415 "-" "User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; Creative AutoUpdate v1.40.02)"
O IDS da rede detectou este ataque como DOUBLE USER-AGENT attack. Como ele vinha de várias origens dinamicamente, bloquear os ips era uma tarefa árdua, então tive que resolver no servidor mesmo.
4ª ação - Medidas emergenciais
Como o tempo para raciocinar era muito pouco realizei algumas tentativas não tão eficazes porém contornava um pouco essa situação
Como a assinatura do ataque não mudava foi fácil criar uma regra de iptables através de expressão regular. Ela não é de minha autoria, sou péssimo nesse quesito.
tail -f /var/log/apache2/www.hackme.com.br-access.log | grep [aA][Tt][aA][rR][dD][eE] | awk '{print "iptables -A INPUT -s "$1" -j REJECT"}' | sh &
Usar o REJECT não é muito elegante em se tratando de regras de firewall porque ele aumenta o consumo de memória porém o DROP não estava funcionando.
Exemplo de uma origem ( zumbi ) bloqueada:
REJECT all -- 1-48.94.187.totvs.com.br anywhere reject-with icmp-port-unreachable
Com isso tive que fazer um upgrade de memória poque o iptables estava brocando tudo.
5ª ação - Medidas emergenciais ( Snort+FWsnort )
Resolvi por o snort em conjunto com o fwsnort para bloquear os ataques. Dá um pouco de trabalho mas ele conseguiu pegar algumas origens, o problema é que o próprio ataque já estava exaurindo os recursos da máquina juntamente com o iptables e eu ainda jogo o snort+mysql+fwsnort. Ai lascou tudo, tive que voltar a prancheta.
6ª. ação - Algumas horas depois... ModSecurity e tunning do Apache
Vocês devem estar fazendo o seguinte questionamento: "Sim. E onde entra o Ossec nisso tudo????"
O Ossec estava bloqueando, porém como a assinatura do ataque era um pouco específica, ele não estava bloqueando todas as origens. Tentei criar uma personal rule mas já era 03:00 da madruga e eu não estava enxergando nem raciocinando.
Com certeza com a criação da regra baseada na assinatura do ataque ele seria muito mais efetivo. Como isso não era possível no momento, parti para a guerra fazendo um tuning do Apache e usando o Modsecurity.
Tunning
vim /etc/apache2/apache2.conf
ServerLimit 4000 MaxClients 4000
ModSecurity
aptitude install libapache2-mod-security2
vim /etc/apache2/conf.d/modsecurity.conf
< IfModule mod_security2.c>
SecRuleEngine On
SecDebugLog /var/log/apache2/modsec_debug.log
SecDebugLogLevel 0
# Serial audit log
SecAuditEngine RelevantOnly
SecAuditLogRelevantStatus ^5
SecAuditLogParts ABIFHZ
SecAuditLogType Serial
SecAuditLog /var/log/apache2/modsec_audit.log
# if there where more than 5 requests per second for this IP
# set var block to 1 (expires in 5 seconds) and increase var blocks by one (expires in an hour)
SecRule ip:requests "@eq 5" "phase:1,pass,nolog,setvar:ip.block=1,expirevar:ip.block=5,setvar:ip.blocks=+1,expirevar:ip.blocks=3600"
# if user was blocked more than 5 times (var blocks>5), log and return http 403
SecRule ip:blocks "@ge 5" "phase:1,deny,nolog,logdata:'req/sec: %{ip.requests}, blocks: %{ip.blocks}',status:403"
# if user is blocked (var block=1), log and return http 403
SecRule ip:block "@eq 1" "phase:1,deny,nolog,logdata:'req/sec: %{ip.requests}, blocks: %{ip.blocks}',status:403"
SecRule REQUEST_LINE "^GET?\WWW\.ATARDE\.COM\.BR$ HTTP"\
"nolog,deny,setvar:ip.ddos=+1,deprecatevar:ip.ddos=100/10"
</IfModule>
</blockquote>
A regra abaixo foi a que bloqueou os ataques. As outras foram só para encher linguiça.
**SecRule REQUEST_LINE "^GET?\WWW\.ATARDE\.COM\.BR$ HTTP"\ "nolog,deny,setvar:ip.ddos=+1,deprecatevar:ip.ddos=100/10"**
As referências abaixo me ajudaram muito:
- http://blog.cherouvim.com/simple-dos-protection-with-mod_security/
- http://spamcleaner.org/en/misc/flood-http-mod_security.html
- http://www.howtoforge.com/apache2_mod_security_debian_etch
Às 04:00 da madruga as coisas se estabilizaram, o acesso ao site foi normalizado e o load não passava de 1.00. Com certeza essa não foi a forma mais elegante de bloquear este tipo de ataque, acredito que um IPS na borda ajudaria muito na resolução e prevenção, porém temos que trabalhar com as ferramentas disponíveis e usar a criatividade.
Referências Adicionais
Referências adicionais sobre os assuntos abordados neste site podem ser encontradas em nossa Bibliografia.
Avalie esta dica
Opinião dos Leitores
03 Jun 2011, 01:32
o script mandava o Cpanel executar uma terefa de log,,, isso ocorria centenas de vez por dia... e acabava com a memoria... dai travava
ele bloqueou a tarefa, então sempre que o servidor tenta iniciar a tarefa, o proprio serv cancela.
Entao o que acontece é nao tenho ideia de como fazer isso. Alguem poderia me dar alguma informação?
obrigado
09 Mai 2011, 21:37
O ATarde não era o alvo, o GET que aparece no log vinha das máquinas atacantes.
Não sei por que cargas d'agua esse troço apareceu assim.
Isso não aconteceu no ATarde foi em outro local.
Abs,
Alexos
06 Mai 2011, 08:20
Meu servidor uso de Debian, esse seu comando não mostrou "grep 80" verifique-se o /etc/services
Meu comando:
netstat -awt | grep www | wc -l
netstat -awt | grep https | wc -l
05 Mai 2011, 19:10
Eu teria omitido o nome do site cliente...
O modulo recent do IPTables não teria resolvido isso? No meu caso foi suficiente para um servidor smtp em condições parecidas.
Valeu!
05 Mai 2011, 09:02
Resolveria seu problema sem esse trauma todo!
05 Mai 2011, 08:20
Eh, os ataques continuam, ficar altas horas pra livrar deles e depois ainda reeditar cada etapa pra ajudar os menos desprovidos de técnica, é incrível.
Valeu pelo post,
Deus cuide de você muito mais do que cuidamos do PC
Parabéns, Alexandro
02 Mai 2011, 10:07
O Ataque devia ser algo muito leve.
Ja tive clientes que sofreram com DDoS de grandes proporções, é praticamente impossível parar um ataque desses só com essas medidas.
Mesmo assim, o artigo foi bem escrito.
Parabéns !




