TPROXY no redirige todo el tráfico a un puerto específico

TPROXY no redirige todo el tráfico a un puerto específico

Estoy escribiendo un proxy transparente UDP en Rust, estoy usando varias cajas

la máquina que se supone que debe actuar como proxy se ha configurado como puerta de enlace para las máquinas de destino.

La máquina proxy tiene habilitadas las capacidades de redirección del kernel de Linux; consulte el fragmento a continuación

#!/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

La máquina también tiene una NFTABLESregla configurada para redirigir todo el tráfico entrante al programa proxy; consulte el fragmento a continuación

#!/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 puede ver en las partes comentadas, he experimentado con ambos NAT PREROUTINGy TPROXY. Después de una extensa investigación y pruebas, descubrí que cuando uso NAT PREROUTINGmi proxy (que escucha en el puerto 35) obtiene TODO el tráfico entrante de los clientes, pero cuando leo los paquetes del socket, la dirección de destino original se sobrescribe con la dirección de la máquina proxy. ip (que no quiero). Pero si en lugar de eso uso TPROXYno obtengo todo el tráfico entrante, solo obtengo lo que "se supone" que mi máquina debe ver, por ejemplo, tráfico de transmisión y tráfico que tiene la dirección mac de la máquina proxy como destino, esto significa que puedo No veo todo el tráfico de los clientes conectados.

He seguido las instrucciones dadas en elmanual tproxy del kernel de Linux.

Cabe señalar que establezco IP_TRANSPARENT.

Estas son las cosas que configuro en mi 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
...

En cuanto a lo que he probado, debo decir que he probado muchas combinaciones posibles de reglas y código con variaciones y estructuras diferentes.

Voy a publicar una breve lista de enlaces que ya he visitado y leído varias veces.

En cuanto a lo que espero, espero recibir todo el tráfico entrante y redirigirlo al TPROXYpuerto 35.

También publiqué una pregunta similar en stackoverflow, pero se me ocurrió que esto no es solo una pregunta de programación, sino que también podría ser una pregunta de red/linux.

Me gustaría señalar una cosa más, durante mi prueba de ayer descubrí que, aunque lo desactivé ICMP redirection(ver el primer fragmento), vi que la máquina estaba enviando mensajes de redirección ICMP de todos modos leyéndolos a través de Wireshark, y eso es algo que me dejó bastante desconcertado. .

información relacionada