Rust WireGuard用户空间API库wireguard-uapi的使用:实现高效安全的VPN隧道配置与管理

Rust WireGuard用户空间API库wireguard-uapi的使用:实现高效安全的VPN隧道配置与管理

wireguard-uapi-rs简介

这是一个为Linux系统实现的WireGuard Netlink API的Rust库。

主要功能:

  • 完全支持读取WireGuard设备接口
  • 部分支持创建新的WireGuard设备接口(可以创建和删除设备接口,但目前不支持为这些设备添加IP地址)

快速示例

use failure;
use wireguard_uapi::{DeviceInterface, WgSocket};

fn main() -> Result<(), failure::Error> {
  let mut wg = WgSocket::connect()?;
  let device = wg.get_device(DeviceInterface::from_name("wgtest0"))?;

  print_device(&device);
  Ok(())
}

权限要求

编译后的二进制文件需要CAP_NET_ADMIN能力来读取网络接口。如果使用此库时遇到访问错误,请确保编译后的可执行文件具有该权限。如果您信任编译后的二进制文件,一种授权方法是:

sudo setcap CAP_NET_ADMIN=+eip ./my-compiled-binary

开发设置

与上述类似,编译的测试二进制文件需要与内核交互的权限。最简单的方法是使用sudo运行测试:

# .cargo/config.toml

[target.x86_64-unknown-linux-gnu]
runner = "sudo"

[target.aarch64-unknown-linux-gnu]
runner = "sudo"

免责声明

这不是官方的WireGuard产品。(虽然我有兴趣将其变成官方产品。)

欢迎提交bug报告。

完整示例代码

use std::error::Error;
use wireguard_uapi::{DeviceInterface, WgSocket};

// 打印设备信息
fn print_device(device: &wireguard_uapi::Device) {
    println!("Device: {}", device.ifname);
    println!("Public key: {:?}", device.public_key);
    println!("Private key: {:?}", device.private_key);
    println!("Listen port: {:?}", device.listen_port);
    println!("Fwmark: {:?}", device.fwmark);
    println!("Peers count: {}", device.peers.len());
    
    for peer in &device.peers {
        println!("\nPeer public key: {:?}", peer.public_key);
        println!("Preshared key: {:?}", peer.preshared_key);
        println!("Endpoint: {:?}", peer.endpoint);
        println!("Allowed ips: {:?}", peer.allowedips);
        println!("Last handshake: {:?}", peer.last_handshake_time);
    }
}

fn main() -> Result<(), Box<dyn Error>> {
    // 创建WireGuard套接字连接
    let mut wg = WgSocket::connect()?;
    
    // 获取指定名称的设备信息
    let device = wg.get_device(DeviceInterface::from_name("wg0"))?;
    
    // 打印设备信息
    print_device(&device);
    
    Ok(())
}

安装方法

在项目目录中运行以下Cargo命令:

cargo add wireguard-uapi

或者在Cargo.toml中添加以下行:

wireguard-uapi = "3.0.1"

许可证

MIT许可证


1 回复

Rust WireGuard用户空间API库wireguard-uapi使用指南

简介

wireguard-uapi是一个Rust库,提供了与WireGuard用户空间API交互的功能,允许开发者以编程方式配置和管理WireGuard VPN隧道。这个库是对WireGuard内核模块用户空间API的Rust封装,提供了类型安全的接口来创建、配置和管理VPN隧道。

主要特性

  • 类型安全的WireGuard配置接口
  • 支持创建和管理WireGuard隧道
  • 支持对等体和密钥配置
  • 与Linux内核WireGuard模块交互
  • 异步友好的设计

安装

在Cargo.toml中添加依赖:

[dependencies]
wireguard-uapi = "0.1"
tokio = { version = "1.0", features = ["full"] } # 如果需要异步支持

完整示例代码

以下是基于内容提供的示例整合的完整WireGuard管理程序:

use wireguard_uapi::{Device, Config, Peer, AllowedIp};
use wireguard_uapi::crypto::{gen_private_key, gen_public_key};
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
use std::path::Path;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 1. 创建WireGuard设备
    let device_name = "wg0";
    let device_path = Path::new("/dev/net/tun");
    let device = Device::create(device_name, device_path).await?;
    println!("WireGuard设备创建成功: {}", device_name);

    // 2. 生成密钥
    let private_key = gen_private_key();
    let public_key = gen_public_key(&private_key);
    println!("生成的私钥: {:?}", private_key);
    println!("对应的公钥: {:?}", public_key);

    // 3. 配置设备参数
    let config = Config {
        listen_port: Some(51820),
        fwmark: None,
        private_key: Some(private_key),
        replace_peers: true,
        ..Default::default()
    };
    device.configure(&config).await?;
    println!("WireGuard设备基本配置完成");

    // 4. 添加对等体
    let peer = Peer {
        public_key: [0u8; 32], // 替换为实际对等体公钥
        preshared_key: None,
        endpoint: Some(SocketAddr::new(IpAddr::V4(Ipv4Addr::new(192, 168, 1, 100)), 51820)),
        persistent_keepalive_interval: Some(25),
        allowed_ips: vec![
            AllowedIp {
                addr: IpAddr::V4(Ipv4Addr::new(10, 0, 0, 2)),
                cidr_mask: 32,
            }
        ],
        ..Default::default()
    };
    device.add_peer(&peer).await?;
    println!("对等体添加完成");

    // 5. 获取设备信息
    let info = device.get_info().await?;
    println!("当前设备信息: {:?}", info);
    
    let peers = device.get_peers().await?;
    println!("当前对等体列表: {:?}", peers);

    // 6. 删除设备(演示用,实际可能需要保留)
    Device::delete(device_name).await?;
    println!("WireGuard设备已删除");

    Ok(())
}

代码说明

  1. 设备创建:使用Device::create创建新的WireGuard虚拟网络设备
  2. 密钥生成:使用内置的gen_private_keygen_public_key函数生成WireGuard所需的密钥对
  3. 设备配置:通过Config结构体配置设备参数,包括监听端口和私钥
  4. 对等体管理:使用Peer结构体定义对等体参数,包括公钥、端点地址和允许的IP范围
  5. 信息查询:调用get_infoget_peers获取设备当前状态
  6. 设备删除:演示如何使用Device::delete删除创建的设备

注意事项

  1. 运行此程序需要Linux系统和已安装的WireGuard内核模块
  2. 需要root权限或CAP_NET_ADMIN能力
  3. 生产环境中应考虑添加更完善的错误处理和日志记录
  4. 密钥管理应当谨慎,避免硬编码在代码中

扩展建议

  1. 可以将配置参数提取到外部配置文件
  2. 添加更完整的错误处理逻辑
  3. 实现定期状态检查功能
  4. 添加日志记录功能,便于问题排查
回到顶部