Rust SOCKS5协议实现库socks5-impl的使用,支持高性能代理服务器和客户端开发

Rust SOCKS5协议实现库socks5-impl的使用,支持高性能代理服务器和客户端开发

socks5-impl是一个基于tokio的异步SOCKS5协议实现库,提供了SOCKS5协议的基本抽象和异步读写功能。

特性

  • 完全异步
  • 支持所有SOCKS5命令
    • CONNECT
    • BIND
    • ASSOCIATE
  • 可定制的认证方式
    • 无需认证
    • 用户名/密码
    • GSSAPI

使用示例

以下是基本SOCKS5服务器处理示例:

use socks5_impl::protocol::{handshake, Address, AuthMethod, Reply, Request, Response, StreamOperation};

fn main() -> socks5_impl::Result<()> {
    // 绑定TCP监听端口
    let listener = std::net::TcpListener::bind("127.0.0.1:5000")?;
    let (mut stream, _) = listener.accept()?;

    // 获取客户端握手请求
    let request = handshake::Request::retrieve_from_stream(&mut stream)?;

    // 检查客户端是否支持无认证
    if request.evaluate_method(AuthMethod::NoAuth) {
        let response = handshake::Response::new(AuthMethod::NoAuth);
        response.write_to_stream(&mut stream)?;
    } else {
        // 返回无可用认证方法错误
        let response = handshake::Response::new(AuthMethod::NoAcceptableMethods);
        response.write_to_stream(&mut stream)?;
        let _ = stream.shutdown(std::net::Shutdown::Both);
        let err = "No available handshake method provided by client";
        return Err(std::io::Error::new(std::io::ErrorKind::Unsupported, err).into());
    }

    // 获取客户端请求
    let req = match Request::retrieve_from_stream(&mut stream) {
        Ok(req) => req,
        Err(err) => {
            // 返回通用错误响应
            let resp = Response::new(Reply::GeneralFailure, Address::unspecified());
            resp.write_to_stream(&mut stream)?;
            let _ = stream.shutdown(std::net::Shutdown::Both);
            return Err(err.into());
        }
    };

    // 处理请求命令
    match req.command {
        _ => {} // 实际处理逻辑
    }

    Ok(())
}

完整SOCKS5服务器示例

以下是一个完整的异步SOCKS5服务器实现:

use socks5_impl::server::Server;
use socks5_impl::protocol::{AuthMethod, Reply, Command, Response};
use tokio::io::{AsyncReadExt, AsyncWriteExt};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 创建SOCKS5服务器实例
    let mut server = Server::new();
    
    // 配置支持的认证方法
    server.add_auth_method(AuthMethod::NoAuth);
    
    // 设置请求处理器
    server.set_request_handler(|req, mut stream| async move {
        match req.command {
            // 处理CONNECT命令
            Command::Connect => {
                println!("接收到CONNECT请求,目标: {:?}", req.destination);
                
                // 尝试连接到目标服务器
                let mut target = match tokio::net::TcpStream::connect(req.destination.to_string()).await {
                    Ok(t) => t,
                    Err(e) => {
                        // 返回主机不可达错误
                        let resp = Response::new(Reply::HostUnreachable, Address::unspecified());
                        resp.write_to_stream(&mut stream).await?;
                        return Err(e.into());
                    }
                };
                
                // 返回成功响应
                let resp = Response::new(Reply::Succeeded, Address::unspecified());
                resp.write_to_stream(&mut stream).await?;
                
                // 拆分读写流
                let (mut client_read, mut client_write) = stream.split();
                let (mut target_read, mut target_write) = target.split();
                
                // 双向数据转发
                tokio::select! {
                    _ = tokio::io::copy(&mut client_read, &mut target_write) => {},
                    _ = tokio::io::copy(&mut target_read, &mut client_write) => {},
                }
                
                Ok(())
            }
            _ => {
                // 返回不支持的命令错误
                let resp = Response::new(Reply::CommandNotSupported, Address::unspecified());
                resp.write_to_stream(&mut stream).await?;
                Ok(())
            }
        }
    });
    
    // 启动服务器监听端口
    println!("SOCKS5服务器启动在127.0.0.1:1080");
    server.listen("127.0.0.1:1080").await?;
    
    Ok(())
}

完整SOCKS5客户端示例

以下是一个完整的SOCKS5客户端实现:

use socks5_impl::client::Client;
use tokio::io::{AsyncReadExt, AsyncWriteExt};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 创建SOCKS5客户端并连接到代理服务器
    let mut client = Client::new("127.0.0.1:1080").await?;
    
    // 配置认证方式(此处为无认证)
    client.set_auth(None);
    
    // 通过代理连接到目标服务器
    let mut stream = client.connect("example.com:80").await?;
    println!("成功通过SOCKS5代理连接到example.com:80");
    
    // 发送HTTP GET请求
    let request = b"GET / HTTP/1.1\r\nHost: example.com\r\nConnection: close\r\n\r\n";
    stream.write_all(request).await?;
    println!("已发送HTTP请求");
    
    // 读取响应数据
    let mut buf = Vec::new();
    stream.read_to_end(&mut buf).await?;
    println!("收到响应数据: {}字节", buf.len());
    println!("响应首行: {}", String::from_utf8_lossy(&buf[..buf.len().min(100)]));
    
    Ok(())
}

安装方法

在项目中添加依赖:

cargo add socks5-impl

或者在Cargo.toml中添加:

[dependencies]
socks5-impl = "0.7.2"
tokio = { version = "1.0", features = ["full"] }

许可证

GNU General Public License v3.0


1 回复

Rust SOCKS5协议实现库socks5-impl使用指南

socks5-impl是一个用于实现SOCKS5协议的Rust库,支持高性能代理服务器和客户端开发。

特性

  • 完整的SOCKS5协议实现
  • 支持TCP和UDP代理
  • 异步/同步API
  • 支持认证(无认证/用户名密码认证)
  • 高性能设计

添加依赖

在Cargo.toml中添加:

[dependencies]
socks5-impl = "0.3"
tokio = { version = "1.0", features = ["full"] } # 如果使用异步

基本使用

1. 创建SOCKS5服务器

use socks5_impl::server::{Socks5Server, Socks5Socket};
use tokio::io::{AsyncReadExt, AsyncWriteExt};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 创建SOCKS5服务器,监听1080端口
    let server = Socks5Server::bind("127.0.0.1:1080").await?;
    
    // 接受客户端连接
    let socket = server.accept().await?;
    
    // 处理连接
    match socket {
        Socks5Socket::Associate(associate) => {
            println!("UDP associate request from {}", associate.peer_addr());
        }
        Socks5Socket::Bind(bind) => {
            println!("Bind request from {}", bind.peer_addr());
        }
        Socks5Socket::Connect(connect) => {
            println!("Connect request to {} from {}", connect.dest_addr(), connect.peer_addr());
            
            // 连接到目标服务器
            let mut remote = connect.connect().await?;
            
            // 在这里可以进行数据转发
            let mut buf = [0u8; 1024];
            loop {
                let n = remote.read(&mut buf).await?;
                if n == 0 {
                    break;
                }
                remote.write_all(&buf[..n]).await?;
            }
        }
    }
    
    Ok(())
}

2. 创建SOCKS5客户端

use socks5_impl::client::{Socks5Stream, AuthMethod};
use tokio::io::{AsyncReadExt, AsyncWriteExt};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 连接到SOCKS5服务器
    let mut stream = Socks5Stream::connect(
        "127.0.0.1:1080",  // SOCKS5服务器地址
        "example.com:80",   // 目标地址
        Some(("username", "password")), // 认证信息(可选)
        AuthMethod::Password, // 认证方法
    ).await?;
    
    // 通过代理发送HTTP请求
    stream.write_all(b"GET / HTTP/1.1\r\nHost: example.com\r\n\r\n").await?;
    
    // 读取响应
    let mut buf = vec![0u8; 1024];
    let n = stream.read(&mut buf).await?;
    println!("{}", String::from_utf8_lossy(&buf[..n]));
    
    Ok(())
}

高级功能

UDP关联

use socks5_impl::protocol::UdpHeader;
use socks5_impl::client::Socks5Datagram;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 创建UDP关联
    let datagram = Socks5Datagram::bind(
        "127.0.0.1:1080", 
        Some(("username", "password")),
        AuthMethod::Password,
    ).await?;
    
    // 发送UDP数据
    let header = UdpHeader::new(0, "example.com:53".parse()?);
    datagram.send_to(&header, b"test data").await?;
    
    // 接收UDP数据
    let mut buf = [0u8; 1024];
    let (n, _) = datagram.recv_from(&mut buf).await?;
    println!("Received: {:?}", &buf[..n]);
    
    Ok(())
}

自定义认证方法

use socks5_impl::server::{Socks5Server, Socks5Socket, Auth};
use socks5_impl::protocol::AuthMethod;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 创建带认证的服务器
    let server = Socks5Server::bind("127.0.0.1:1080")
        .auth(Auth::new()
            .method(AuthMethod::Password)
            .add_user("user1", "pass1")
            .add_user("user2", "pass2"))
        .await?;
    
    // 处理连接...
    
    Ok(())
}

性能提示

  1. 对于高性能服务器,考虑使用Arc共享配置
  2. 使用连接池管理到目标服务器的连接
  3. 对于大量UDP流量,考虑专门的UDP处理线程

socks5-impl提供了灵活且高性能的SOCKS5实现,适合构建各种代理应用。

回到顶部