Userspace WireGuard® Implementation in Rust

Overview

boringtun logo banner

BoringTun

crates.io

BoringTun is an implementation of the WireGuard® protocol designed for portability and speed.

BoringTun is successfully deployed on millions of iOS and Android consumer devices as well as thousands of Cloudflare Linux servers.

The project consists of two parts:

  • The executable boringtun, a userspace WireGuard implementation for Linux and macOS.
  • The library boringtun that can be used to implement fast and efficient WireGuard client apps on various platforms, including iOS and Android. It implements the underlying WireGuard protocol, without the network or tunnel stacks, those can be implemented in a platform idiomatic way.

Installation

You can install this project using cargo:

cargo install boringtun

Building

  • Library only: cargo build --lib --release [--target $(TARGET_TRIPLE)]
  • Executable: cargo build --bin boringtun --release [--target $(TARGET_TRIPLE)]

By default the executable is placed in the ./target/release folder. You can copy it to a desired location manually, or install it using cargo install --bin boringtun --path ..

Running

As per the specification, to start a tunnel use:

boringtun [-f/--foreground] INTERFACE-NAME

The tunnel can then be configured using wg, as a regular WireGuard tunnel, or any other tool.

It is also possible to use with wg-quick by setting the environment variable WG_QUICK_USERSPACE_IMPLEMENTATION to boringtun. For example:

sudo WG_QUICK_USERSPACE_IMPLEMENTATION=boringtun WG_SUDO=1 wg-quick up CONFIGURATION

Testing

Testing this project has a few requirements:

  • sudo: required to create tunnels. When you run cargo test you'll be prompted for your password.
  • Docker: you can install it here. If you are on Ubuntu/Debian you can run apt-get install docker.io.

Benchmarking

To benchmark this project you can run this command:

cargo +nightly bench

This command depends on the unstable test feature of the Rust compiler. As a result, you'll need to use the nightly channel of Rust when you run it.

Supported platforms

Target triple Binary Library
x86_64-unknown-linux-gnu Build Status
aarch64-unknown-linux-gnu Build Status
armv7-unknown-linux-gnueabihf Build Status
x86_64-apple-darwin Build Status
x86_64-pc-windows-msvc Build Status
aarch64-apple-ios FFI bindings
armv7-apple-ios FFI bindings
armv7s-apple-ios FFI bindings
aarch64-linux-android JNI bindings
arm-linux-androideabi JNI bindings

Other platforms may be added in the future

Linux

x86-64, aarch64 and armv7 architectures are supported. The behaviour should be identical to that of wireguard-go, with the following difference:

boringtun will drop privileges when started. When privileges are dropped it is not possible to set fwmark. If fwmark is required, such as when using wg-quick, instead running with sudo, give the executable the CAP_NET_ADMIN capability using: sudo setcap cap_net_admin+epi boringtun. Alternatively run with --disable-drop-privileges or set the environment variable WG_SUDO=1.

macOS

The behaviour is similar to that of wireguard-go. Specifically the interface name must be utun[0-9]+ for an explicit interface name or utun to have the kernel select the lowest available. If you choose utun as the interface name, and the environment variable WG_TUN_NAME_FILE is defined, then the actual name of the interface chosen by the kernel is written to the file specified by that variable.


FFI bindings

The library exposes a set of C ABI bindings, those are defined in the wireguard_ffi.h header file. The C bindings can be used with C/C++, Swift (using a bridging header) or C# (using DLLImport with CallingConvention set to Cdecl).

JNI bindings

The library exposes a set of Java Native Interface bindings, those are defined in src/jni.rs.

License

The project is licensed under the 3-Clause BSD License.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the 3-Clause BSD License, shall licensed as above, without any additional terms or conditions.

If you want to contribute to this project, please read our CONTRIBUTING.md.


WireGuard is a registered trademark of Jason A. Donenfeld. BoringTun is not sponsored or endorsed by Jason A. Donenfeld.

Comments
  • Shared library is not built since v0.5.0

    Shared library is not built since v0.5.0

    As soon as refactoring around workspace is done cargo does not build platform-specific shared and static library anymore. If I add required crate-types for libraries in boringtun/Cargo.toml it builds dynamic and static libraries, but does not include FFI calls there, so library can't be linked anymore. Probably I'm doing something wrong, I'm not a Rust developer, please, help me to get working shared library with expected bindings.

    opened by RandoMan70 20
  • .cargo/config.toml: Add llvm option slp back

    .cargo/config.toml: Add llvm option slp back

    Fixes: 3396860d5f51 ("emit=asm breaks clippy, and is unnecessary")

    Commit 3396860d5f51 deletes RUSTFLAG "llvm-args=-slp-recursion-max-depth" from config file by mistake and causes the benchmark by running "cargo +nightly bench" with performance down. Add this flag to get performance back.

    Signed-off-by: Cathy Zhang [email protected]

    opened by bjzhjing 10
  • compile issue

    compile issue

    run cargo install boringtun produce the following output:

       Compiling chrono v0.4.9
       Compiling boringtun v0.2.0
    error[E0308]: mismatched types
      --> /root/.cargo/registry/src/github.com-1ecc6299db9ec823/boringtun-0.2.0/src/device/tun_linux.rs:77:29
       |
    77 |                 ifru_flags: IFF_TUN | IFF_NO_PI | IFF_MULTI_QUEUE,
       |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected i16, found i32
    
    error: aborting due to previous error
    
    For more information about this error, try `rustc --explain E0308`.
    error: failed to compile `boringtun v0.2.0`, intermediate artifacts can be found at `/tmp/cargo-installRDLTdM`
    
    Caused by:
      Could not compile `boringtun`.
    
    
    

    Any hint on what's going on?

    opened by zTrix 10
  • android build is broken again due to recent changes

    android build is broken again due to recent changes

    In a133f1df70e09052f3fabdcd50cba98d299b0e51 a new argument was added to new_tunnel for the preshared_key, but the usage in src/jni.rs was not updated.

    https://github.com/cloudflare/boringtun/blob/a133f1df70e09052f3fabdcd50cba98d299b0e51/src/jni.rs#L148-L155

    opened by saurik 8
  • Project maintainership status.

    Project maintainership status.

    Is it maintained? Is it recommended for real usage or only for testing?

    NOTE: This crate is still undergoing review for security concerns. Therefore, we recommend that you take caution before using it in a production application.

    Is the review still going on, abandoned or complete? What is the result?

    opened by vi 8
  • Boringtun always in the process .

    Boringtun always in the process .

    I use wg-quick down wgcf or WG_QUICK_USERSPACE_IMPLEMENTATION=boringtun WG_SUDO=1 wg-quick down wgcf to close wireguard.

    Then i use ps -axj | grep boringtun. It is still running. I have to use kill $(pgrep -f boringtun).

    Could I use a command to close it automatically?

    image

    question 
    opened by fscarmen 7
  • Boringtun fails to start on Apple Silicon

    Boringtun fails to start on Apple Silicon

    boringtun compiles succesfully with cargo install --locked --path . on master with Rust v1.49 on Apple Silicon.

    However, when running with boringtun utun, I get the following message:

    Boringtun failed to start.
    

    Related: Homebrew/homebrew-core#68301

    opened by richiksc 7
  • wg complains 'Unable to modify interface: Unknown error -98'

    wg complains 'Unable to modify interface: Unknown error -98'

    Debian 9, default kernel 4.9 rustc version 1.36.0 wg from WireGuard-0.0.20190702.tar.xz

    # boringtun -f -v debug wg1 either doesn't output anything or this:

    Poll error Interrupted system call
    Poll error Interrupted system call
    Poll error Interrupted system call
    Poll error Interrupted system call
    Poll error Interrupted system call
    Poll error Interrupted system call
    Poll error Interrupted system call
    

    README.md says

    The tunnel can then be configured using wg, as a regular WireGuard tunnel, or any other tool.

    but

    # wg setconf wg1 /etc/wireguard/conf
    Unable to modify interface: Unknown error -98
    

    /tmp/boringtun.err is empty and /tmp/boringtun.out contains only one line:

    Success, daemonized
    

    What am I doing wrong?

    opened by Jimmy-Z 7
  • cargo clippy + cargo check fail because of --emit asm

    cargo clippy + cargo check fail because of --emit asm

    ag-dubss-MacBook-Pro:boringtun ag_dubs$ cargo clippy
        Checking boringtun v0.2.0 (/Users/ag_dubs/CloudFlare/boringtun)
    error: crate `base64` required to be available in rlib format, but was not found in this form
    
    error: crate `hex` required to be available in rlib format, but was not found in this form
    
    error: crate `libc` required to be available in rlib format, but was not found in this form
    
    error: crate `ring` required to be available in rlib format, but was not found in this form
    
    error: aborting due to 4 previous errors
    
    error: Could not compile `boringtun`.
    
    To learn more, run the command again with --verbose.
    
    opened by ashleygwilliams 7
  • Usage of CPU features (SSE)

    Usage of CPU features (SSE)

    SSE is known of being able to accelerate ChaCha20 cipher, which is the main cryptographic primitive behind WireGuard. Adaptively enabling SSE on capable hardware could increase performance and energy efficiency of implementation. Kernel implementation does use hardware acceleration via Crypto API

    opened by sh7dm 6
  • installing boringtun in windows 10

    installing boringtun in windows 10

    Hi,

    I haven't used rust before, so I am not sure what's wrong here, just wanted to install boringtun binary.

    Here is the error log:

    C:\WINDOWS\system32>cargo install boringtun
        Updating crates.io index
      Installing boringtun v0.4.0
    warning: output filename collision.
    The bin target `boringtun` in package `boringtun v0.4.0` has the same output filename as the lib target `boringtun` in package `boringtun v0.4.0`.
    Colliding filename is: C:\Users\nawaz\AppData\Local\Temp\cargo-installGxn0iY\release\boringtun.pdb
    The targets should have unique names.
    Consider changing their names to be unique or compiling them separately.
    This may become a hard error in the future; see <https://github.com/rust-lang/cargo/issues/6313>.
       Compiling cfg-if v1.0.0
       Compiling lazy_static v1.4.0
       Compiling proc-macro2 v1.0.36
       Compiling winapi v0.3.9
       Compiling unicode-xid v0.2.2
       Compiling windows_x86_64_msvc v0.32.0
       Compiling log v0.4.14
       Compiling crossbeam-utils v0.8.8
       Compiling syn v1.0.88
       Compiling smallvec v1.8.0
       Compiling parking_lot_core v0.9.1
       Compiling once_cell v1.10.0
       Compiling cc v1.0.73
       Compiling libc v0.2.120
       Compiling scopeguard v1.1.0
       Compiling itoa v1.0.1
       Compiling untrusted v0.7.1
       Compiling pin-project-lite v0.2.8
       Compiling spin v0.5.2
       Compiling ip_network_table-deps-treebitmap v0.5.0
       Compiling ip_network v0.4.1
       Compiling hex v0.4.3
       Compiling base64 v0.13.0
       Compiling untrusted v0.9.0
       Compiling tracing-core v0.1.23
       Compiling sharded-slab v0.1.4
       Compiling thread_local v1.1.4
       Compiling lock_api v0.4.6
       Compiling time v0.3.7
       Compiling ip_network_table v0.2.0
       Compiling ring v0.16.20
       Compiling windows-sys v0.32.0
       Compiling tracing-log v0.1.2
       Compiling crossbeam-channel v0.5.3
       Compiling quote v1.0.15
       Compiling parking_lot v0.12.0
       Compiling ansi_term v0.12.1
       Compiling tracing-subscriber v0.3.9
       Compiling tracing-appender v0.2.1
       Compiling tracing-attributes v0.1.20
       Compiling tracing v0.1.32
       Compiling boringtun v0.4.0
    error[E0433]: failed to resolve: could not find `device` in the crate root
      --> C:\Users\nawaz\.cargo\registry\src\github.com-1ecc6299db9ec823\boringtun-0.4.0\src/main.rs:12:12
       |
    12 | use crate::device::drop_privileges::drop_privileges;
       |            ^^^^^^ could not find `device` in the crate root
    
    error[E0432]: unresolved import `crate::device`
      --> C:\Users\nawaz\.cargo\registry\src\github.com-1ecc6299db9ec823\boringtun-0.4.0\src/main.rs:13:12
       |
    13 | use crate::device::{DeviceConfig, DeviceHandle};
       |            ^^^^^^ could not find `device` in the crate root
    
    error[E0432]: unresolved import `clap`
      --> C:\Users\nawaz\.cargo\registry\src\github.com-1ecc6299db9ec823\boringtun-0.4.0\src/main.rs:14:5
       |
    14 | use clap::{value_t, App, Arg};
       |     ^^^^ use of undeclared crate or module `clap`
    
    error[E0433]: failed to resolve: could not find `unix` in `os`
      --> C:\Users\nawaz\.cargo\registry\src\github.com-1ecc6299db9ec823\boringtun-0.4.0\src/main.rs:17:14
       |
    17 | use std::os::unix::net::UnixDatagram;
       |              ^^^^ could not find `unix` in `os`
    
    error[E0432]: unresolved import `daemonize`
      --> C:\Users\nawaz\.cargo\registry\src\github.com-1ecc6299db9ec823\boringtun-0.4.0\src/main.rs:15:5
       |
    15 | use daemonize::Daemonize;
       |     ^^^^^^^^^ use of undeclared crate or module `daemonize`
    
    error: cannot determine resolution for the macro `value_t`
      --> C:\Users\nawaz\.cargo\registry\src\github.com-1ecc6299db9ec823\boringtun-0.4.0\src/main.rs:98:18
       |
    98 |     let tun_fd = value_t!(matches.value_of("tun-fd"), isize).unwrap_or_else(|e| e.exit());
       |                  ^^^^^^^
       |
       = note: import resolution is stuck, try simplifying macro imports
    
    error: cannot determine resolution for the macro `value_t`
       --> C:\Users\nawaz\.cargo\registry\src\github.com-1ecc6299db9ec823\boringtun-0.4.0\src/main.rs:103:21
        |
    103 |     let n_threads = value_t!(matches.value_of("threads"), usize).unwrap_or_else(|e| e.exit());
        |                     ^^^^^^^
        |
        = note: import resolution is stuck, try simplifying macro imports
    
    error: cannot determine resolution for the macro `value_t`
       --> C:\Users\nawaz\.cargo\registry\src\github.com-1ecc6299db9ec823\boringtun-0.4.0\src/main.rs:105:9
        |
    105 |         value_t!(matches.value_of("verbosity"), tracing::Level).unwrap_or_else(|e| e.exit());
        |         ^^^^^^^
        |
        = note: import resolution is stuck, try simplifying macro imports
    
    error[E0433]: failed to resolve: use of undeclared type `UnixDatagram`
       --> C:\Users\nawaz\.cargo\registry\src\github.com-1ecc6299db9ec823\boringtun-0.4.0\src/main.rs:108:26
        |
    108 |     let (sock1, sock2) = UnixDatagram::pair().unwrap();
        |                          ^^^^^^^^^^^^ use of undeclared type `UnixDatagram`
    
    error[E0425]: cannot find function `drop_privileges` in this scope
       --> C:\Users\nawaz\.cargo\registry\src\github.com-1ecc6299db9ec823\boringtun-0.4.0\src/main.rs:175:25
        |
    175 |         if let Err(e) = drop_privileges() {
        |                         ^^^^^^^^^^^^^^^ not found in this scope
    
    Some errors have detailed explanations: E0425, E0432, E0433.
    For more information about an error, try `rustc --explain E0425`.
    error: failed to compile `boringtun v0.4.0`, intermediate artifacts can be found at `C:\Users\nawaz\AppData\Local\Temp\cargo-installGxn0iY`
    
    Caused by:
      could not compile `boringtun` due to 10 previous errors
    
    

    Thanks

    opened by fawazahmed0 6
  • Clarify that CAP_NET_ADMIN is required

    Clarify that CAP_NET_ADMIN is required

    From the current wording of the README, I thought boringtun could run without CAP_NET_ADMIN- but it can't at all, failing with:

    2023-01-04T23:37:51.496375Z ERROR boringtun_cli: Failed to initialize tunnel, error: IOCtl("Operation not permitted")
    

    It looks like this originates from ioctl(fd, TUNSETIFF as _, &ifr), which is a privileged operation.

    I think I'm not the only one to make this mistake (https://github.com/cloudflare/boringtun/issues/117), so this clarifies that CAP_NET_ADMIN is required.

    opened by zachwalton 0
  • Unable to modify interface: Protocol error

    Unable to modify interface: Protocol error

    Now I use boringtun as wireguard userspace implementation, and I execute this command, there is a certain probability that an error will be reported, and then wireguard will not be available.

    wg set wg-home peer xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx= endpoint xxx.xxx.xxx.xxx:xxxxx
    Unable to modify interface: Protocol error
    
    opened by pexcn 1
  • Set configuration file

    Set configuration file

    Hello, is it possible with boringtun core library to set configuration? My main goal is just to use vpn connection file and setup vpn connection in system with this library. So I have config file with keys, servers from my vpn provider. It looks like:

    [Interface]
    # NetShield = 0
    # Moderate NAT = off
    # VPN Accelerator = on
    PrivateKey = PRIVATE KEY HERE
    Address = SERVER ADDRESS/32
    DNS = SERVER ADDRESS
    
    [Peer]
    PublicKey = PUBLIC KEY HERE
    AllowedIPs = 0.0.0.0/0
    Endpoint = SERVER ADDRESS:51820
    

    How can I "apply" it to created tunnel? So I did the same logic as cli and check with wg show:

    interface: utun42
      listening port: 58873
    

    With wg-quick I can put config file into /etc/wireguard/test.conf and run it: wg-quick up test. And it creates vpn connection and works okay. Can I do the same with only this library? Or I should apply this config file on created tunnel with some other tool?

    opened by max-frai 1
  • Server mode?

    Server mode?

    To the best of my knowledge, boringtun is currently only a wireguard client. We can create a new tunnel with https://github.com/cloudflare/boringtun/blob/5f61297bfb198c9eea7d9b3e1bb32bdd36e403f7/boringtun/src/wireguard_ffi.h#L76-L81 . I didn't find any function to listen for incoming wireguard connection. Will server mode be supported?

    opened by contrun 7
  • Write lock never released

    Write lock never released

    I was experimenting to understand the code base better and discovered that a device handle write lock is never released if mut_func panic!s. As a result, the DeviceHandle's remaining event_loop threads are blocked from doing any other work.

    Generally it's not an issue unless someone is working on api::api_set(). On MacOS, I see my application "freeze" and I have to sudo kill (not sure why but ctrl-c doesn't work once the condition is hit) the process which results in the utun interface hanging around until I reboot.

    opened by thrykol 4
Releases(boringtun-cli-0.5.2)
Owner
Cloudflare
Cloudflare
A Kubernetes implementation of the Open Application Model specification

Rudr ?? NOTE: Rudr is deprecated in favor of the upcoming open application platform project as its successor. There are no plans to produce future rel

Open Application Model 1.6k Jan 4, 2023
Layered bitset implementation

Layered bitsets This crates contains implementation of bitsets with layered structure, allowing fast operations that benifit from skipping large empty

Zakarum 4 Apr 16, 2022
A genetic algorithm for bechmark problems, written to learn Rust.

Genetic Algorithm A genetic algorithm in Rust for the following benchmark problems: Ackley Griewangk Rastrigin Rosenbrock Schwefel Sphere Usage: Insta

Andrew Schwartzmeyer 73 Dec 25, 2022
interative assembly shell written in rust

Overview this project is inspired by https://github.com/poppycompass/asmshell Preview Build from source git clone https://github.com/keystone-engine/k

Xargin 236 Dec 23, 2022
Distributed compute platform implemented in Rust, and powered by Apache Arrow.

Ballista: Distributed Compute Platform Overview Ballista is a distributed compute platform primarily implemented in Rust, powered by Apache Arrow. It

Ballista 2.3k Jan 3, 2023
Drill is a HTTP load testing application written in Rust inspired by Ansible syntax

Drill Drill is a HTTP load testing application written in Rust. The main goal for this project is to build a really lightweight tool as alternative to

Ferran Basora 1.5k Dec 28, 2022
An experimental HTTP load testing application written in Rust.

Herd Herd was a small side project in building a HTTP load testing application in Rust with a main focus on being easy to use and low on OS level depe

Jacob Clark 100 Dec 27, 2022
A fast data collector in Rust

Flowgger is a fast, simple and lightweight data collector written in Rust. It reads log entries over a given protocol, extracts them, decodes them usi

Amazon Web Services - Labs 739 Jan 7, 2023
kytan: High Performance Peer-to-Peer VPN in Rust

kytan: High Performance Peer-to-Peer VPN kytan is a high performance peer to peer VPN written in Rust. The goal is to to minimize the hassle of config

Chang Lan 368 Dec 31, 2022
A purpose-built proxy for the Linkerd service mesh. Written in Rust.

This repo contains the transparent proxy component of Linkerd2. While the Linkerd2 proxy is heavily influenced by the Linkerd 1.X proxy, it comprises

Linkerd 1.7k Jan 7, 2023
Full fake REST API generator written with Rust

Weld Full fake REST API generator. This project is heavily inspired by json-server, written with rust. Synopsis Our first aim is to generate a fake ap

Seray Uzgur 243 Dec 31, 2022
A GPU-accelerated cross-platform terminal emulator and multiplexer written by @wez and implemented in Rust

Wez's Terminal A GPU-accelerated cross-platform terminal emulator and multiplexer written by @wez and implemented in Rust User facing docs and guide a

Wez Furlong 6.7k Jan 2, 2023
pastebin written in pure rust. A rewrite of ptpb/pb.

rspb rust fork of ptpb/pb TL;DR Create a new paste from the output of cmd: cmd | curl -F c=@- https://pb.mgt.moe/ Usage Creating pastes > echo hi | c

mgt 39 Jan 4, 2023
The LibreTranslate API for Rust.

libretranslate-rs A LibreTranslate API for Rust. libretranslate = "0.2.4" libretranslate allows you to use open source machine translation in your pr

Grant Handy 51 Jan 5, 2023
Yet another pager in Rust

rust-pager Yet another pager in Rust Features Vim like keybindings Search substring Mouse wheel support Install cargo install rust-pager Usage <comman

null 19 Dec 7, 2022
A Rust serverless function to retrieve and relay a playlist for Twitch livestreams/VODs.

City17 A Rust serverless function to retrieve and relay a playlist for Twitch livestreams/VODs. By running this in specific countries and using a brow

Malloc Voidstar 5 Dec 15, 2021
Rust runtime for Vercel Functions.

Rust Rust runtime for Vercel Functions. Community-maintained package to support using Rust inside Vercel Functions as a Runtime. Usage First, you'll n

Vercel Community 378 Dec 30, 2022
Userspace WireGuard® Implementation in Rust

BoringTun BoringTun is an implementation of the WireGuard® protocol designed for portability and speed. BoringTun is successfully deployed on millions

Cloudflare 4.8k Jan 4, 2023
wireguard tool to manage / generate configuration. Maintain one yaml configuration file to quickly build wireguard network.

wgx wireguard tool to manage / generate configuration. Maintain one yaml configuration file to quickly build wireguard network. Usage wgx --h USAGE:

yinheli 6 Nov 3, 2022
The reference implementation of the Linux FUSE (Filesystem in Userspace) interface

libfuse About FUSE (Filesystem in Userspace) is an interface for userspace programs to export a filesystem to the Linux kernel. The FUSE project consi

null 4.2k Jan 4, 2023