我正在用 Rust 編寫一個 UDP 透明代理,我使用了幾個板條箱
- 套接字2=> 存取RAW套接字的創建
- 尼克斯::系統::套接字=> 存取所有低階套接字 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 上偵聽)時,會取得來自客戶端的所有傳入流量,但是當我從套接字讀取封包時,原始目標位址會被代理電腦的位址覆蓋。但是,如果我改為使用,TPROXY
我不會獲得所有傳入流量,我只會獲得我的機器「應該」看到的內容,例如廣播流量和以代理電腦的mac 位址作為目的地的流量,這意味著我可以看不到來自已連線客戶端的所有流量。
我已按照中給出的說明進行操作Linux核心的tproxy手冊。
必須指出的是,我確實設定了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
...
當涉及到我所嘗試的內容時,我必須說我已經嘗試了規則和程式碼的許多可能組合以及變化和不同的結構。
我將發布一個我已經訪問過並閱讀多次的連結的簡短列表
- 在 Rust 中實作用於 RX 和 TX 時間戳記的非同步套接字 recvmsg
- 取得收到的UDP封包的目的位址
- 使用 iptables 將系統範圍內的流量重新導向至本機代理伺服器
- 使用 iptables TPROXY 而不是 REDIRECT
- 透明代理的 IPTables 配置
至於我的期望,我期望獲得所有傳入流量並將其重定向TPROXY
到連接埠 35。
我也在 stackoverflow 上發布了類似的問題,但我發現這不僅是一個程式設計問題,而且也可能是網路/Linux 問題。
我還想指出一件事,在昨天的測試過程中,我發現即使我禁用了ICMP redirection
(請參閱第一個片段),我也看到機器正在發送ICMP 重定向訊息,無論如何都透過wireshark 讀取它們,這讓我非常困惑。