Мой прозрачный прокси -сервер TCP/UDP с nfqueue + windiverert не работаетLinux

Ответить
Anonymous
 Мой прозрачный прокси -сервер TCP/UDP с nfqueue + windiverert не работает

Сообщение Anonymous »

У меня есть прозрачный прокси, который работает путем подделки и портов, но по какой -то причине он не работает. На сервере Debian 12 AMD64 я использовал iptables -t mangle -a prerouting -j nfqueue -queeue -num 2 < /code>, чтобы перехватить все пакеты в мой код, а также на клиенте Windows 11 Amd64, я использую Windierer ./my-proxy не рассказывает мне о причине: udp_csum , но он рассказывает мне о причине: ip_inaddrerror , я больше не знаю, что делать, я полностью отключил контрольную сумму на клиенту, я даже запустил предположения, почему мой прокси не работает.use std::{
net::Ipv4Addr,
process::exit,
io::stdin
};
use tokio::task::spawn;
use packedit::prelude::*;
use windivert::prelude::*;

#[tokio::main]
async fn main() -> () {
let outbound = WinDivert::network("outbound and ip", 0, WinDivertFlags::new()).expect("Не удалось создать экземпляр WinDivert");
let inbound = WinDivert::network("inbound and ip", 0, WinDivertFlags::new()).expect("Не удалось создать экземпляр WinDivert");
spawn(handle(outbound, true));
spawn(handle(inbound, false));
println!("Прокси начал работу");
loop {
let mut buffer = String::new();
stdin().read_line(&mut buffer).unwrap();
if buffer.trim() == String::from("stop") {
println!("Выход...");
println!("Прокси завершил работу");
exit(0);
}
}
}

async fn handle(session: WinDivert, outbound: bool) -> () {
loop {
let mut buffer = vec![0u8; 65535];
match session.recv(Some(&mut buffer)) {
Ok(p) => {
let mut packet = unsafe {WinDivertPacket::::new(edit_packet(&p.data.into_owned(), outbound))};
packet.address = p.address;
packet.address.set_ip_checksum(false);
packet.address.set_tcp_checksum(false);
packet.address.set_udp_checksum(false);
match session.send(&packet) {
Ok(_) => {
if outbound {
println!("Успешно отправлен пакет в сеть");
}
else {
println!("Успешно отправлен пакет в систему");
}
}
Err(e) => {
if outbound {
eprintln!("Не удалось отправить изменённый пакет в сеть: {}", e);
}
else {
eprintln!("Не удалось отправить изменённый пакет в систему: {}", e);
}
}
}
}
Err(e) => {eprintln!("Ошибка получения исходящего пакета: {}", e);}
}
}
}

fn edit_packet(bytes: &[u8], outbound: bool) -> Vec {
let mut packet = Ipv4Packet::from_bytes(bytes.to_vec());
match packet.get_next_level_packet() {
Ipv4NextLevelPacket::Tcp(mut tcp) => {
if tcp.source == 22 || tcp.destination == 22 {
return packet.to_bytes();
}
if outbound {
let mut option = TcpOption::new();
option.kind = 253;
option.data.append(&mut packet.destination.octets().to_vec());
option.data.append(&mut tcp.destination.to_be_bytes().to_vec());
tcp.options.push(option);
tcp.destination = 2054;
packet.destination = Ipv4Addr::new(10, 20, 30, 40);
tcp.recalculate_all(packet.source, packet.destination);
packet.payload = tcp.to_bytes();
}
else {
if packet.source == Ipv4Addr::new(10, 20, 30, 40) && tcp.source == 2054 {
let index = tcp.options.iter().position(|x| x.kind == 253 && x.length == 8).unwrap();
let option = &tcp.options[index];
packet.source = Ipv4Addr::new(option.data[0], option.data[1], option.data[2], option.data[3]);
tcp.source = u16::from_be_bytes([option.data[4], option.data[5]]);
tcp.options.remove(index);
tcp.recalculate_all(packet.source, packet.destination);
packet.payload = tcp.to_bytes();
}
else {
return packet.to_bytes();
}
}
}
Ipv4NextLevelPacket::Udp(mut udp) => {
if outbound {
let mut new_payload = vec![0u8; 6];
new_payload[0..=3].copy_from_slice(&packet.destination.octets());
new_payload[4..=5].copy_from_slice(&udp.destination.to_be_bytes());
new_payload.append(&mut udp.payload);
udp.payload = new_payload;
udp.destination = 2054;
packet.destination = Ipv4Addr::new(10, 20, 30, 40);
udp.recalculate_all(packet.source, packet.destination);
packet.payload = udp.to_bytes();
}
else {
if packet.source == Ipv4Addr::new(10, 20, 30, 40) && udp.source == 2054 {
packet.source = Ipv4Addr::new(udp.payload[0], udp.payload[1], udp.payload[2], udp.payload[3]);
udp.source = u16::from_be_bytes([udp.payload[4], udp.payload[5]]);
udp.payload = udp.payload[6..].to_vec();
udp.recalculate_all(packet.source, packet.destination);
packet.payload = udp.to_bytes();
}
else {
return packet.to_bytes();
}
}
}
Ipv4NextLevelPacket::Unimplemented(_) => {
return packet.to_bytes();
}
}
packet.recalculate_all();
packet.to_bytes()
}
< /code>
Вот мой код сервера: < /p>
use std::{
net::Ipv4Addr,
process::exit,
io::stdin
};
use nfq::{Queue, Verdict};
use tokio::task::spawn;
use packedit::prelude::*;

mod util;
use util::*;

#[tokio::main]
async fn main() {
let mut queue = Queue::open().expect("Не удалось создать очередь входящих пакетов");
queue.bind(2).expect("Не удалось забиндить очередь входящих пакетов");
spawn(handle(queue));
println!("Прокси начал работу");
loop {
let mut buffer = String::new();
stdin().read_line(&mut buffer).unwrap();
if buffer.trim() == String::from("stop") {
println!("Выход...");
println!("Прокси завершил работу");
exit(0);
}
}
}

async fn handle(mut session: Queue) -> () {
let mut connections = Connections::new();
loop {
match session.recv() {
Ok(mut m) => {
m.set_payload(edit_packet(m.get_payload(), &mut connections));
m.set_verdict(Verdict::Accept);
match session.verdict(m) {
Ok(_) => {}
Err(e) => {eprintln!("Не удалось поставить вердикт сообщению: {}", e);}
}
}
Err(e) => {eprintln!("Не удалось получить входящий пакет: {}", e);}
}
}
}

fn edit_packet(bytes: &[u8], connections: &mut Connections) -> Vec {
let mut packet = Ipv4Packet::from_bytes(bytes.to_vec());
match packet.get_next_level_packet() {
Ipv4NextLevelPacket::Tcp(mut tcp) => {
if packet.destination == Ipv4Addr::new(10, 20, 30, 40) {
if tcp.destination == 2054 {
let index = tcp.options.iter().position(|x| x.kind == 253 && x.length == 8).unwrap();
let option = &tcp.options[index];
let res_ip = Ipv4Addr::new(option.data[0], option.data[1], option.data[2], option.data[3]);
let res_port = u16::from_be_bytes([option.data[4], option.data[5]]);
tcp.source = connections.get_outbound_port(res_ip, res_port, packet.source, tcp.source);
tcp.destination = res_port;
packet.source = Ipv4Addr::new(10, 20, 30, 40);
packet.destination = res_ip;
tcp.options.remove(index);
tcp.recalculate_all(packet.source, packet.destination);
packet.payload = tcp.to_bytes()
}
else {
match connections.get_client(packet.source, tcp.source, tcp.destination) {
Some((client_ip, client_port)) => {
let mut option = TcpOption::new();
option.kind = 253;
option.data.append(&mut packet.source.octets().to_vec());
option.data.append(&mut tcp.source.to_be_bytes().to_vec());
packet.source = Ipv4Addr::new(10, 20, 30, 40);
packet.destination = client_ip;
tcp.options.push(option);
tcp.source = 2054;
tcp.destination = client_port;
tcp.recalculate_all(packet.source, packet.destination);
packet.payload = tcp.to_bytes();
}
None => {
eprintln!("Неизвестный пакет без соединения s {}:{} d {}:{}", packet.source, tcp.source, packet.destination, tcp.destination);
return packet.to_bytes();
}
}
}
}
else {
println!("Чужой пакет s {}:{} d {}:{}", packet.source, tcp.source, packet.destination, tcp.destination);
return packet.to_bytes();
}
}
Ipv4NextLevelPacket::Udp(mut udp) => {
if packet.destination == Ipv4Addr::new(10, 20, 30, 40) {
if udp.destination == 2054 {
let res_ip = Ipv4Addr::new(udp.payload[0], udp.payload[1], udp.payload[2], udp.payload[3]);
let res_port = u16::from_be_bytes([udp.payload[4], udp.payload[5]]);
udp.payload = udp.payload[6..].to_vec();
udp.source = connections.get_outbound_port(res_ip, res_port, packet.source, udp.source);
udp.destination = res_port;
packet.source = Ipv4Addr::new(10, 20, 30, 40);
packet.destination = res_ip;
udp.recalculate_all(packet.source, packet.destination);
packet.payload = udp.to_bytes();
}
else {
match connections.get_client(packet.source, udp.source, udp.destination) {
Some((client_ip, client_port)) => {
let mut new_payload = vec![0u8; 6];
new_payload[0..=3].copy_from_slice(&packet.source.octets());
new_payload[4..=5].copy_from_slice(&udp.source.to_be_bytes());
new_payload.append(&mut udp.payload);
udp.payload = new_payload;
packet.source = Ipv4Addr::new(10, 20, 30, 40);
packet.destination = client_ip;
udp.source = 2054;
udp.destination = client_port;
udp.recalculate_all(packet.source, packet.destination);
packet.payload = udp.to_bytes();
}
None => {
eprintln!("Неизвестный пакет без соединения: s {}:{} d {}:{}", packet.source, udp.source, packet.destination, udp.destination);
return packet.to_bytes();
}
}
}
}
else {
println!("Чужой пакет s {}:{} d {}:{}", packet.source, udp.source, packet.destination, udp.destination);
return packet.to_bytes();
}
}
Ipv4NextLevelPacket::Unimplemented(_) => {
return packet.to_bytes();
}
}
packet.recalculate_all();
packet.to_bytes()
}


Подробнее здесь: https://stackoverflow.com/questions/797 ... -dont-work
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Linux»