TPROXY가 모든 트래픽을 지정된 포트로 리디렉션하지 않습니다.

TPROXY가 모든 트래픽을 지정된 포트로 리디렉션하지 않습니다.

저는 Rust로 UDP 투명 프록시를 작성하고 있습니다. 여러 상자를 사용하고 있습니다.

프록시 역할을 하는 머신이 대상 머신의 게이트웨이로 설정되었습니다.

프록시 머신에는 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 PREROUTINGTPROXY. 광범위한 조사와 테스트를 통해 NAT PREROUTING프록시(포트 35에서 수신 대기 중)를 사용할 때 클라이언트로부터 들어오는 모든 트래픽을 받지만 소켓에서 패킷을 읽을 때 원래 대상 주소가 프록시 시스템의 주소로 덮어쓰여진다는 사실 을 발견했습니다. IP (내가 원하지 않는). 그러나 대신 I를 사용하면 TPROXY들어오는 트래픽을 모두 얻지 못하고 내 컴퓨터에서 볼 수 있다고 "가정"한 것만 얻을 수 있습니다. 예를 들어 브로드캐스트 트래픽과 프록시 컴퓨터의 mac 주소가 대상으로 있는 트래픽은 다음을 수행할 수 있음을 의미합니다. 연결된 클라이언트의 모든 트래픽이 표시되지 않습니다.

나는리눅스 커널의 tproxy 매뉴얼.

내가 set 을 수행한다는 점에 유의해야 합니다 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에 비슷한 질문을 게시했지만 이것이 프로그래밍 질문일 뿐만 아니라 네트워크/리눅스 질문일 수도 있다는 생각이 들었습니다.

한 가지 더 언급하고 싶습니다. 어제 테스트하는 동안 비활성화했음에도 불구하고 ICMP redirection(첫 번째 스니펫 참조) 기계가 어쨌든 Wireshark를 통해 읽는 ICMP 리디렉션 메시지를 보내는 것을 보았고 그것이 나를 꽤 당황하게 만들었습니다. .

관련 정보