Recursos avançados do netfilter / iptables

Introdução

É comumente conhecido que o netfilter / iptables é o firewall do sistema operacional Linux. O que não é comumente conhecido é que o iptables tem muitas gemas escondidas que podem permitir que você faça coisas com seu firewall que você nunca imaginou. Neste artigo, vou apresentar muitos desses recursos com alguns usos práticos. Se você não estiver au fait com as noções básicas de iptables, então você deve ler o meu artigo anterior no Diário ” Firewalling com netfilter / iptables “.

Os seguintes recursos são discutidos:

  1. Especificando várias portas em uma regra
  2. Balanceamento de carga
  3. Restringindo o número de conexões
  4. Manter uma lista de conexões recentes para combinar
  5. Correspondência com uma cadeia na carga de dados de um pacote
  6. Regras baseadas em tempo
  7. Definindo cotas de transferência
  8. Correspondência de pacotes com base nos valores de TTL

Todos os recursos discutidos neste artigo são extensões para os módulos de correspondência de pacotes do iptables. I utilizado apenas duas destas extensões no artigo anterior: o --statemódulo que nos permitiu realizar uma filtragem pacotes com base em se eram NEWESTABLISHEDRELATEDou INVALIDconexões; e a multiport extensão, da qual eu irei detalhar mais neste artigo.

Alguns dos módulos introduzidos neste artigo (marcados com um asterisco) ainda não entraram no kernel padrão do Linux, mas um utilitário netfilter chamado “patch-o-matic” pode ser usado para adicioná-los ao seu próprio kernel e isso ser discutido no final do artigo.

1. Especificando Múltiplas Portas com multiport

multiportmódulo permite especificar um número de portas diferentes em uma regra. Isso permite menos regras e facilita a manutenção dos arquivos de configuração do iptables. Por exemplo, se quisermos permitir acesso global às portas SMTP, HTTP, HTTPS e SSH em nosso servidor, normalmente usaríamos algo como o seguinte:

-A INPUT -i eth0 -p tcp -m state --state NOVO --dport ssh -j ACCEPT
-A INPUT -i eth0 -p tcp -m state --state NOVO --dport smtp -j ACCEPT
-A INPUT -i eth0 -p tcp -m state --state NOVO --dport http -j ACCEPT
-A INPUT -i eth0 -p tcp -m state --state NOVO --dport https -j ACCEPT

Usando o multiportmódulo de correspondência, podemos agora escrever:

-A INPUT -i eth0 -p tcp -m state --state NOVO -m multiport --dports ssh, smtp, http, https -j ACEITAR

Ele deve ser usado em conjunto com -p tcpou -p udpsomente até 15 portas podem ser especificadas. As opções suportadas são:

--sports port[,port,port...]
corresponde à (s) porta (s) de origem
--dports port[,port,port...]
corresponde ao (s) porto (es) de destino
--ports port[,port,port...]
corresponde à (s) porta (s) de origem e destino

mport* é outra extensão semelhante que também permite que você especifique intervalos de porta, por exemplo --dport 22,80,6000:6100.

2. Balanceamento de carga com random* ou nth*

Tanto o randomnthextensões podem ser usadas para balanceamento de carga. Se, por exemplo, você desejasse equilibrar o tráfego da Web recebido entre quatro servidores da Web espelhados, você poderia adicionar um dos seguintes conjuntos de regras à suanattabela:

-A PREROUTING -i eth0 -p tcp --dport 80 -m state --state NOVO -m nth --contador 0 --todos os 4 --pacote 0 \
    -j DNAT - para destino 192.168.0.5:80
-A PREROUTING -i eth0 -p tcp --dporta 80 -m state --state NEW -m nth --contador 0 --todos os 4 --pacote 1 \
    -j DNAT - para destino 192.168.0.6:80
-A PREROUTING -i eth0 -p tcp --dport 80 -m state --state NOVO -m nth --contador 0 --todos 4 --pacote 2 \
    -j DNAT - para destino 192.168.0.7:80
-A PREROUTING -i eth0 -p tcp --dport 80 -m state --state NOVO -m nth --contador 0 --todos 4 --pacote 3 \
    -j DNAT - para destino 192.168.0.8:80

ou:

-A PREROUTING -i eth0 -p tcp --dporta 80 -m state --state NEW -m random - média 25 \
    -j DNAT - para destino 192.168.0.5:80
-A PREROUTING -i eth0 -p tcp --dporta 80 -m state --state NEW -m random - média 25 \
    -j DNAT - para destino 192.168.0.6:80
-A PREROUTING -i eth0 -p tcp --dporta 80 -m state --state NEW -m random - média 25 \
    -j DNAT - para destino 192.168.0.7:80
-A PREROUTING -i eth0 -p tcp --dport 80 -m state --state NOVO \
    -j DNAT - para destino 192.168.0.8:80

nthextensão correspondente permite que você corresponda ao enésimo pacote recebido pela regra. Existem até 16 (0 … 15) contadores para corresponder aos enésimos pacotes. As quatro nthregras acima ( ) usam o contador 0 para contar cada 4º pacote. Depois que o 4º pacote é recebido, o contador é zerado. A primeira regra corresponde ao primeiro pacote ( --packet 0) de cada quatro contados, a segunda regra corresponde ao segundo pacote ( --packet 0) e assim por diante.

randomextensão correspondente permite combinar pacotes com base em uma determinada probabilidade. A primeira regra do conjunto de randomregras acima corresponde a 25% ( --average 25) das conexões TCP para a porta 80 e as redireciona para o primeiro servidor da Web espelhado. Dos 75% de conexões que não coincidem na primeira regra, 25% corresponderão ao segundo e 25% corresponderão ao terceiro. Os restantes 25% serão apanhados pela quarta regra.

Outro uso da randomextensão seria simular uma conexão de rede defeituosa para avaliar o desempenho do hardware / software de rede, etc.

3. Restringindo o número de conexões com limitiplimit*

limitextensão correspondente pode ser usada para limitar o número de vezes que uma regra corresponde em um determinado período de tempo, enquanto a iplimitextensão pode restringir o número de conexões TCP paralelas de um determinado host ou rede. Essas extensões podem ser usadas para várias finalidades:

  • proteger contra ataques do DOS (negação de serviço), como impedir uma inundação de solicitações HTTP para seu servidor da Web, garantindo que todos os seus clientes tenham acesso ilimitado;
  • impedir que um ataque de força bruta adivinhe senhas;
  • limitar o uso da Internet pelos funcionários durante o horário de trabalho;
  • e muitos mais.

Vamos considerar o caso em que queremos limitar o uso da Internet de nossos funcionários durante o horário de trabalho. Nós poderíamos usar uma regra como:

-A FORWARD -m state --state NOVO -p tcp -m multiport --dportar http, https -o eth0 -i eth1 \
    -m limite - limite 50 / hora - limite-rajada 5 -j ACEITAR

Esta regra assume que estamos agindo como um servidor proxy onde a conexão externa é via eth0e se eth1 conecta à rede do nosso escritório. A regra limita todos os nossos computadores internos a apenas 50 novas conexões HTTP ou HTTPS por hora e o uso --limit-burstimpede que qualquer funcionário use todos os 50 de uma só vez. Os pacotes podem ser combinados /day/hour/minuteou /sec.

--limit-burstparâmetro pode ser bastante confuso no começo. No exemplo acima, ele garantirá que, se todos os funcionários estiverem tentando acessar a Internet durante toda a hora, apenas 5 conexões serão feitas a cada 5 minutos. Se passar 30 minutos sem conexões e depois houver uma corrida repentina pelos 30 minutos restantes, apenas 5 conexões serão permitidas a cada 2,5 minutos. Eu ouvi uma vez que explicou da seguinte forma:

Para cada limit regra, há um “bucket” contendo “tokens”. Sempre que a regra corresponde, um token é removido e quando a contagem de token chega a zero, a regra não corresponde mais.--limit é a taxa de recarga do balde. 
--limit-burst é o tamanho do depósito (número de tokens que ele pode conter).

iplimitextensão nos permite restringir o número de conexões TCP paralelas de um determinado host ou rede. Se, por exemplo, quisermos limitar o número de conexões HTTP feitas por qualquer endereço IP a 5, poderíamos usar:

-A INPUT -p tcp -m state --state NOVO --dport http -m iplimit --iplimit-above 5 -j DROP

4. Mantendo uma lista de recentconexões para combinar

Ao usar a recentextensão, é possível criar dinamicamente uma lista de endereços IP que correspondam a uma regra e, depois, corresponder a esses IPs de maneiras diferentes. Um uso possível seria criar uma lista de “maus” temporários, detectando possíveis varreduras de portas e, em seguida, DROPtodas as outras conexões da mesma fonte por um determinado período de tempo.

A porta 139 é uma das portas mais perigosas para usuários do Microsoft Windows®, pois é por meio dessa porta que o serviço de compartilhamento de arquivos e impressão do Windows é executado. Isso também torna essa porta uma das primeiras verificadas por muitos scanners de portas ou hackers em potencial e um alvo para muitos dos worms atuais. Podemos usar a recentextensão correspondente para bloquear temporariamente qualquer IP de conexão com a nossa máquina que varre essa porta da seguinte maneira:

-A FORWARD -m recente --name portscan --rcheck --segundos 300 -j DROP
-A FORWARD -p tcp -i eth0 --dport 139 -m recente --name portscan --set -j DROP

Agora, qualquer um que tentar se conectar à porta 139 em nosso firewall terá todos os seus pacotes caídos até que 300 segundos tenham passado. As opções suportadas incluem:

--name name
O nome da lista para armazenar ou verificar o IP. Se nenhum nome for dado, então DEFAULTserá usado
--set
Isso adicionará o endereço de origem do pacote à lista. Se o endereço de origem já estiver na lista, isso atualizará a entrada existente.
--rcheck
Isto irá verificar se o endereço de origem do pacote está atualmente na lista.
--update
Isto irá verificar se o endereço de origem do pacote está atualmente na lista. Se for, então essa entrada será atualizada e a regra retornará verdadeira.
--remove
Isso verificará se o endereço de origem do pacote está atualmente na lista e, em caso afirmativo, esse endereço será removido da lista e a regra retornará true.
--seconds seconds
Esta opção deve ser usada em conjunto com um dos --rcheckou --update. Quando usado, isso limitará a correspondência a acontecer somente quando o endereço estiver na lista e for visto dentro do último número de segundos especificado.
--hitcount hits
Esta opção deve ser usada em conjunto com um dos --rcheckou --update. Quando usado, isso limitará a correspondência a acontecer somente quando o endereço estiver na lista e os pacotes tiverem sido recebidos como maiores ou iguais ao valor determinado. Essa opção pode ser usada junto com “segundos” para criar uma correspondência ainda mais restrita, exigindo um determinado número de ocorrências dentro de um período de tempo específico.

5. Combinando com um string* na carga de dados de um pacote

stringextensão permite combinar uma string em qualquer lugar na carga de dados de um pacote. Embora essa extensão tenha muitos usos válidos, recomendo cautela. Digamos, por exemplo, que o nosso firewall Linux esteja protegendo uma rede interna com alguns computadores que executam o Microsoft Windows® e gostaríamos de bloquear todos os arquivos executáveis. Nós podemos tentar algo como:

-A FORWARD -m string --string '.com' -j DROP
-A FORWARD -m string --string '.exe' -j DROP

Isso tem vários problemas:

  • se o ‘ .com‘ ou ‘ .exe‘ estiver dividido em dois pacotes, ele não será correspondido
  • se algum pacote que estiver sendo transmitido contiver alguma das picadas, ele será descartado; isso inclui todos os pacotes de uma página da Web que contenham essas cadeias de caracteres, de uma transmissão de e-mail, etc.

6. Regras Baseadas no Tempo com time*

Podemos combinar regras com base na hora do dia e no dia da semana usando o timemódulo. Isso pode ser usado para limitar o uso da equipe na hora do almoço, para impedir que cada um de um conjunto de servidores espelhados fique fora de ação para backups automatizados ou manutenção do sistema, etc. O exemplo a seguir permite acesso à web durante a hora do almoço:

-A FORWARD -p tcp -m multiportar --dportar http, https -o eth0 -i eth1 \
    -m time --timestart 12:30 --timestop 13:30 --days seg, ter, qua, qui, sex -j ACEITAR

Claramente os horários de início e parada são de 24 horas com o formato HH:MM. O dia é uma lista separada por vírgulas que é sensível e composta por MonTueWedThuFriSate / ou Sun.

7. Definindo cotas de transferência com quota*

Definir cotas de transferência pode ser muito útil em muitas situações. Como exemplo, muitos usuários de banda larga terão cotas de download definidas para eles por seu ISP e muitos podem cobrar extra por cada megabyte transferido além dessa cota. Você pode usar o iptables para monitorar seu uso e interrompê-lo quando atingir sua cota (digamos, 2 GB) com uma regra semelhante à seguinte:

-A INPUT -p tcp -m quota --quota 2147483648 -j ACEITAR
-A INPUT -j DROP

Você pode então ver seu uso com o seguinte comando:
$ iptables -v -L

Você também precisará redefinir a cota todo mês manualmente (reiniciando iptables) ou com um cron job. Claramente, seu computador precisaria estar ‘sempre ativo’ para que este exemplo fosse de alguma utilidade, mas também há outras situações em que a quota extensão seria útil.

8. Correspondência de pacotes baseada em valores TTL

O valor TTL (Time-To-Live) de um pacote é um número de 8 bits que é decrementado por um cada vez que o pacote é processado por um host intermediário entre sua origem e destino. O valor padrão é dependente do sistema operacional e geralmente varia de 32 a 128. Sua finalidade inclui garantir que nenhum pacote permaneça na rede por um período de tempo não razoável, fique preso em um loop infinito devido a tabelas de roteamento incorretas, etc. O valor de um pacote chega a 0 e é descartado e uma mensagem é enviada para sua origem, que pode decidir se deseja ou não reenviá-la.

Como um aparte interessante: é realmente como o traceroutecomando funciona. Ele envia um pacote para o destino com um TTL de 1 primeiro e recebe uma resposta do primeiro host intermediário. Em seguida, ele envia um pacote com um TTL de 2 e recebe uma resposta do segundo host intermediário e assim por diante até atingir seu destino.

A utilidade da correspondência de pacotes com base no valor de TTL depende da sua imaginação. Um possível uso é identificar ataques “man-in-the-middle”. Se você se conectar regularmente de casa para o trabalho, poderá monitorar seus valores de TTL e estabelecer um valor máximo razoável na extremidade de recebimento. Você pode usar isso para negar quaisquer pacotes que cheguem com um valor TTL mais alto, pois isso pode indicar um possível ataque “man-in-the-middle”; alguém interceptando seus pacotes, lendo / armazenando-os e reenviando-os para o destino. Existem, é claro, métodos “man-in-the-middle” que não alterariam o valor do TTL, mas, como sempre, a segurança nunca é absoluta, apenas incremental. A correspondência TTL também pode ser usada para depuração de rede ou para localizar hosts com valores TTL padrão incorretos.

Como um exemplo simples, vamos rejeitar todos os pacotes de um IP específico com um TTL menor que 40:

-A INPUT -s 1.2.3.4 -m ttl - tll-lt 40 -j REJEITAR

Você também pode verificar os valores de TTL que são menores que ( --ttl-gt) ou iguais a ( --ttl-eq) um valor específico.

Corrigindo seu kernel com Patch-O-Matic (POM)

Alguns dos recursos mais recentes apresentados neste artigo não são considerados estáveis ​​o suficiente pela equipe de desenvolvimento do netfilter para inclusão no kernel atual do Linux. Para usá-los, você precisará corrigir seu kernel usando um utilitário chamado patch-o-matic. Isso não é para os fracos de coração e não vou fornecer instruções passo a passo aqui. Vou simplesmente cobrir patch-o-matic e fornecer referências para mais informações.

Patch-o-matic pode ser baixado da página inicial do netfilter, http://www.netfilter.org/ . Você também precisará do código-fonte do seu kernel (se você estiver usando um kernel fornecido com a sua distribuição, instale o kernel-sourcepacote ou instale um novo kernel baixando o código-fonte mais recente do kernel em http://www.kernel.org/ ) e o código fonte do iptables que você também pode baixar da página inicial do netfilter. Depois de tê-los, descompacte-os e execute o runmescript em patch-o-matic da seguinte maneira:
$ KERNEL_DIR=<path to the kernel source code> IPTABLES_DIR=<path to the iptables source code> ./runme extra

O script descreve cada nova extensão e pergunta se deve ou não corrigir o kernel para isso. Uma vez terminado, você precisará recompilar o kernel, os módulos do kernel do netfilter e os binários do iptables. Isso está fora do escopo deste artigo, mas você encontrará informações úteis sobre os seguintes sites:

Rolar para cima