Ir para o conteúdo
ou

Software livre Brasil

Tela cheia
 Feed RSS

Alexos Core Labs

27 de Maio de 2009, 0:00 , por Software Livre Brasil - | Ninguém está seguindo este artigo ainda.
Licenciado sob GNU FDL

Alta disponibilidade e segurança com Nginx e Naxsi

4 de Maio de 2013, 0:00, por Software Livre Brasil - 0sem comentários ainda

Além de servir como um servidor web leve e versátil o Nginx é muito poderoso como proxy-reverso. Também podemos utilizá-lo como um sistema de balanceamento de carga de excelente performance.

Neste post mostrarei como criar um ambiente não só de balanceamento de carga com failover, como também irei incrementá-lo com uma camada de segurança usando o WAF Naxsi.

nginxha

Instalação

aptitude install nginx-naxsi

Habilitar o balanceamento de carga é muito simples bastando para isso incluir a diretiva upstream no vhost do site. Ele possibilita diversos tipos de configurações:

Esse é caso mais simples onde os backends serão tratados como um único host.

upstream acme {
        server 192.168.0.2;
        server 192.168.0.3;
        server 192.168.0.4; 
        }

A entidade acme agora será tratada como upstream servindo de referência para o parâmetro proxy_pass como mostra o exemplo abaixo:

server {
  listen acme:80;
  access_log /var/log/nginx/nginx.log;
  
  location / {
    proxy_pass http://acme;
  }
}

Para o cliente sempre manter a conexão no mesmo backend utiliza-se o parâmetro hash_ip.

upstream acme {
        hash_ip;
        server 192.168.0.2;
        server 192.168.0.3;
        server 192.168.0.4; 
        }

Prioridade e Failover

Para definir a prioridade de cada backend utiliza-se o parâmetro weight o valor padrão é 1. No exemplo abaixo as 3 primeiras requisições serão enviadas para o servidor 192.168.0.2, a 4a e 5a para o 192.168.0.3 e a 6a. para o 192.168.0.4.

upstream acme {
        hash_ip;
        server 192.168.0.2 weight=3;
        server 192.168.0.3 weight=2;
        server 192.168.0.4; 
        }

O failover é habilitando usando os parâmetros max_fails define o total de falhas na requisição e fail_timeout define o intervalo de tempo entre as falhas a partir dai a requisição é enviada para o próximo backend.

upstream acme {
        hash_ip;
        server 192.168.0.2 max_fails=3  fail_timeout=30s;
        server 192.168.0.3;
        server 192.168.0.4; 
        server 192.168.0.5 down;
        }

O parâmetro down é utilizado quando um backend está inacessível.

Naxsi

O Naxsi é um Web Application Firewall para o Nginx criado pelo Thibault Koechlin. Uma das grandes vantagens é que ele segue o modelo positivo de segurança aprendendo como a aplicação funciona e criando regras baseadas no comportamento (whitelist-based), ele não utiliza assinatura dos ataques (blacklist-based) como um AV por exemplo.

Habilitar esse WAF é muito simples bastando apenas adicionar a seguinte linha no arquivo nginx.conf:


include /etc/nginx/naxsi_core.rules;

E no arquivo do vhost

 location / {
     include    /etc/nginx/naxsi.rules;
     proxy_pass  http://acme/;
     ...
     }

#Naxsi Learning Mode 

  location /RequestDenied {
   proxy_pass http://127.0.0.1:4242;
   }

A opção Learning Mode permite ao Naxsi aprender o funcionamento da aplicação criando novas regras de whitelist.

Outra ferramenta bastante útil é o nx_util, ele é um parser que lê o arquivo de erro dos sites, atualiza uma base de dados sqlite, gera novas regras de whitelist e exporta os dados para a tela ou para um arquivo html muito bacana.

wget https://naxsi.googlecode.com/files/nx_util-0.3.tgz
tail /var/log/nginx/acme.error.log | nx_util.py -d naxsi_ui -l -i -o -H /var/www/acme.html

naxsi_ui

Visualizando os dados na console

tail /var/log/nginx/naxsi.error.log | nx_util.py -d naxsi_ui -l -i -o
Using stdin.
Committing to db ...
########### Optimized Rules Suggestion ##################
# total_count:1 (50.0%), peer_count:1 (100.0%) | simple quote
BasicRule wl:1306 "mz:$URL:/vulnerabilities/sqli/|$ARGS_VAR:id";
# total_count:1 (50.0%), peer_count:1 (100.0%) | simple quote
BasicRule wl:1013 "mz:$URL:/vulnerabilities/sqli/|$ARGS_VAR:id";

OBS1: Para acessar o html utilizei o lighttpd configurando-o na porta 8080.

OBS2: Para evitar problemas com o WordPress existem regras específicas que podem ser encontradas neste blog

Abaixo seguem os arquivos de configuração completos:

Nginx

/etc/nginx/nginx.conf
user  nginx;
worker_processes  4;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;

    tcp_nodelay on;

    gzip  on;
    gzip_disable "MSIE [1-6]\.(?!.*SV1)";

    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;

# Protecao contra DoS
    client_body_buffer_size 1K;
    client_header_buffer_size 1k;
    client_max_body_size 2M;
    large_client_header_buffers 2 1k;
    client_body_timeout 10;
    client_header_timeout 10;
    keepalive_timeout 5 5;
    send_timeout 10;

    server_tokens off;

    proxy_set_header   Host             $host;
    proxy_set_header   X-Real-IP        $remote_addr;
    proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;

    proxy_max_temp_file_size 0;

    proxy_connect_timeout      90;
    proxy_send_timeout         90;
    proxy_read_timeout         90;

    proxy_buffer_size          4k;
    proxy_buffers              4 32k;
    proxy_busy_buffers_size    64k;
    proxy_temp_file_write_size 64k;
    proxy_cache_methods GET HEAD POST;

# Naxsi WAF

    include /etc/nginx/naxsi_core.rules;

}

Vhost

/etc/nginx/sites-available/acme
upstream acme {
        hash_ip;
        server 192.168.0.2 weight=5;
        server 192.168.0.3 max_fails=3  fail_timeout=30s;
        server 192.168.0.4; 
        }

server {
    listen       80;
    server_name  acme;

    access_log  /var/log/nginx/acme.access.log  main;
    error_log  /var/log/nginx/acme.error.log;

    location / {
     include    /etc/nginx/naxsi.rules;
     proxy_pass  http://acme/;
     proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
     proxy_redirect off;
     proxy_buffering off;
     proxy_set_header        Host            $host;
     proxy_set_header        X-Real-IP       $remote_addr;
     proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;	
}

#Naxsi Learning Mode 

  location /RequestDenied {
   proxy_pass http://127.0.0.1:4242;
   }
}


Criando regras para ips dinâmicos no iptables

23 de Abril de 2013, 0:00, por Software Livre Brasil - 0sem comentários ainda

<p>Uma boa prática de segurança é limitar o acesso a consoles administrativas ou conteúdo privado para origens específicas, mas como fazer isso no iptables quando seu ip é dinâmico?</p> <p>Existe um <a href="http://l7-filter.sourceforge.net/HOWTO">patch</a> que amplia o suporte do iptables até a camada de aplicação, só é que necessário recompilar o kernel o que dá um certo trabalho.</p> <p>Passei pelo mesmo problema e encontrei uma solução que vem funcionando muito bem. </p> <p>Usando os scripts abaixo as regras do iptables serão atualizadas sempre que houver mudança no ip de origem.</p> <p><strong>RedHat e derivados</strong></p> <p>Crie o arquivo <strong><em>/usr/bin/dynamic_iptables.py</em></strong> com o conteúdo abaixo. Ele será responsável por verificar se o ip foi modificado e irá reiniciar o iptables.</p> <p>Altere o valor da variável <strong>home_dyndns</strong> com o nome do host criado no seu serviço de DNS dinâmico ( e.g. no-ip ou dyndns )</p> <pre><code>#!/usr/bin/python import os def gettextoutput(cmd): """Return (status, output) of executing cmd in a shell.""" pipe = os.popen('{ ' + cmd + '; } 2>&#038;1', 'r') pipe = os.popen(cmd + ' 2>&#038;1', 'r') text = pipe.read() if text[-1:] == '\n': text = text[:-1] return text home_dyndns = "acme.no-ip.org" log_dyndns = "/tmp/iptables_noip_update.log" last_dyndns = gettextoutput("cat " + log_dyndns) cur_dyndns = gettextoutput("host " + home_dyndns) print "Log: "+ last_dyndns print "Cur: "+ cur_dyndns if last_dyndns == cur_dyndns: print "IPs match, no restart necessary" else: print "Updating last IP with current" os.system("echo '" + cur_dyndns + "' > " + log_dyndns) print "Restarting iptables to update" os.system("/etc/init.d/iptables restart") </code></pre> <p>Crie o arquivo <em><strong>/usr/bin/update_rules.sh</strong></em> que será responsável pela atualização das regras do iptables com o novo endereço de origem.</p> <p>Altere o valor da variável <em><strong>HOSTNAME</strong></em> com o nome do host criado no seu serviço de DNS dinâmico ( e.g. no-ip ou dyndns )</p> <pre><code>#!/bin/bash HOSTNAME=acme.no-ip.org LOGFILE=/tmp/iptables_noip_update.log Current_IP=$(host $HOSTNAME | cut -f4 -d' ') if [ $LOGFILE = "" ] ; then iptables -I INPUT -i eth0 -s $Current_IP -j ACCEPT echo $Current_IP > $LOGFILE else Old_IP=$(cat $LOGFILE) if [ "$Current_IP" = "$Old_IP" ] ; then echo "IP address has not changed" else iptables -D INPUT -i eth0 -s $Old_IP -j ACCEPT iptables -I INPUT -i eth0 -s $Current_IP -j ACCEPT echo $Current_IP > $LOGFILE echo "iptables have been updated" fi </code></pre> <p>No Redhat as regras do iptables são armazenadas no arquivo <em><strong>/etc/sysconfig/iptables</strong></em> criado usando o comando <em>iptables-save</em>. Quando o serviço for reiniciado as regras contidas neste arquivo serão reaplicadas. </p> <p><strong>Debian e derivados</strong></p> <p>Para rodar no Debian foi preciso fazer pequenas adaptações nos scripts. </p> <p>Crie o arquivo <strong><em>/usr/bin/dynamic_iptables.py</em></strong> com o conteúdo abaixo. </p> <p>Altere o valor da variável <strong>home_dyndns</strong> com o nome do host criado no seu serviço de DNS dinâmico ( e.g. no-ip ou dyndns )</p> <pre><code>#!/usr/bin/python import os def gettextoutput(cmd): """Return (status, output) of executing cmd in a shell.""" pipe = os.popen('{ ' + cmd + '; } 2>&#038;1', 'r') pipe = os.popen(cmd + ' 2>&#038;1', 'r') text = pipe.read() if text[-1:] == '\n': text = text[:-1] return text home_dyndns = "acme.no-ip.org" log_dyndns = "/tmp/iptables_noip_update.log" last_dyndns = gettextoutput("cat " + log_dyndns) cur_dyndns = gettextoutput("host " + home_dyndns) print "Log: "+ last_dyndns print "Cur: "+ cur_dyndns if last_dyndns == cur_dyndns: print "IPs match, no restart necessary" else: print "Updating last IP with current" os.system("echo '" + cur_dyndns + "' > " + log_dyndns) </code></pre> <p>Crie o arquivo <em><strong>/usr/bin/update_rules.sh</strong></em>.</p> <p>Altere o valor da variável <em><strong>HOSTNAME</strong></em> com o nome do host criado no seu serviço de DNS dinâmico ( e.g. no-ip ou dyndns )</p> <pre><code>#!/bin/bash HOSTNAME=acme.no-ip.org LOGFILE=iptables_noip_update.log Current_IP=$(host $HOSTNAME | cut -f4 -d' ') if [ $LOGFILE = "" ] ; then iptables -I INPUT -i eth0 -s $Current_IP -j ACCEPT echo $Current_IP > $LOGFILE else Old_IP=$(cat $LOGFILE) iptables -D INPUT -i eth0 -s $Old_IP -j ACCEPT iptables -I INPUT -i eth0 -s $Current_IP -j ACCEPT echo $Current_IP > $LOGFILE echo "iptables have been updated" fi </code></pre> <p><strong>Agendamento</strong></p> <p>Para automatizar o processo de atualização crie agendamentos no <em><strong>/etc/crontab</strong></em> ou no crontab do usuário root usando o comando <strong>sudo crontab -e</strong></p> <pre><code>* 8 * * * /usr/bin/dynamic_iptables.py > /tmp/dynamic_iptables.log * * * * * /usr/bin/update_rules.sh > /tmp/dynamic_rules.log </code></pre> <p><strong>Referências</strong></p> <p><a href="http://diginc.us/linux/2010/using-iptables-with-dynamic-ip-hostnames-like-dyndns-org/">Using IPTables with Dynamic IP hostnames like dyndns.org</a></p> <p><a href="http://l7-filter.sourceforge.net/HOWTO">L7-filter Kernel Version HOWTO</a></p> <div class="crp_related"><h3>Related Posts:</h3><ul><li><a href="http://blog.alexos.com.br/2011/08/05/protecao-contra-portscans-com-ossec-hids-e-portsentry/" class="crp_title">Proteção contra portscans com Ossec HIDS e Portsentry</a></li><li><a href="http://blog.alexos.com.br/2011/01/20/lamp-implementando-um-servidor-lamp-seguro/" class="crp_title">LAMP++ &#8211; Implementando um servidor LAMP seguro (&hellip;</a></li><li><a href="http://blog.alexos.com.br/2012/09/21/testando-a-ferramenta-de-protecao-multi-tarefa-artillery/" class="crp_title">Testando a ferramenta de proteção multi-tarefa Artillery</a></li><li><a href="http://blog.alexos.com.br/2011/04/30/case-bloqueando-um-http-ddos-com-modsecurity-ossec-e-iptables/" class="crp_title">Case &#8211; Bloqueando um HTTP DDoS com ModSecurity, Ossec&hellip;</a></li><li><a href="http://blog.alexos.com.br/2013/05/04/alta-disponibilidade-e-seguranca-com-nginx-e-naxsi/" class="crp_title">Alta disponibilidade e segurança com Nginx e Naxsi</a></li></ul></div>



Otimizando a detecção de ataques de SQLi com evasão do Ossec HIDS

19 de Abril de 2013, 0:00, por Software Livre Brasil - 0sem comentários ainda

SQL injection é uma das vulnerabilidades mais difundidas e exploradas em aplicações Web, não é muito difícil encontrar esta falha em diversos CMSs, plugins e códigos de sites espalhados pela internet.

 

Ferramentas de proteção como WAFs e IDS/IPS possuem regras que alertam ou bloqueiam este tipo de ataque, porém existem diversas técnicas evasivas que permitem o concretização do ataque como:

 

  • White Space Manipulation;
  • URL encoding;
  • Unicode/UTF-8;
  • Hex Encoding;
  • char() function;
  • Comment Exploitation;
  • Concatenation, etc.

O SQLmap, uma das melhores ferramentas para este tipo de ataque, possui um pool de scripts de evasão ( tamper ) bastante interessante.

 

Aproveitei o laboratório da apresentação que farei no Flisol para melhorar a detecção destes ataques e acabei criando algumas regras que otimizaram o tempo de identificação e o bloqueio. As regras atuais conseguem identificar o ataque, porém o delay entre a identificação e o bloqueio é um pouco alto, usando mais de um tamper e outras opções como o aumento do intervalo das requisições por exemplo piora ainda mais detecção.

 

Estas novas regras foram aprovadas pelo upstream do Ossec HIDS estando disponíveis no repositório do projeto e serão publicadas juntamente com a nova versão que está na versão alfa.

 

Quem estiver interessado em utilizar ou testar apenas adicione as linhas abaixo no arquivo /var/ossec/rules/local_rules.xml.

 

<group name=”attack,sqlinjection,”>

   <rule id=”160001″ level=”6″>

     <if_sid>31100</if_sid>

<url>=%27|select%2B|insert%2B|%2Bfrom%2B|%2Bwhere%2B|%2Bunion%2B</url>

     <description>SQL injection attempt.</description>

   </rule>

   <rule id=”160002″ level=”6″>

     <if_sid>31100</if_sid>

<url>%EF%BC%87|%EF%BC%87|%EF%BC%87|%2531|%u0053%u0045</url>

    <description>SQL injection attempt.</description>

   </rule>

</group>

Sugestões e melhorias serão sempre bem vindas! =P



Linode Pwned!

16 de Abril de 2013, 0:00, por Software Livre Brasil - 0sem comentários ainda

Hoje o Linode anunciou que seu ambiente de administração de servidores foi invadido. O cracker “ryan” que se diz do grupo HTP ( Hack the Planet ) assumiu a autoria do ataque com o objetivo obter informações de cartões de crédito e senhas de acesso.

Segundo o anúncio os dados dos cartões são mantidos criptografados usando chave pública e privada dentro do banco de dados e as chaves públicas são auto-encriptadas com senhas complexas. Além destas informações o cracker obteve acesso nos servidores web e “parte” do código-fonte das aplicações do Linode.

A falha explorada do Adobe ColdFusion ( CVE-2013-1387, CVE-2013-1388) foi recentemente divulgada e corrigida, ela permite o ‘bypass’ da autenticação na console administrativa.

Para os usuários deste datacenter é recomendando acompanhar as informações do cartão de crédito cadastrado, trocar a senha de acesso da dashboad usando senhas complexas, monitorar o consumo de recursos do servidor e rezar.

Para os usuários do ColdFusion é de extrema importância a atualização do ambiente, já que após explorado o servidor poderá ser utilizado para práticas criminosas ( Spam, botnet, etc ).

Não fico surpreso com esta notícia, já que a gestão de vulnerabilidades é quase que totalmente negligenciada por todos, seja ele um grande ou pequeno provedor.

Referências:

CVE-2013-1387

CVE-2013-1388

Hackers Claim to Have Gained Access to Linode Customer Passwords, Credit Cards

Blog Linode – Security Incident Update

Adobe Security Bulletin



Habilitando o HSTS no Apache e Nginx (Atualizado)

26 de Novembro de 2012, 0:00, por Software Livre Brasil - 0sem comentários ainda

O HTTP Strict Transport Security ou HSTS (RFC 6797) é um novo padrão de segurança SSL aprovado recentemente pelo IETF. Ele traz diversas melhorias para o SSL como forçar a utilização do HTTPS impedindo que sites sejam acessados usando o protocolo HTTP ou que partes do código de um site que está usando HTTPS seja executado em servidores usando o HTTP entre outras.

Este protocolo já é utilizado pelo Google,Paypal,Twitter e outros sites, porém necessita da adoção em massa para se tornar um padrão de fato. Ativá-lo é muito simples e ele substitui a utilização do redirecionamento forçado do HTTP para HTTPS.

No Apache

Habilite o módulo mod_headers

a2enmod headers

Adicione o seguinte parâmetro no VHOST do site

Header add Strict-Transport-Security “max-age=15768000″

ou

Strict-Transport-Security: max-age=15768000 ; includeSubDomains

O parâmetro max-age define para o navegador o período de validade em segundos que o HTTPS será forçado, nesse caso serão 6 meses.
O parâmetro includeSubDomains indica que esta regra valerá para os subdominios.

No Nginx

Adicione o seguinte parâmetro no arquivo de configuração do Nginx

add_header Strict-Transport-Security max-age=15768000;

Dica: Use Qualys SSL Server Test para testar se HSTS está funcionando corretamente.

Referências

Owasp HTTP Strict Transport Security

Novo padrão promete aumentar proteção de sites seguros

Firefox 4: HTTP Strict Transport Security (force HTTPS)

Protecting your users from phishing with Apache rules and HSTS



Tags deste artigo: linux security free software segurança hardening hacking sysadmin