sexta-feira, 29 de agosto de 2008

Iptables - Um firewall statefull

No artigo anterior foi descrito as chains e qual o caminho que o pacote percorre dentro do iptables até chegar no sistema operacional e sair pela interface de rede. Agora neste artigo quero falar um pouco sobre uma característica interessante do iptables que é a capacidade do iptables em verificar o estado de um pacote ou não. Você pode me perguntar "Mas o que é isso de verificar o estado do pacote?". Um pacote que chega ao seu firewall pode ser uma resposta para uma conexão web, ftp, dns que tem origem dentro de sua rede ou uma conexão que se originou sem ser requisitada (e possivelmente pode ser uma tentativa maliciosa)! Para ser capaz de distinguir isso o iptables possui uma tabela interna onde verifica esta informação!

Informações dinâmicas como esta estão guardadas em um diretório especial que que se chama proc. É ai que o iptables possui este arquivo. Talvez o nome possa mudar de uma distribuição a outra, mas ele geralmente estará relacionado com conntrack. Tenho um livro comprado a algum tempo e ali ele cita o nome como sendo ip_conntrack_max! Buscando em meu firewall/proxy encontrei 3 ocorrências porém todas elas possuem o mesmo valor (que vamos explicar já já o que ele significa), mantendo uma coerência! Para encontrar esse arquivo executei o seguinte comando:

find /proc -iname *conntrack_max
/proc/sys/net/ipv4/netfilter/ip_conntrack_max
/proc/sys/net/netfilter/nf_conntrack_max
/proc/sys/net/nf_conntrack_max

Caso você mude o valor em qualquer um desses arquivos ela se refletirá nos outros! Então não se dê o trabalho de criar um script para mudar nos três lugares! Estes arquivos só existirão após estar carregado no sistema os módulos de rastreamento de conexão (nf_conntrack, nf_conntrack_ipv4, xt_state, que são carregados automaticamente quando se usa o módulo do iptables state). Os valores contidos nestes arquivos representam o número máximo de conexões que poderão ser rastreadas pelo firewall. Caso você chegue ao valor máximo você verá uma mensagem como esta em seu log:

ip_conntrack: maximum limit of xyz entries exceeded

E novas conexões serão rejeitadas! Você pode mudar esse valor mas geralmente o padrão é algo aceitável. Se você precisa mudar ele existe um arquivo que esta disponível no site da wallfire.org! Ali é explicado os valores padrão e como são calculados.

Um firewall capaz de fazer este tipo de inspeção nos pacotes é de grande auxilio e irá economizar muitas linhas de código para criar algo mais seguro. Sem isso as regras de seu firewall seriam muito mais complexas, além de ter que imaginar inumeras possibilidades de pacotes maliciosos! Claro que essas vantagens vem a um custo, cada nova conexão rastreada por este sistema necessita de 224 bytes de memória adicional! Essa informação você pode verificar ao momento em que os módulos são carregados e será algo como isso aqui:

ip_conntrack version 2.4 (960 buckets, 7680 max) - 224 bytes per conntrack

Se não fosse o valor do arquivo conntrack_max uma rede com muitos usuários de p2p poderia facilmente lotar a memória do servidor! Porém mesmo com este limite redes ponto-a-ponto podem impedir que conexões importantes sejam efetuadas! Por isso use o módulo ipp2p do POM e limite as conexões p2p!

Na prática o comando que permite o iptables verificar o estado de um pacote que chega a interface do firewall é este:

iptables -t tabela -A chain -m state --state ESTABLISHED,RELATED -j ação
Caso você queira que o iptables não tenha esse comportamento não use o módulo state (-m state)! Com isso você precisará escrever regras bem detalhadas para não correr risco de aceitar alguma conexão maliciosa.

Eu espero que este tipo de informação seja útil para esclarecer bem como funciona este poderoso firewall que o linux possui! O que estou explanando até agora é somente teoria de como ele funciona, espero logo chegar na parte mais prática com exemplos interessantes.

quinta-feira, 28 de agosto de 2008

Iptables - Descrição das chains e seu uso na prática

Pretendo que esse seja o primeiro artigo de uma serie que estarei tentando explicar o uso do iptables. Iniciarei explicando as chains padrão do iptables e seu uso na prática. Mostrarei o fluxo que o pacote percorre dentro do iptables até chegar ao sistema operacional ou ao meio de rede. Minha intenção ao criar esse tipo de postagem foi ver que muitas pessoas que me pedem ajuda as vezes não conhecem bem o funcionamento desta ferramenta. Este primeiro post não tem o intuito de mostrar comandos.

A definição que esta no manual do iptables é esta:

Iptables é utilizado para criar, manter e inspecionar as tabelas de filtro de pacotes ip no kernel do linux.

Para que se possa manipular isso de forma eficiente, o iptables criou uma serie de tabelas e cada uma contém chains (cadeias, rotinas) pré-definidas ou criadas pelo usuário que são executadas a medida que os pacotes chegam ao sistema operacional. Abaixo elas estão definidas:

  1. raw - Essa eu nunca usei e por isso não tenho muito conhecimento, porém lendo na documentação disponível on-line da iptables-tutorial eles descrevem que ela tem uma única finalidade que é a de marcar pacotes que não devem ser manipulados pelo sistema de rastreamento de conexões (conntrack). Ela possui duas chains disponíveis que são prerouting e output.
  2. mangle - Esta aqui é muito utilizada para a manipulação de pacotes. Geralmente se usa para mudar (mangle) algum valor como ToS, as marcações FW, TTL entre outros. É aqui que eu por exemplo marco os pacotes para um tratamento diferenciado de QoS em meu proxy/gateway! É altamente recomendado NÃO REALIZAR NENHUM FILTRO nesta tabela, já que existe uma com essa finalidade! Ela possui cinco chains disponíveis que são prerouting, input, forward, output e postrouting.
  3. nat - A função desta tabela é bem sugestiva e ela deve ser utilizada para as necessidades de tradução de endereços de rede (Network Address Translation). É nesta tabela que iremos colocar as regras para compartilhar uma conexão de internet (Masquerade, SNAT) com uma LAN, aqui iremos criar a possibilidade de alguém localizado na internet acesse um recurso interno da DMZ (como um servidor web) e coisas desse genero. Ela possui três chains disponíveis que são prerouting, postrouting e output.
  4. filter - E finalmente temos a tabela filter! Essa é a que deve ser usada para filtrar pacotes, ou seja, permitir ou restringir o acesso! É aqui que você irá verificar a direção de um pacote, o que ele contém e tomar uma ação com ele, seja aceitar ou rejeitar. Ela possui três chains dispoíveis que são input, forward e output.

Agora você me pergunta "e isso tudo que você esta falando ai de prerouting, postouring, forward, para que serve?". Bom essas chains são utilizadas para propósitos específicos dentro do ciclo de vida de um pacote dentro do iptables e das decisões de roteamento do linux, e irei explica-lo agora:

  1. prerouting - Esta chain é a primeira a ser processada pelo iptables em qualquer tabela! Ela tem esse nome pois ela é utilizada antes mesmo do kernel do linux tomar alguma decisão de roteamento baseado em seu endereço de origem/destino, marcas FW, etc. Então se você precisa fazer algo desse genero, aqui é o local!
  2. input - Esta é utilizada ÚNICA e SOMENTE para os pacotes que possuem o endereço de destino o computador/servidor local! Pacotes com outros destinos que não seja esse não serão afetados por essa chain!
  3. forward - Pacotes que passam por aqui possuem endereço de destino que não seja o computador/servidor local! São pacotes destinados por exemplo para a sua LAN, para a internet ou para alguma outra rede que seu linux tenha conectado e que este seja responsável por fazer roteamento. Aqui você pode identificar esses pacotes.
  4. output - Esta chain possui a função de inspecionar os pacotes gerados pelo computador/servidor local! Se você quer proibir que seu computador/servidor local faça ping aqui é o local (tabela filter)!
  5. postrouting - De forma análoga a chain prerouting, esta possui função exatamente oposta a ela. Os pacotes que passam por aqui já tiveram sua decisão de roteamento tomada! Aqui é o local onde se pode aplicar o Masquerade, Snat, Dnat!
Com o fluxograma abaixo eu imagino que esse monte de definições ficará um pouco mais claro:





Bom, eu espero que com essa primeira introdução fique um pouco mais fácil e claro ao momento de criar suas regras de iptables ou quando você estiver procurando solucionar algum problema! Esse é só o primeiro de uma serie em que estarei explicando o funcionamento deste poderoso firewall que é o iptables!

Esta imagem foi retirada do tutorial on-line de iptables hospedado no frozen-tux.

quarta-feira, 27 de agosto de 2008

Usando find + tar para fazer backups

Como todo bom administrador de sistemas, com uma certa regularidade é necessário fazer backup dos arquivos contidos no servidor, ainda mais se for um samba onde pode estar o trabalho de muitos funcionários de sua empresa. É prudente que de tempos em tempos seja feito um backup completo do sistema porém fazer isso de forma regular é muito tedioso, leva tempo e você precisa ter bastante espaço para realizar um backup desse tipo!

Uma forma interessante de realizar backups incrementais é usar a dupla find + tar! O comando find é extremamente poderoso e até pouco tempo comecei a desvendar bem suas funcionalidades e capacidades! Primeiro ele permite que você encontre um arquivo no seu disco com uma variedade de características como:
  • Tempo em horas da última modificação (-mtime n)
  • Tempo em minutos da última modificação (-mmin n)
  • Tempo em minutos desde o último acesso (-amin n)
  • Arquivo pertence a um grupo especifico (-group grupo)
  • Arquivo pertence a um usuário especifico (-user usuário)
  • Arquivo possui um tamanho especifico (-size n[k|M|G])
Existem muitas outras possibilidades e estão todas listadas no manual do find, e com elas é possível encontrar arquivos com características específicas! Com a saída dele é possível usar o tar para criar seu arquivo de backup!

Creio que a parte que pode complicar um pouco em um processo automático de backup usando o find + tar é que arquivos que contém espaços em seus nomes podem não ser guardados corretamente e eu experimentei isso quando fui usar o tar recebendo a saída do find! Ainda bem que existe uma opção que corrige esse problema e o backup é efetuado com sucesso! O comando que utilizei para criar um backup incremental usando o find foi o seguinte:

find /diretorio/de/destino/ -mtime -30 -type f -print0 | xargs -0 tar -rf backup.tar

Com isso eu vou encontrar os arquivos que foram modificados nos últimos 30 dias (-mtime -30) que são arquivos regulares (-type f). O que possibilita a execução deste comando sem erros ao criar o arquivo é "-print0 | xargs -0"! O primeiro argumento, o print0, trata corretamente os espaços em branco nos nomes dos arquivos permitindo o correto processamento destes por programas que utilizam a saída do find. A opção do xargs trata a saída do find exatamente da mesma forma e executa o tar, criando assim um backup dos arquivos encontrados!

O tar por si só possui a funcionalidade de backup incremental, mas eu vejo que usando o find no processo de backup permite uma flexibilidade muito grande para encontrar arquivos específicos em seu disco rígido.

Um passo que nunca esqueço nesse procedimento é o de criar uma verificação de integridade com o md5sum, dessa forma no momento de restaura-lo posso ter a segurança de que os arquivos não foram corrompidos! Essa ferramenta existe em qualquer distribuição moderna de linux.

terça-feira, 26 de agosto de 2008

Usando syslog em shell script com logger

Até pouco tempo atrás em meus scripts shell para ter algum tipo de log das ações que ele estava executando sempre utilizava o comando echo seguido dos redirecionadores de concatenação a um determinado arquivo em algum lugar do sistema de arquivos, geralmente em /var/log.

Não é uma forma muito elegante mas concerteza funciona muito bem e imagino que essa é uma forma bastante utilizada por todos que necessitam as vezes criar algum script shell! Pois bem, procurando e lendo em alguns livros me deparei com um programa que até então não o conhecia; o nome desse aplicativo é logger e com ele é possível interagir com o syslog do sistema permitindo ao seu script logar as ações de forma muito mais profissional.

Mas antes de entrarmos para falar desse programa, vamos mostrar um pouquinho de syslog! O syslog é usado pelo sistema para gerenciar os logs gerados pelos programas instalados, autenticações, o boot do sistema operacional, mensagens do kernel entre outros. O syslog possui divisões que facilitam identificar o que irá para cada arquivo como esta descrito abaixo:

*, auth, authpriv, cron, daemon, ftp, kern, local0-7, lpr, mail, mark, news, syslog, user

E cada um desses recursos possuem vários níveis de severidade que são:

emerg, alert, crit, err, warning, notice, info, debug

A que nos interessa agora é a local0-7! Estes estão destinados para serem utilizados pelo usuário em scripts e por programas que permitem mudar seu sistema de logs para o syslog, como o FreeRadius, por exemplo! Como havia dito, o recurso syslog que nos interessa é o local0-7! Com ele é possível definir que seu script envie mensagens de log para um arquivo especifico usando os recursos de log do sistema! Para que seja possível usar os recursos local0 a local7 é necessário configurar o arquivo /etc/syslog.conf adicionando a seguinte linha e reiniciar o daemon:

local5.* /var/log/andrelog.log

Com isso estarei configurando o recurso local5 para enviar todas suas mensagens no arquivo de log /var/log/andrelog.log. Porém para que isso seja usado por um script shell é necessário o uso do programa logger! Observe o script abaixo:

#!/bin/bash

logger -t $0 -p local5.warning "teste syslog em shell script"
A saida no arquivo de log mencionado anteriormente é:

Aug 26 09:29:40 debiandre testeScript.sh: teste syslog em shell script

Neste comando do logger eu utilizei dois parâmetros que foram o -t e o -p. O primeiro (-t) me permite adicionar um tag (marcação) a mensagem, que nesse caso eu coloquei a variável $0 que em shell script é o nome do script, e o segundo (-p) me permite definir o recurso do syslog que desejo utilizar, sua severidade e a mensagem que quero enviar. Com isso o syslog já se encarrega de escrever no arquivo de log colocando essas mensagens e a data da execução!

Com este exemplo é possível imaginar uma variedade de formas para utilizar o logger em um shell script, substituindo a forma tradicional para criar logs! Ainda é possível utilizar uma outra funcionalidade do syslog que é a de enviar os logs para um servidor remoto, sendo possivel assim a centralização desses arquivos! Mas isso pode ser uma outra dica para um outro post!

Espero que essa dica seja útil para vocês como foi para mim! ;)

segunda-feira, 25 de agosto de 2008

Estatísticas de Trafego de rede com Ntop

Esses dias tive a necessidade de saber que tipo de tráfego tinha em minha rede. Não tive a necessidade de bloquear nada, era somente para fins estatísticos e tinha que ser gratuita, já que a empresa que atualmente trabalho não gosta muito de gastar com softwares!

Procurando na Internet me lembrei da ferramenta Ntop que me pareceu ser uma ferramenta bastante completa, simples e consegue gerar estatísticas do tipo de dados (http, https, smtp, pop, e outros se você quiser configurar) que estão trafegando em sua rede.

Aqui eu acabei usando uma configuração de mirroring do switch para capturar tudo que passa no meu servidor proxy/gateway e assim conseguir saber o que o pessoal tem usado por aqui. Esse servidor onde estalei o Ntop é um Ubuntu 8.04 LTS Server Edition e nele já tenho outras ferramentas como Cacti e uma outra para gerar relatórios do tráfego VoIP dos clientes que temos aqui que se chama VQManager.

A instalação foi bastante simples e rápida como seria em qualquer distribuição baseada em Debian:

aptitude install ntop
Após isso é necessário definir pelo menos a senha de administrador para que ele possa ser iniciado:

ntop --set-admin-password=minh@S&nhA
Essa senha restringe o acesso a parte de configuração usando a pagina WEB! Depois de definida a senha de administrador execute o seguinte comando para inicia-lo:

/etc/init.d/ntop start
E ele deverá estar sendo executado na porta 3000 TCP!
Basicamente agora é só usar seu navegador para acessar a ferramenta por HTTP e começar a ver as estatísticas de tráfego de sua rede!