From fc104d5deecef628a8f9ade545c899d147d535a7 Mon Sep 17 00:00:00 2001 From: lubeilin <1791778603@qq.com> Date: Mon, 9 Oct 2023 20:56:04 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=8F=82=E6=95=B0=E5=85=B3?= =?UTF-8?q?=E9=97=ADip=E4=BB=A3=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 +-- vnt-cli/README.md | 5 ++++ vnt-cli/src/config/mod.rs | 4 +++ vnt-cli/src/main.rs | 11 ++++++- vnt-jni/src/vnt_util.rs | 1 + vnt/Cargo.toml | 2 +- vnt/src/core/mod.rs | 7 ++++- vnt/src/handle/recv_handler.rs | 52 ++-------------------------------- vnt/src/handle/tun_tap/mod.rs | 13 ++------- vnt/src/ip_proxy/mod.rs | 41 +++++++++++++++++++++++++++ 10 files changed, 74 insertions(+), 66 deletions(-) diff --git a/README.md b/README.md index 39511ce..33bd0fb 100644 --- a/README.md +++ b/README.md @@ -85,8 +85,8 @@ features说明 | server_encrypt | 支持服务端加密 | 是 | | ip_proxy | 内置ip代理 | 是 | -如果编译时去除了内置的ip代理,则可以使用nat转发来实现点对网 - +如果编译时去除了内置的ip代理(或使用--no-proxy关闭了代理),则可以使用网卡NAT转发来实现点对网, +一般来说使用网卡NAT转发会比内置的ip代理性能更好
NAT配置可参考如下示例,点击展开 ### 在出口一端做如下配置 diff --git a/vnt-cli/README.md b/vnt-cli/README.md index 72e6b86..b682c13 100644 --- a/vnt-cli/README.md +++ b/vnt-cli/README.md @@ -80,6 +80,11 @@ 取值ipv4/ipv6,选择只使用ipv4打洞或者只使用ipv6打洞,默认两则都会使用 ### --port `` 取值0~65535,指定本地监听的端口,默认取随机端口 +### --cmd +开启交互式命令,开启后可以直接在窗口下输入命令,如需后台运行请勿开启 +### --no-proxy +关闭内置的ip代理,内置的代理较为简单,而且一般来说直接使用网卡NAT转发性能会更高, +有需要可以自行配置NAT转发,[可参考‘编译’小节中的NAT配置](https://github.com/lbl8603/vnt#%E7%BC%96%E8%AF%91) ### -f `` 指定配置文件 配置文件采用yaml格式,可参考: diff --git a/vnt-cli/src/config/mod.rs b/vnt-cli/src/config/mod.rs index 5d53cf0..c11a66a 100644 --- a/vnt-cli/src/config/mod.rs +++ b/vnt-cli/src/config/mod.rs @@ -25,6 +25,7 @@ pub struct FileConfig { pub tcp: bool, pub ip: Option, pub relay: bool, + pub no_proxy: bool, pub server_encrypt: bool, pub parallel: usize, pub cipher_model: String, @@ -55,6 +56,7 @@ impl Default for FileConfig { tcp: false, ip: None, relay: false, + no_proxy: false, server_encrypt: false, parallel: 1, cipher_model: "aes_gcm".to_string(), @@ -145,6 +147,8 @@ pub fn read_config(file_path: &str) -> io::Result<(Config, bool)> { file_conf.tcp, virtual_ip, file_conf.relay, + #[cfg(feature = "ip_proxy")] + file_conf.no_proxy, file_conf.server_encrypt, file_conf.parallel, cipher_model, diff --git a/vnt-cli/src/main.rs b/vnt-cli/src/main.rs index ba4fd7b..c193d55 100644 --- a/vnt-cli/src/main.rs +++ b/vnt-cli/src/main.rs @@ -58,6 +58,7 @@ fn main() { opts.optopt("", "punch", "取值ipv4/ipv6", ""); opts.optopt("", "port", "监听的端口", ""); opts.optflag("", "cmd", "开启窗口输入"); + opts.optflag("", "no-proxy", "关闭内置代理"); opts.optopt("f", "", "配置文件", ""); //"后台运行时,查看其他设备列表" opts.optflag("", "list", "后台运行时,查看其他设备列表"); @@ -258,6 +259,8 @@ fn main() { .unwrap_or(PunchModel::All); let port = matches.opt_get::("port").unwrap_or(None).unwrap_or(0); let cmd = matches.opt_present("cmd"); + #[cfg(feature = "ip_proxy")] + let no_proxy = matches.opt_present("no-proxy"); let config = Config::new( tap, token, @@ -274,6 +277,8 @@ fn main() { tcp_channel, virtual_ip, relay, + #[cfg(feature = "ip_proxy")] + no_proxy, server_encrypt, parallel, cipher_model, @@ -528,10 +533,14 @@ fn print_usage(program: &str, _opts: Options) { &enums[1..] ); } - println!(" --finger 增加数据指纹校验,可增加安全性,如果服务端开启指纹校验,则客户端也必须开启"); + if !enums.is_empty() { + println!(" --finger 增加数据指纹校验,可增加安全性,如果服务端开启指纹校验,则客户端也必须开启"); + } println!(" --punch 取值ipv4/ipv6,ipv4表示仅使用ipv4打洞"); println!(" --port 取值0~65535,指定本地监听的端口,默认取随机端口"); println!(" --cmd 开启交互式命令,使用此参数开启控制台输入"); + #[cfg(feature = "ip_proxy")] + println!(" --no-proxy 关闭内置代理,如需点对网则需要配置网卡NAT转发"); println!(); println!( diff --git a/vnt-jni/src/vnt_util.rs b/vnt-jni/src/vnt_util.rs index 60ead60..38bc3bb 100644 --- a/vnt-jni/src/vnt_util.rs +++ b/vnt-jni/src/vnt_util.rs @@ -146,6 +146,7 @@ fn new_sync(env: &mut JNIEnv, config: JObject) -> Result { None, false, false, + false, 1, cipher_model, finger, diff --git a/vnt/Cargo.toml b/vnt/Cargo.toml index 55e9e39..8dd7a8a 100644 --- a/vnt/Cargo.toml +++ b/vnt/Cargo.toml @@ -44,7 +44,7 @@ protobuf-codegen = "3.2.0" protoc-bin-vendored = "3.0.0" [features] -default = ["server_encrypt","aes_gcm","aes_cbc","aes_ecb","sm4_cbc"] +default = ["server_encrypt","aes_gcm","aes_cbc","aes_ecb","sm4_cbc","ip_proxy"] openssl = ["openssl-sys"] # 从源码编译 openssl-vendored = ["openssl-sys/vendored"] diff --git a/vnt/src/core/mod.rs b/vnt/src/core/mod.rs index 16de099..91fccb2 100644 --- a/vnt/src/core/mod.rs +++ b/vnt/src/core/mod.rs @@ -302,7 +302,7 @@ impl VntUtil { Some(ExternalRoute::new(config.in_ips)) }; #[cfg(feature = "ip_proxy")] - let (tcp_proxy, udp_proxy, ip_proxy_map) = if config.out_ips.is_empty() { + let (tcp_proxy, udp_proxy, ip_proxy_map) = if config.out_ips.is_empty() || config.no_proxy { (None, None, None) } else { let (tcp_proxy, udp_proxy, ip_proxy_map) = crate::ip_proxy::init_proxy( @@ -582,6 +582,8 @@ pub struct Config { pub tcp: bool, pub ip: Option, pub relay: bool, + #[cfg(feature = "ip_proxy")] + pub no_proxy: bool, pub server_encrypt: bool, pub parallel: usize, pub cipher_model: CipherModel, @@ -607,6 +609,7 @@ impl Config { tcp: bool, ip: Option, relay: bool, + #[cfg(feature = "ip_proxy")] no_proxy: bool, server_encrypt: bool, parallel: usize, cipher_model: CipherModel, @@ -635,6 +638,8 @@ impl Config { tcp, ip, relay, + #[cfg(feature = "ip_proxy")] + no_proxy, server_encrypt, parallel, cipher_model, diff --git a/vnt/src/handle/recv_handler.rs b/vnt/src/handle/recv_handler.rs index 3232b6e..b5a5653 100644 --- a/vnt/src/handle/recv_handler.rs +++ b/vnt/src/handle/recv_handler.rs @@ -233,57 +233,9 @@ impl ChannelDataHandler { if self.out_external_route.allow(&ipv4.destination_ip()) { #[cfg(feature = "ip_proxy")] if let Some(ip_proxy_map) = &self.ip_proxy_map { - match ipv4.protocol() { - ipv4::protocol::Protocol::Tcp => { - if ip_proxy_map.tcp_handler.recv_handle( - &mut ipv4, - source, - destination, - )? { - return Ok(()); - } - } - ipv4::protocol::Protocol::Udp => { - if ip_proxy_map.udp_handler.recv_handle( - &mut ipv4, - source, - destination, - )? { - return Ok(()); - } - } - #[cfg(not(target_os = "android"))] - ipv4::protocol::Protocol::Icmp => { - if ip_proxy_map.icmp_handler.recv_handle( - &mut ipv4, - source, - destination, - )? { - return Ok(()); - } - } - _ => { - log::warn!( - "不支持的ip代理ipv4协议{:?}:{}->{}->{}", - ipv4.protocol(), - source, - destination, - ipv4.destination_ip() - ); - return Err(Error::Warn( - "不支持的ip代理ipv4协议".to_string(), - )); - } + if ip_proxy_map.recv_handle(&mut ipv4, source, destination)? { + return Ok(()); } - } else { - log::warn!( - "不支持ip代理{:?}:{}->{}->{}", - ipv4.protocol(), - source, - destination, - ipv4.destination_ip() - ); - return Err(Error::Warn("不支持ip代理".to_string())); } } else { log::warn!( diff --git a/vnt/src/handle/tun_tap/mod.rs b/vnt/src/handle/tun_tap/mod.rs index ae65da5..8ed1fc6 100644 --- a/vnt/src/handle/tun_tap/mod.rs +++ b/vnt/src/handle/tun_tap/mod.rs @@ -188,17 +188,8 @@ pub fn base_handle( } #[cfg(feature = "ip_proxy")] if let Some(proxy_map) = proxy_map { - match protocol { - Protocol::Tcp => { - let mut ipv4_packet = IpV4Packet::new(net_packet.payload_mut())?; - proxy_map.tcp_handler.send_handle(&mut ipv4_packet)?; - } - Protocol::Udp => { - let mut ipv4_packet = IpV4Packet::new(net_packet.payload_mut())?; - proxy_map.udp_handler.send_handle(&mut ipv4_packet)?; - } - _ => {} - } + let mut ipv4_packet = IpV4Packet::new(net_packet.payload_mut())?; + proxy_map.send_handle(&mut ipv4_packet)?; } client_cipher.encrypt_ipv4(&mut net_packet)?; //优先发到直连到地址 diff --git a/vnt/src/ip_proxy/mod.rs b/vnt/src/ip_proxy/mod.rs index 1e5ac7b..e379708 100644 --- a/vnt/src/ip_proxy/mod.rs +++ b/vnt/src/ip_proxy/mod.rs @@ -6,6 +6,7 @@ use std::{io, thread}; use crossbeam_utils::atomic::AtomicCell; use dashmap::DashMap; +use packet::ip::ipv4; use tokio::net::UdpSocket; use packet::ip::ipv4::packet::IpV4Packet; @@ -173,3 +174,43 @@ pub fn send( } } } + +impl ProxyHandler for IpProxyMap { + fn recv_handle( + &self, + ipv4: &mut IpV4Packet<&mut [u8]>, + source: Ipv4Addr, + destination: Ipv4Addr, + ) -> io::Result { + match ipv4.protocol() { + ipv4::protocol::Protocol::Tcp => { + self.tcp_handler.recv_handle(ipv4, source, destination) + } + ipv4::protocol::Protocol::Udp => { + self.udp_handler.recv_handle(ipv4, source, destination) + } + #[cfg(not(target_os = "android"))] + ipv4::protocol::Protocol::Icmp => { + self.icmp_handler.recv_handle(ipv4, source, destination) + } + _ => { + log::warn!( + "不支持的ip代理ipv4协议{:?}:{}->{}->{}", + ipv4.protocol(), + source, + destination, + ipv4.destination_ip() + ); + Ok(false) + } + } + } + + fn send_handle(&self, ipv4: &mut IpV4Packet<&mut [u8]>) -> io::Result<()> { + match ipv4.protocol() { + ipv4::protocol::Protocol::Tcp => self.tcp_handler.send_handle(ipv4), + ipv4::protocol::Protocol::Udp => self.udp_handler.send_handle(ipv4), + _ => Ok(()), + } + } +}