Informática Numaboa - Linux
Filtragem de pacotes no Linux 2.4
Qui 26 Abr 2007 17:47 |
- Detalhes
- Categoria: Como fazer configurações
- Atualização: Quinta, 01 Janeiro 2009 03:06
- Autor: vovó Vicki
- Acessos: 10244
Especificações de filtragem
Vimos o uso de '-p' para especificar o protocolo e de '-s' para especificar o endereço de origem (source). Existem outras opções que podem ser utilizadas para especificar características dos pacotes. Güenta que vem aí um caminhão delas:
Endereços de Origem e de Destino
Endereços IP de origem ('-s', '--source' ou '--src') e destino ('-d', '--destination' ou '--dst') podem ser especificados de quatro modos diferentes. O mais comum é usar o nome completo, como 'localhost' ou 'www.numaboa.com'. O segundo modo é especificar o endereço IP pelo seu quarteto de números, como por exemplo '127.0.0.1'.
O terceiro e quarto modos permitem a especificação de um grupo de endereços IP, do tipo '199.95.207.0/24' ou '199.95.207.0/255.255.255.0'. Ambos especificam endereços IP que vão de 199.95.207.0 a 199.95.207.255 inclusive; os dígitos após a barra '/' indicam as partes significantes do endereço IP. '/32' ou '/255.255.255.255' é o default (não há faixa de endereços, apenas um IP específico). Se nenhum endereço IP deve ser considerado, pode-se usar '/0' como em:
[ NOTA: `-s 0/0' é redundante. ] # iptables -A INPUT -s 0/0 -j DROP #
Isto raramente é usado porque o efeito mostrado acima é o mesmo que não usar a opção '-s'.
Inversão
Muitas flags, incluindo-se aí as '-s' (ou '--source') e '-d' ('--destination'), podem ter seus argumentos precedidos por '!' (significando NÃO e pronunciado 'NOT') para caçar endereços que NÃO sejam iguais aos indicados. Por exemplo, '-s ! localhost' identificam qualquer pacote que não tenha vindo do localhost.
Protocolo
O protocolo pode ser especificado com a flag '-p' (ou '--protocol'). O protocolo pode ser um número (se você conhecer seu número de identificação) ou um nome nos casos especiais de 'TCP, 'UDP' e 'ICMP'. A caixa não importa, de modo que 'tcp' funciona tão bem quanto 'TCP'.
O nome do protocolo pode receber o prefixo '!' para inverter a especificação. Por exemplo, '-p ! TCP' especifica pacotes que não sejam TCP.
Interfaces
As opções '-i' (ou '--in-interface') e '-o' (ou '--out-interface') especificam o nome da interface. Uma interface é o dispositivo físico pelo qual o pacote entrou ('-i') ou pelo qual deve sair ('-o'). Pode-se usar o comando ifconfig para listar as interfaces que estão 'no ar', isto é, as que estão trabalhando no momento.
Pacotes que atravessam a cadeia INPUT não possuem uma interface de saída (output) de modo que qualquer regra nesta cadeia que use '-o' encontrará alguma coisa. Da mesma forma, pacotes atravessando a cadeia OUTPUT não possuem uma interface de entrada (input) e qualquer regra que use '-i' não terá qualquer efeito.
Apenas os pacotes que atravessam a cadeia FORWARD possuem tanto uma interface de entrada quanto uma de saída.
É absolutamente lícito especificar uma interface que não exista - a regra não vai caçar nada enquanto esta interface não estiver operante. Isto é extremamente útil para links discados PPP (geralmente, interface ppp0) e outros semelhantes.
Como caso especial, um nome de interface que termina com um '+' coincide com todas as interfaces (se estiverem ativas ou não) que comecem com esta string. Por exemplo, para especificar uma regra que identifique todas as interfaces PPP, pode-se usar a opção '-i ppp+'.
O nome da interface precedido por ' ! ' (observe os espaços) seleciona pacotes que não casam com a(s) interface(s) especificada(s). Por exemplo, '-i ! ppp+'.
Fragmentos
Algumas vezes um pacote é muito grande para caber num fio. Quando isto acontece, o pacote é dividido em fragmentos e enviado como múltiplos pacotes. O outro lado dá um jeito de se virar com estes fragmentos e de recompor o pacote.
O problema é que o fragmento inicial possui todos os campos do cabeçalho (IP + TCP, UDP e ICMP), mas os subsequentes só possuem um subconjunto do cabeçalho (IP sem os campos de protocolo adicionais). Por este motivo, examinando os demais fragmentos para procurar os cabeçalhos de protocolo (como fazem as extensões TCP, UDP e ICMP) não é possível.
Se você estiver usando 'connection tracking' ou NAT, então todos os fragmentos serão reagrupados antes de alcançarem o código da filtragem de pacotes e você não precisa se preocupar com eles.
( Saiba também: a cadeia INPUT da tabela de filtros (ou qualquer outra tabela atrelada ao gancho NF_IP_LOCAL_IN) só é atravessada depois do reagrupamento dos fragmentos da pilha IP central (core))
Necas de 'connection tracking' ou NAT? Então é importante entender como os fragmentos são tratados pelas regras de filtragem. Qualquer regra que solicitar informações que não temos, deixará de atuar. Isto significa que o primeiro fragmento será tratado como qualquer outro pacote, mas os fragmentos subsequentes não. Uma regra como '-p TCP --sport www' (especificando a porta de origem como 'www') nunca poderá coincidir com um fragmento que não seja o primeiro. A regra oposta, '-p TCP --spor ! www', terá a mesma limitação.
Entretanto, é possível criar uma regra específica para o segundo e demais fragmentos usando a flag '-f' (ou '--fragment'). Também é permitido especificar que determinada regra não se aplica para o segundo e demais fragmentos com '-f' precedido por ' ! '.
Já que o filtro pode controlar o primeiro fragmento, normalmente é considerado seguro deixar passar o segundo e os demais porque, se o primeiro for 'dropado', os demais não poderão ser reagrupados. Só tem um probleminha: sabe-se que existem alguns bugs nesta área que fazem com que as máquinas congelem só porque recebem fragmentos sem o fragmento líder...
Pacotes malformados (pacotes TCP, UDP e ICMP muito pequenos que não permitem que o código do firewall leia as portas ou o código e tipo ICMP) são eliminados quando este tipo de verificação é tentado. O mesmo acontece com fragmentos que começam na posição 8.
Como exemplo, a regra a seguir eliminará qualquer fragmento que esteja indo na direção de 192.168.1.1:
# iptables -A OUTPUT -f -d 192.168.1.1 -j DROP #