progress
Former-commit-id: 2c8d8ac3845be86db0032025a127865f1f6d4ee7 [formerly 7550a9453455a95cb7583d582b5ac36d5a2c4e85] [formerly 39ce55e6191ae0f82e97708165be5fb27bffad51 [formerly e6c8f9d061578f0aad10fd974fb30bba6fb980d2]] Former-commit-id: 29b3ac95435e35e66a93aada96692dde1d5d6213 [formerly afaaf09642072cec135a9fe451510be3ec2196e1] Former-commit-id: 6ea160887038963bc34a6fb0b93baa318286f068 Former-commit-id: 40d8cad8790877c1d0712dfcd828939f4585dd38 Former-commit-id: a3de18cc4ac432e9aac64c30b05fc86f6fcf6b42 Former-commit-id: 7193a47d510ecd22b43a001b8b128b24643f6e42 [formerly 5a0575a31f03fe2754ed3a2c784f6181bc654456] Former-commit-id: 9aef01bbe49921a4e0cc3eda2ecf929e476eacff
This commit is contained in:
parent
ef112495ae
commit
a15e8a2548
5 changed files with 169 additions and 12 deletions
73
Cargo.lock
generated
73
Cargo.lock
generated
|
@ -92,6 +92,17 @@ version = "1.0.75"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6"
|
checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "async-trait"
|
||||||
|
version = "0.1.74"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "atomic"
|
name = "atomic"
|
||||||
version = "0.5.3"
|
version = "0.5.3"
|
||||||
|
@ -267,6 +278,20 @@ dependencies = [
|
||||||
"crypto-common",
|
"crypto-common",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fast-socks5"
|
||||||
|
version = "0.9.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "aa6a4a9ab1f87e2d8e9345ce944de7c45d065ee89f5942512f32698e48a8429a"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"async-trait",
|
||||||
|
"log",
|
||||||
|
"thiserror",
|
||||||
|
"tokio",
|
||||||
|
"tokio-stream",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fastwebsockets"
|
name = "fastwebsockets"
|
||||||
version = "0.4.4"
|
version = "0.4.4"
|
||||||
|
@ -467,12 +492,12 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "jsonwebtoken"
|
name = "jsonwebtoken"
|
||||||
version = "8.3.0"
|
version = "9.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6971da4d9c3aa03c3d8f3ff0f4155b534aad021292003895a469716b2a230378"
|
checksum = "1e863f95209c79b9b8b001c4b03463385f890a765dbc4e0802cb8d4177e3e410"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64",
|
"base64",
|
||||||
"ring",
|
"ring 0.17.4",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
]
|
]
|
||||||
|
@ -779,12 +804,26 @@ dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
"libc",
|
"libc",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"spin",
|
"spin 0.5.2",
|
||||||
"untrusted",
|
"untrusted 0.7.1",
|
||||||
"web-sys",
|
"web-sys",
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ring"
|
||||||
|
version = "0.17.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fce3045ffa7c981a6ee93f640b538952e155f1ae3a1a02b84547fc7a56b7059a"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
"getrandom",
|
||||||
|
"libc",
|
||||||
|
"spin 0.9.8",
|
||||||
|
"untrusted 0.9.0",
|
||||||
|
"windows-sys",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustc-demangle"
|
name = "rustc-demangle"
|
||||||
version = "0.1.23"
|
version = "0.1.23"
|
||||||
|
@ -798,7 +837,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cd8d6c9f025a446bc4d18ad9632e69aec8f287aa84499ee335599fabd20c3fd8"
|
checksum = "cd8d6c9f025a446bc4d18ad9632e69aec8f287aa84499ee335599fabd20c3fd8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"ring",
|
"ring 0.16.20",
|
||||||
"rustls-webpki",
|
"rustls-webpki",
|
||||||
"sct",
|
"sct",
|
||||||
]
|
]
|
||||||
|
@ -830,8 +869,8 @@ version = "0.101.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3c7d5dece342910d9ba34d259310cae3e0154b873b35408b787b59bce53d34fe"
|
checksum = "3c7d5dece342910d9ba34d259310cae3e0154b873b35408b787b59bce53d34fe"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ring",
|
"ring 0.16.20",
|
||||||
"untrusted",
|
"untrusted 0.7.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -861,8 +900,8 @@ version = "0.7.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4"
|
checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ring",
|
"ring 0.16.20",
|
||||||
"untrusted",
|
"untrusted 0.7.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -995,6 +1034,12 @@ version = "0.5.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
|
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "spin"
|
||||||
|
version = "0.9.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "strsim"
|
name = "strsim"
|
||||||
version = "0.10.0"
|
version = "0.10.0"
|
||||||
|
@ -1257,6 +1302,12 @@ version = "0.7.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
|
checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "untrusted"
|
||||||
|
version = "0.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "url"
|
name = "url"
|
||||||
version = "2.4.1"
|
version = "2.4.1"
|
||||||
|
@ -1478,11 +1529,13 @@ dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"base64",
|
"base64",
|
||||||
"clap",
|
"clap",
|
||||||
|
"fast-socks5",
|
||||||
"fastwebsockets",
|
"fastwebsockets",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"hyper",
|
"hyper",
|
||||||
"jsonwebtoken",
|
"jsonwebtoken",
|
||||||
"libc",
|
"libc",
|
||||||
|
"log",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"pin-project",
|
"pin-project",
|
||||||
"rustls-native-certs",
|
"rustls-native-certs",
|
||||||
|
|
|
@ -19,19 +19,21 @@ ahash = { version = "0.8.3", features = []}
|
||||||
pin-project = "1"
|
pin-project = "1"
|
||||||
scopeguard = "1.2.0"
|
scopeguard = "1.2.0"
|
||||||
uuid = { version = "1.4.1", features = ["v7", "serde"] }
|
uuid = { version = "1.4.1", features = ["v7", "serde"] }
|
||||||
jsonwebtoken = { version = "8.3.0", default-features = false }
|
jsonwebtoken = { version = "9.0.0", default-features = false }
|
||||||
rustls-pemfile = { version = "1.0.3", features = [] }
|
rustls-pemfile = { version = "1.0.3", features = [] }
|
||||||
|
|
||||||
rustls-native-certs = { version = "0.6.3", features = [] }
|
rustls-native-certs = { version = "0.6.3", features = [] }
|
||||||
tokio = { version = "1.32.0", features = ["full"] }
|
tokio = { version = "1.32.0", features = ["full"] }
|
||||||
tokio-rustls = { version = "0.24.1", features = ["tls12", "dangerous_configuration", "early-data"] }
|
tokio-rustls = { version = "0.24.1", features = ["tls12", "dangerous_configuration", "early-data"] }
|
||||||
tokio-stream = { version = "0.1.14", features = ["net"] }
|
tokio-stream = { version = "0.1.14", features = ["net"] }
|
||||||
|
fast-socks5 = { version = "0.9.1", features = [] }
|
||||||
futures-util = { version = "0.3.28" }
|
futures-util = { version = "0.3.28" }
|
||||||
|
|
||||||
tracing = { version = "0.1.37", features = ["log"] }
|
tracing = { version = "0.1.37", features = ["log"] }
|
||||||
tracing-subscriber = { version = "0.3.17", features = ["env-filter", "fmt", "local-time"] }
|
tracing-subscriber = { version = "0.3.17", features = ["env-filter", "fmt", "local-time"] }
|
||||||
base64 = "0.21.4"
|
base64 = "0.21.4"
|
||||||
serde = { version = "1.0.188", features = ["derive"] }
|
serde = { version = "1.0.188", features = ["derive"] }
|
||||||
|
log = "0.4.20"
|
||||||
|
|
||||||
[target.'cfg(target_family = "unix")'.dependencies]
|
[target.'cfg(target_family = "unix")'.dependencies]
|
||||||
tokio-fd = "0.3.0"
|
tokio-fd = "0.3.0"
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
mod embedded_certificate;
|
mod embedded_certificate;
|
||||||
|
mod socks5;
|
||||||
#[cfg(target_family = "unix")]
|
#[cfg(target_family = "unix")]
|
||||||
mod stdio;
|
mod stdio;
|
||||||
mod tcp;
|
mod tcp;
|
||||||
|
|
101
src/socks5.rs
Normal file
101
src/socks5.rs
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
use anyhow::Context;
|
||||||
|
use fast_socks5::server::{Config, DenyAuthentication, Socks5Server};
|
||||||
|
use fast_socks5::util::target_addr::TargetAddr;
|
||||||
|
use futures_util::{stream, Stream, StreamExt};
|
||||||
|
use std::net::SocketAddr;
|
||||||
|
use std::pin::Pin;
|
||||||
|
use std::task::Poll;
|
||||||
|
use tokio::net::TcpStream;
|
||||||
|
|
||||||
|
use log::warn;
|
||||||
|
use tracing::{info, warn};
|
||||||
|
use url::Host;
|
||||||
|
|
||||||
|
pub struct Socks5Listener {
|
||||||
|
stream: Pin<Box<dyn Stream<Item = anyhow::Result<(TcpStream, Host, u16)>>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Stream for Socks5Listener {
|
||||||
|
type Item = anyhow::Result<(TcpStream, Host, u16)>;
|
||||||
|
|
||||||
|
fn poll_next(
|
||||||
|
self: Pin<&mut Self>,
|
||||||
|
cx: &mut std::task::Context<'_>,
|
||||||
|
) -> Poll<Option<Self::Item>> {
|
||||||
|
unsafe { self.map_unchecked_mut(|x| &mut x.stream) }.poll_next(cx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn run_server(bind: SocketAddr) -> Result<Socks5Listener, anyhow::Error> {
|
||||||
|
info!("Starting TCP server listening cnx on {}", bind);
|
||||||
|
|
||||||
|
let server = Socks5Server::<DenyAuthentication>::bind(bind)
|
||||||
|
.await
|
||||||
|
.with_context(|| format!("Cannot create socks5 server {:?}", bind))?;
|
||||||
|
|
||||||
|
let mut cfg = Config::<DenyAuthentication>::default();
|
||||||
|
cfg.set_allow_no_auth(true);
|
||||||
|
cfg.set_dns_resolve(false);
|
||||||
|
cfg.set_execute_command(false);
|
||||||
|
|
||||||
|
let server = server.with_config(cfg);
|
||||||
|
let stream = stream::unfold(server, move |server| async {
|
||||||
|
let mut acceptor = server.incoming();
|
||||||
|
loop {
|
||||||
|
let cnx = match acceptor.next().await {
|
||||||
|
None => return None,
|
||||||
|
Some(Err(err)) => {
|
||||||
|
drop(acceptor);
|
||||||
|
return Some((Err(anyhow::Error::new(err)), server));
|
||||||
|
}
|
||||||
|
Some(Ok(cnx)) => cnx,
|
||||||
|
};
|
||||||
|
|
||||||
|
let cnx = match cnx.upgrade_to_socks5().await {
|
||||||
|
Ok(cnx) => cnx,
|
||||||
|
Err(err) => {
|
||||||
|
warn!("Rejecting socks5 cnx: {}", err);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let Some(target) = cnx.target_addr() else {
|
||||||
|
warn!("Rejecting socks5 cnx: no target addr");
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
let (host, port) = match target {
|
||||||
|
TargetAddr::Ip(SocketAddr::V4(ip)) => (Host::Ipv4(*ip.ip()), ip.port()),
|
||||||
|
TargetAddr::Ip(SocketAddr::V6(ip)) => (Host::Ipv6(*ip.ip()), ip.port()),
|
||||||
|
TargetAddr::Domain(host, port) => (Host::Domain(host.clone()), *port),
|
||||||
|
};
|
||||||
|
drop(acceptor);
|
||||||
|
return Some((Ok((cnx.into_inner(), host, port)), server));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let listener = Socks5Listener {
|
||||||
|
stream: Box::pin(stream),
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(listener)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use super::*;
|
||||||
|
use futures_util::StreamExt;
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn socks5_server() {
|
||||||
|
let mut x = run_server(SocketAddr::from_str("[::]:4343").unwrap())
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
loop {
|
||||||
|
let cnx = x.next().await.unwrap().unwrap();
|
||||||
|
eprintln!("{:?}", cnx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,7 +10,7 @@ use anyhow::Context;
|
||||||
use fastwebsockets::{
|
use fastwebsockets::{
|
||||||
Frame, OpCode, Payload, WebSocket, WebSocketError, WebSocketRead, WebSocketWrite,
|
Frame, OpCode, Payload, WebSocket, WebSocketError, WebSocketRead, WebSocketWrite,
|
||||||
};
|
};
|
||||||
use futures_util::{pin_mut};
|
use futures_util::pin_mut;
|
||||||
use hyper::header::{AUTHORIZATION, SEC_WEBSOCKET_VERSION, UPGRADE};
|
use hyper::header::{AUTHORIZATION, SEC_WEBSOCKET_VERSION, UPGRADE};
|
||||||
use hyper::header::{CONNECTION, HOST, SEC_WEBSOCKET_KEY};
|
use hyper::header::{CONNECTION, HOST, SEC_WEBSOCKET_KEY};
|
||||||
use hyper::server::conn::Http;
|
use hyper::server::conn::Http;
|
||||||
|
|
Loading…
Reference in a new issue