TPROXY não está redirecionando todo o tráfego para uma porta especificada

TPROXY não está redirecionando todo o tráfego para uma porta especificada

Estou escrevendo um proxy UDP transparente em Rust, estou usando várias caixas

a máquina que deveria atuar como proxy foi definida como gateway para as máquinas de destino.

A máquina proxy tem os recursos de redirecionamento do kernel Linux habilitados, veja o trecho abaixo

#!/bin/sh

# Redirect packets coming to the computer
sysctl -w net.ipv4.ip_forward=1
sysctl -w net.ipv6.conf.all.forwarding=1

# Disable ICMP redirection
sysctl -w net.ipv4.conf.all.send_redirects=0

A máquina também possui uma NFTABLESregra configurada para redirecionar todo o tráfego de entrada para o programa proxy, veja o trecho abaixo

#!/bin/sh

# Setting up NFTABLES

nft add table filter
nft add chain filter divert "{ type filter hook prerouting priority -150; }"
nft add rule filter divert meta l4proto udp socket transparent 1 meta mark set 1 accept

#nft add table ip nat
#nft -- add chain ip nat prerouting { type nat hook prerouting priority -100 \; }

# Creating a new rule that redirects UDP traffic from P1-P2 to port 35

nft add rule filter divert udp dport 80-65525 tproxy to :35 meta mark set 1 accept

#nft add rule ip nat prerouting udp dport 80-65525 redirect to :35

Como você pode ver nas partes comentadas, experimentei ambos NAT PREROUTINGe TPROXY. Após extensa pesquisa e testes, descobri que quando uso NAT PREROUTINGmeu proxy (que está escutando na porta 35) recebe TODO o tráfego de entrada dos clientes, mas quando leio os pacotes do soquete, o endereço de destino original é substituído pelo endereço da máquina proxy ip (o que eu não quero). Mas se eu usar, TPROXYnão recebo todo o tráfego de entrada, só recebo o que minha máquina "deveria" ver, por exemplo, tráfego de transmissão e tráfego que tem o endereço MAC da máquina proxy como destino, isso significa que posso não vejo todo o tráfego dos clientes conectados.

Eu segui as instruções dadas nomanual tproxy do kernel linux.

Deve-se notar que eu defino IP_TRANSPARENT.

Estas são as coisas que eu defini no meu programa

use socket2::{Socket, Domain, Type, Protocol};
use std::os::fd::{OwnedFd, RawFd, AsRawFd};
use nix::sys::socket::{
    ...
    sockopt::{IpTransparent, Ipv4OrigDstAddr, Ipv4PacketInfo},
    setsockopt,
    ...
};
...
let client_to_proxy_socket = match Socket::new(Domain::IPV4, Type::RAW, Some(Protocol::UDP)) { ... };
let socket_ref: OwnedFd = client_to_proxy_socket.into();
let active: bool = true;
match setsockopt(&socket_ref, IpTransparent, &active) { ... };   // IP_TRANSPARENT
match setsockopt(&socket_ref, Ipv4OrigDstAddr, &active) { ... }; // SO_ORIGINAL_DST
match setsockopt(&socket_ref, Ipv4PacketInfo, &active) { ... };  // IP_PKTINFO
...

Quando se trata do que tentei, devo dizer que tentei muitas combinações possíveis de regras e códigos com variações e estruturas diferentes.

Vou postar uma pequena lista de links que já visitei e li diversas vezes

Quanto ao que espero, espero receber todo o tráfego de entrada e redirecioná-lo TPROXYpara a porta 35.

Também postei uma pergunta semelhante no stackoverflow, mas me ocorreu que esta não é apenas uma questão de programação, mas também pode ser uma questão de rede/Linux.

Gostaria de ressaltar mais uma coisa, durante meus testes de ontem descobri que mesmo tendo desabilitado ICMP redirection(veja o primeiro trecho) vi que a máquina estava enviando mensagens de redirecionamento ICMP de qualquer maneira lendo-as através do wireshark, e isso é algo que me deixou bastante confuso .

informação relacionada