netfilter: descarta pacotes com opções de IP

netfilter: descarta pacotes com opções de IP

Gostaria de adicionar uma regra para descartar um IPv4pacote seguindo IP optiono cabeçalho. Entendo que IHLo campo (Comprimento do cabeçalho da Internet) no cabeçalho contém o número de palavras de 32 bits no cabeçalho IPv4, incluindo opções. Portanto, meu entendimento é que uma regra deve obter o comprimento do pacote + opções do IHLcampo e comparar com 20 (comprimento do cabeçalho IPv4 sem opções) e, se for maior que 20, descartar o pacote.

Existe um iptablesmódulo específico que permite inspecionar IPo cabeçalho e avaliar (fazer operação aritmética)?

Responder1

iptablesinclui o u32método match que permite realizar algumas operações bit a bit (mas não aritméticas arbitrárias), comparações de intervalo e algumas indireções semelhantes a ponteiros na carga útil do pacote para corresponder às condições:

u32

O U32 testa se quantidades de até 4 bytes extraídas de um pacote possuem valores especificados. A especificação do que extrair é geral o suficiente para encontrar dados em determinados deslocamentos de cabeçalhos ou cargas tcp.

Possui sua própria gramática de sublinguagem e a gramática e os exemplos do manual devem ser examinados.

DIHé o tamanho do cabeçalho IP (em pedaços de 32 bits em vez de bytes) e faz parte dos primeiros 32 bits no cabeçalho (4 bits para versão com valor 0x04 para IPv4 seguido pelos 4 bits para IHL) e, portanto, se não houver opção, esse tamanho deve ser o tamanho mínimo: 20 (bytes) / 4 (bytes por palavras de 32 bits), portanto IHL = 5 (palavras de 32 bits). Não tratarei de casos inválidos onde DIH < 5, a pilha IPv4 já deveria ter cuidado disso.

Isso se traduz em:

  • pegue o primeiro valor de 32 bits
  • mascará-lo para a parte do DIH
  • mude para 24 bits
  • compare a igualdade com 5 (inverta o resultado !na partida)

Então, para descartar esse pacote recebido comtabelas de ip:

iptables -A INPUT -m u32 ! --u32 '0 & 0x0F000000 >> 24 = 5' -j DROP

sem inversão (correspondendo a 6 ou superior):

iptables -A INPUT -m u32 --u32 '0 & 0x0F000000 >> 24 = 6:0xF' -j DROP

O manual tem um exemplo semelhante onde é deslocado por 24 bits e depois multiplicado por 4 (portanto, deslocado apenas por 22 bits) para ter bytes e não palavras de 32 bits (porque os u32ponteiros usados ​​posteriormente usam endereços de 8 bits), para recuperar o início do carga útil da camada 4 e continue para outras operações:

... 0 >> 22 & 0x3C @ 0 >> 24 = 0"

O primeiro 0 significa leitura dos bytes 0-3, >>22 significa deslocar esses 22 bits para a direita. Mudar 24 bits daria o primeiro byte, então apenas 22 bits são quatro vezes isso mais alguns bits a mais. &3C elimina então os dois bits extras à direita e os primeiros quatro bits do primeiro byte. Por exemplo, se IHL=5, então o cabeçalho IP terá 20 (4 x 5) bytes de comprimento.
[...]

dando para o caso do OP:

iptables -A INPUT -m u32 ! --u32 '0 >> 22 & 0x3C = 20' -j DROP

sem inversão (e sem se preocupar com o fato de que o primeiro próximo valor possível não é 21, mas 24, nem com o valor máximo exato, desde que o valor fornecido seja maior):

iptables -A INPUT -m u32 --u32 '0 >> 22 & 0x3C = 21:0xFF' -j DROP

O primeiro método pode ser simplificado em:

  • pegue o primeiro valor de 32 bits
  • mascará-lo para a parte do DIH
  • compare a igualdade com (5<<24), ou seja, compare com 0x05000000 (idem)

dando:

iptables -A INPUT -m u32 ! --u32 '0 & 0x0F000000 = 0x05000000' -j DROP

ou:

iptables -A INPUT -m u32 --u32 '0 & 0x0F000000 = 0x06000000:0x0F000000' -j DROP

ou mesmo:

  • pegue o primeiro valor de 32 bits
  • compare o valor com intervalo entre 0x45000000 e 0x45FFFFFF para OK (IPv4semprecomeça com 4 e qualquer valor após a parte do DIH deve ser ignorado) ou entre 0x46000000 e 0x4FFFFFFF para não OK.

dando:

iptables -A INPUT -m u32 ! --u32 '0 = 0x45000000:0x45FFFFFF' -j DROP

ou:

iptables -A INPUT -m u32 --u32 '0 = 0x46000000:0x4FFFFFFF' -j DROP

Escolha sua escolha.

informação relacionada