TPROXY не перенаправляет весь трафик на указанный порт

TPROXY не перенаправляет весь трафик на указанный порт

Я пишу UDP-прозрачный прокси на Rust, использую несколько крейтов

  • сокет2=> Доступ к созданию RAW-сокета
  • nix::sys::сокет=> Доступ ко всем низкоуровневым вызовам API сокетов
  • std::net::сокет=> Доступ к стандартному разъему

Машина, которая должна действовать как прокси-сервер, была установлена ​​в качестве шлюза для целевых машин.

На прокси-машине включены возможности перенаправления ядра Linux, см. фрагмент ниже.

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

На машине также установлено NFTABLESправило для перенаправления всего входящего трафика на прокси-программу, см. фрагмент ниже.

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

Как вы можете видеть из закомментированных частей, я экспериментировал с обоими NAT PREROUTINGи TPROXY. После обширных исследований и тестирования я обнаружил, что когда я использую NAT PREROUTINGсвой прокси (который прослушивает порт 35), он получает ВЕСЬ входящий трафик от клиентов, но когда я читаю пакеты из сокета, исходный адрес назначения перезаписывается IP-адресом прокси-машины (чего я не хочу). Но если я вместо этого использую , TPROXYя не получаю весь входящий трафик, я получаю только то, что «должна» видеть моя машина, например, широковещательный трафик и трафик, который имеет mac-адрес прокси-машины в качестве пункта назначения, это означает, что я не могу видеть весь трафик от подключенных клиентов.

Я выполнил(а) инструкции, данные вруководство по tproxy ядра Linux.

Следует отметить, что я устанавливаю IP_TRANSPARENT.

Это то, что я установил в своей программе.

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
...

Говоря о том, что я пробовал, я должен сказать, что я перепробовал множество возможных комбинаций как правил, так и кода с вариациями и различными структурами.

Я собираюсь опубликовать краткий список ссылок, которые я уже посещал и читал много раз.

Что касается моих ожиданий, то я ожидаю получить весь входящий трафик и перенаправить его TPROXYна порт 35.

Я также разместил аналогичный вопрос на stackoverflow, но мне пришло в голову, что это не только вопрос программирования, но это может быть также вопрос сети/Linux.

Хочу отметить еще одну вещь: во время вчерашнего тестирования я обнаружил, что даже несмотря на то, что я отключил ICMP redirection(см. первый фрагмент), я видел, что машина все равно отправляла сообщения о перенаправлении ICMP, считывая их через Wireshark, и это меня очень озадачило.

Связанный контент