Gostaria de adicionar uma regra para descartar um IPv4
pacote seguindo IP option
o cabeçalho. Entendo que IHL
o 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 IHL
campo e comparar com 20 (comprimento do cabeçalho IPv4 sem opções) e, se for maior que 20, descartar o pacote.
Existe um iptables
módulo específico que permite inspecionar IP
o cabeçalho e avaliar (fazer operação aritmética)?
Responder1
iptables
inclui o u32
mé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:
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 u32
ponteiros 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.