É possível descartar todos os pacotes TCP SYN com uma carga usando nftables
?
As páginas do manual mencionam várias length
opções, mas nenhuma que eu possa usar para pacotes TCP sem erros de sintaxe.
Estou usando o kernel v6.2.10 e nftables v1.0.7.
Hoje não existe um recurso direto para isso com nftables . O recurso de carga útil bruta do nftables é muito limitado para isso. Um segmento TCP não possui informações de cabeçalho diretas para o comprimento dos dados. Ele tem o tamanho do cabeçalho
@th,96,4 << 2
e isso não é útil para alcançar a parte de dados. iptables 'u32
match pode fazer melhor, mas ainda não é suficiente: ele pode encadear computações e obter um ponteiro para o início da carga útil de dados TCP e corresponder ao seu conteúdo (ok nftables ' muito recente@ih
talvez possa fazer o mesmo). Ainda assim, como ele não pode fazer subtrações nem é flexível o suficiente, não pode ser usado para calcular o tamanho da carga útil de dados, mas talvez tenha sido bom o suficiente ("Qualquer acesso à memória fora de [skb->dados,skb-> end] faz com que a correspondência falhe.": para tamanho de dados entre 1 e 3, o comportamento pode ser indefinido).Pelo que vale a pena, o BPF de tcpdump pode fazer tal cálculo para IPv4 porque sabe como fazer subtrações:
Usando uma tabela de pesquisa para o caso IPv4
O que não pode ser calculado em tempo de execução pode, às vezes, ser pré-calculado e colocado em uma tabela de pesquisa. Para IPv4 e nftables , pode-se construir uma tabela de pesquisa com todos os valores válidos para o trio (IP Total Length , IHL , Data Offset ) onde o tamanho dos dados TCP seria zero e corresponder (ou não corresponder) a esta tabela de pesquisa.
11x11=121 possibilidades onde o comprimento do IP ( comprimento total ) = IHLx4 + DOx4
Nota: com o IPv6 e seu número variável de cabeçalhos extras entre o cabeçalho fixo e o cabeçalho do protocolo final (TCP), esse método não pode ser usado porque a(s) tabela(s) de pesquisa provavelmente teria um tamanho muito grande em vez de apenas 121 elementos .
tcpsynzero.nft
:Carregue primeiro com
nft -f tcpsynzero.nft
(a tabela está carregada, mas inativa , portanto, não habilitada, porque sem o conjunto carregado, todos os SYNs seriam descartados).Script bash
generatetriplets.bash
para gerar comandos nftables para preencher o conjunto:Preencha o conjunto com:
Por fim, habilite a tabela (redeclarar a tabela é quase um no-op, exceto que remove o sinalizador inativo ):
Teste
testado em Linux 6.1.xe nftables 1.0.7, e (ab)usando TCP Fast Open com alguns modos forçados:
Servidor Linux em 192.0.2.2 onde o conjunto de regras nftables foi instalado.
e
Cliente Linux com
e
trabalhando imediatamente:
1º SYN bloqueado (e tentado novamente com SYN normal após 1s):
Observação: o teste com o conjunto de regras nftables no cliente e não no servidor não tem atraso porque o veredicto de saída de drop aciona um erro imediato no soquete, mas isso é imediatamente repetido pelo kernel com um SYN normal. É claro que o contador na regra de descarte ainda é incrementado, pois um pacote ainda foi descartado.
Solução semelhante usada em outro caso nftables : Nftables timestamp map