Mostrando postagens com marcador firewall. Mostrar todas as postagens
Mostrando postagens com marcador firewall. Mostrar todas as postagens

terça-feira, 9 de setembro de 2008

Iptables - marcação de pacotes para qos e/ou roteamento

Neste artigo irei mostrar como utilizar o iptables para marcar pacotes (qualquer um que você consiga enquadrar em uma regra de iptables) para usar uma determinada tabela de roteamento do linux, no caso de você ter mais de um link, ou ainda que use algumas regras definidas de QoS. Com este documento não tenho o objetivo de mostrar como criar as regras de qualidade de serviço, este será tema de um outro artigo.

Existe um tutorial muito bom que foi escrito em inglês e hospedado no site Linux Advanced Routing and Traffic Control onde ele ensina técnincas de roteamento, manipulação das tabelas e a criação de regras para alocar um certo tipo de trafego a um link específico. É uma excelente fonte de pesquisa e foi deste site onde aprendi muito do conteúdo que sei hoje sobre este tema.

O linux permite que você coloque uma marcação no pacote para posterior uso como roteamento, qos ou ainda os dois juntos! Esta marca só esta presente a nível de kernel, ou seja, quando o pacote é enviado para o meio de rede ela já não existe! Então não adianta querer marcar os pacotes com a técnica que vamos explicar aqui para identificar o pacote em um outro servidor em sua rede. Uma marca que persiste no meio de rede é o do ToS.

Com o iptables podemos fazer uma serie de comparações nos pacotes como já vimos em outros artigos e as marcas que usaremos podem ser verificadas ou "escritas" em um determinado pacote. Quando queremos verificar qual marca um pacote possui é possível faze-lo em qualquer tabela do iptables, porém para marca-lo só na mangle como veremos a seguir:
iptables -t mangle -A PREROUTING -i eth0 -j MARK --set-mark 0x1
iptables -t filter -A FORWARD -m mark --mark 0x1 -j ACCEPT

Se alguma tentativa de marcar um pacote fora da tabela mangle for feito um erro de argumento inválido será emitido. Fiz alguns testes para tentar descobrir qual o número máximo de marcas que se pode utilizar e cheguei a conclusão de que não pode ter mais do que 8 dígitos, ou seja 0x99999999 seria um valor máximo! Acho que é suficiente! Hehehe

Com essas possibilidades você pode criar uma estrutura de roteamento e/ou qos para sua rede podendo priorizar pacotes de serviços como http, smtp/pop, ftp, voip e deixar outros com menor prioridade utilizar regras mais restritas. Um comando importante neste cenário é o ip. Este comando faz parte do pacote iproute do linux e esta presente por padrão em quase todas as distribuições, se não estiver procure por este pacote! Com ele temos a possibilidade de mudar/configurar a tabela de roteamento do kernel do linux.

Como vimos, com o ip podemos trabalhar com as regras de roteamento do nosso linux e para gerenciarmos as regras de qos temos o tc. Com ele podemos criar filas de qos especializadas, diferentes da padrão utilizada pelo linux que é a pfifo_fast:
2: eth1: mtu 1500 qdisc pfifo_fast
Utilizando a marcação acima (0x1) podemos dizer que este pacote use uma tabela de roteamento específica e que use uma configuração de qos especial:
ip rule add from all fwmark 0x1 table link1
tc filter add dev eth1 protocol all parent 1:0 handle 0x1 fw classid 1:112
Eu tenho usado este tipo de configuração para ajustar regras de qos em minha rede pois aqui temos vários clientes usando um mesmo link de internet. Claro que aqui estou usando muitas regras e até scripts para gerar um bloco grande automaticamente. Este comando ip é muito poderoso e você pode fazer roteamento baseado na origem, destino, campo ToS e conseguir um controle bastante interessante em sua rede!

Outra forma de classificar os pacotes e aloca-los em uma regra de qos específica é utilizando o próprio iptables! Ele possui um alvo (target) especial que já coloca os pacotes em uma fila especial de qos que você criou! O comando é assim:
iptables -t mangle -A POSTROUTING -p tcp --dport 80 -j CLASSIFY 1:112
Uma ressalva é importante de ser feita aqui, esta regra só pode ser utilizada na tabela mangle na chain POSTROUTING! Este comando é bastante explicativo e irá se enquadrar com pacotes que usem tcp e tenham por destino a porta 80 (web) colocando este em uma regra de qos. Eu já fiz testes das duas formas, usando mark e classify, e obtive resultados melhores quando usando a primeira técnica (mark) para realizar qos.

Com participo do fórum da Under-linux.org, sempre vejo pessoas perguntando se é possível realizar qos para um determinado computador e/ou serviço que ele esta servindo, com estas técnicas é possível garantir/limitar banda, alocar tráfego em um determinado link para recursos em sua rede, ai é só questão de criatividade para estar criando as regras e fazer algo bem interessante!

Como sempre, se existir alguma dúvida, crítica ou sugestão por favor postem aqui neste fórum ou mesmo no meu perfil no site da Under-linux.org.


terça-feira, 2 de setembro de 2008

Iptables - compartilhando seu link de internet com SNAT ou MASQUERADE (Atualizado)

Como temos visto nos artigos anteriores o iptables é uma ferramenta muito poderosa e com conhecimento é possível criar regras melhores com o intuito de melhorar a segurança de sua rede interna. O que vou descrever aqui neste artigo não é muita novidade para pessoas que já estão acostumadas com seu uso, porém para aqueles que estão iniciando nesta poderosa ferramenta podem se sentir um pouco perdidos na hora de ter que implementar um firewall para compartilhar a internet. Espero que com este artigo possa abrir um pouco mais o horizonte dessas pessoas e mostrar que não é difícil criar seus próprios scripts de iptables que possam cumprir com todos os requisitos que necessitem!

Antes de tudo gostaria de mostrar aqui que existe um padrão para os endereços que podem ser utilizados dentro de uma rede interna! Já vi pessoas que usaram redes destinadas a uso na internet em suas redes locais. Pode ser que no inicio não tenha problema, mas pode ser que em um determinado momento você necessite de um recurso da internet que está presente nesta rede que esta sendo usada em sua lan, e como resultado, não irá conseguir acessa-lo! O documento guia para isto é a RFC1918 (procure por Private Address Space) e esta disponível para pesquisas. Para aqueles que querem saber de uma vez, o padrão é este:
10.0.0.0 - 10.255.255.255 (10/8 prefix)
172.16.0.0 - 172.31.255.255 (172.16/12 prefix)
192.168.0.0 - 192.168.255.255 (192.168/16 prefix)
Com isto podemos nos guiar para criar nossa rede interna e saber que fora deste escopo estaremos usando uma rede que está disponível para uso na internet!

Se estamos falando aqui de compartilhar uma conexão de internet estamos falando de NAT (Network Address Translation), ou seja, queremos que endereços privados possam acessar recursos que geralmente estão fora da nossa rede local. Neste link está uma animação feita pela cisco onde descreve todo o processo! Bem interessante de se ver!

No iptables existe uma tabela específica para fazer este tipo de trabalho e ela tem um nome bem sugestivo que é nat! Nela é possível utilizar uma chain para fazer o serviço que é a POSTROUTING com dois possíveis alvos: SNAT e MASQUERADE! Cada um destes alvos pode ser utilizado para uma determinada necessidade.

O SNAT é muito útil para quando você tem por exemplo um ip público fixo ou ainda uma classe de ips públicos que foi dado a você pelo seu provedor! Por exemplo:
iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -j SNAT --to 200.200.200.200
Desta forma estamos dizendo que a rede de origem 192.168.0/24 terá o ip público 200.200.200.200! Com isso é possível ter vários ips válidos na interface externa de seu Linux (eth0:1, eth0:2) e poder escolher por onde sairá algum pacote que você possa enquadrar em uma regra de iptables! Como por exemplo, você poderia ter seus servidores (web, ftp, e-mail) saindo por um ip válido enquanto que sua rede local usaria outro! As regras ficariam mais ou menos assim:
# Servidores usam este ip 200.200.200.200
iptables -t nat -A POSTROUTING -m iprange --src-range 192.168.0.2-192.168.0.5 -j SNAT --to 200.200.200.200

# A lan usa este 200.200.200.201
iptables -t nat -A POSTROUTING -m iprange --src-range 192.168.0.20-192.168.0.80 -j SNAT --to 200.200.200.201
Este exemplo funciona muito bem no caso de você ter mais de um endereço ip publico e não usar um proxy, como o Squid. Se você estiver usando o squid, é necessário acrescentar umas linhas ao seu arquivo de configuração. No meu caso eu fiz o seguinte:
acl MinhaLAN src 10.10.10.0/255.255.255.0
acl Cliente1 src 10.10.11.0/255.255.255.0
acl Cliente2 src 10.10.12.0/255.255.255.248
http_access allow MinhaLAN
http_access allow Cliente1
http_access allow Cliente2
tcp_outgoing_address seuIpPublico MinhaLAN
tcp_outgoing_address seuOutroIpPublico Cliente1 Cliente2
O que faz o trabalho de usar diferentes endereços ip para as requisições http são as linhas tcp_outgoing_address. Este é um exemplo totalmente funcional e estou usando aqui em minha empresa! O funcionamento do MASQUERADE por outro lado é útil para quando você não sabe seu endereço ip público, como por exemplo, em uma rede onde a atribuição seja automática (DHCP)! Por exemplo:
iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -o ppp0 -j MASQUERADE
Com esta regra você não precisa se preocupar com o endereço ip externo do seu Linux. O iptables se encarregará de fazer o trabalho de NAT! Lendo no tutorial do IpSysctl eles fazem uma recomendação para que o parâmetro ip_dynaddr esteja habilitado evitando problemas em uma possível troca de ip de origem (por terminar o tempo de aluguel de um endereço)! Muito importante também não esquecer de habilitar o encaminhamento de ips no seu linux em ambos os casos:
echo "1" > /proc/sys/net/ipv4/ip_forward
É muito importante saber qual dessas opções melhor satisfaz seus requerimentos! Com essas instruções em mente podemos criar um script de iptables para compartilhar a internet:

#!/bin/bash
#
# Um firewall statefull com MASQUERADE
#

#=========================
# variaveis
#-------------------------
cmd=iptables
lan=eth1
wan=eth0

#=========================
# 1 - limpando iptables
# 2 - politica padrao
#-------------------------
$cmd -t filter -F
$cmd -t nat -F
$cmd -t mangle -F

$cmd -t filter -P INPUT DROP
$cmd -t filter -P FORWARD DROP
$cmd -t filter -P OUTPUT DROP

#=========================
# conexões filter - input
#-------------------------
$cmd -t filter -A INPUT -i $wan -m state --state RELATED,ESTABLISHED -j ACCEPT
$cmd -t filter -A INPUT -i lo -j ACCEPT
$cmd -t filter -A INPUT -i $lan -j ACCEPT

#==========================
# conexões filter - forward
#--------------------------
$cmd -t filter -A FORWARD -i $wan -m state --state RELATED,ESTABLISHED -j ACCEPT
$cmd -t filter -A FORWARD -i $lan -o $wan -j ACCEPT

#==========================
# conexões filter - output
#--------------------------
$cmd -t filter -A OUTPUT -i lo -j ACCEPT

#===========================
# conexões nat - postrouting
#---------------------------
$cmd -t nat -A POSTROUTING -o $wan -j MASQUERADE

Caso você tenha ficado em dúvida sobre algum conceito do iptables aqui aprensentado não deixe de visitar os outros artigos neste mesmo blog que estão nos seguintes links:

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

Se tiverem dúvidas, críticas ou sugestões não hesitem em posta-las!

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.