firezone
wireguardex
Elixir

Configure WireGuard® interfaces in Elixir using Rust NIFs.

Last updated Jun 30, 2026
85
Stars
9
Forks
2
Issues
0
Stars/day
Attention Score
42
Language breakdown
Elixir 70.3%
Rust 29.7%
Files click to expand
README

Wireguardex

Overview

hex.pm hex.pm hex.pm

Wireguardex is an Elixir library for configuring WireGuard® interfaces.

It is exposed as a native library via NIFs implemented in Rust using the rustler and wireguard-control crates.

Used by Firezone to manage WireGuard interfaces in Elixir.

Getting started

Add wireguardex to your dependencies:

def deps do
  [
    {:wireguardex, "~> 0.5"}
  ]
end

Then you can just use wireguardex to manage your wireguard interfaces:

# Imports for cleanliness
import Wireguardex.DeviceConfigBuilder
import Wireguardex.PeerConfigBuilder
import Wireguardex, only: [set_device: 2]

interface_name = "wg0" privatekey = Wireguardex.generateprivate_key() {:ok, publickey} = Wireguardex.getpublickey(privatekey) listen_port = 58210 fwmark = 1234

:ok = device_config() # <-- Start configuring the devices # Here we set configuration for the device |> privatekey(privatekey) |> publickey(publickey) |> listenport(listenport) |> fwmark(fwmark) |> setdevice(interfacename) # <-- This actually creates the interface

After creation you could also add peers:

# Create a peer
peer =
  peer_config()
  |> publickey(publickey)
  |> presharedkey(Wireguardex.generatepreshared_key())
  |> endpoint("127.0.0.1:1234")
  |> persistentkeepaliveinterval(30)
  |> allowed_ips(["255.0.0.0/24", "127.0.0.0/16"])

Add peer to existing device

:ok = Wireguardex.addpeer(interfacename, peer)

And easily remove it afterwards using its public key:

:ok = Wireguardex.removepeer(interfacename, public_key)

To get information on an existing device:

{:ok, device} = Wireguardex.getdevice(interfacename)

Finally to delete a device:

:ok = Wireguardex.deletedevice(interfacename)

Installation

The package can be installed by adding wireguardex to your list of dependencies in mix.exs:

def deps do
  [
    {:wireguardex, "~> 0.3"}
  ]
end

Wireguardex will try to download a precompiled NIF library. If you want to compile your own NIF, you'll need to have Rust installed. The common option is to use Rustup.

To force compilation you can set the environment variable WIREGUARDNIF_BUILD to true or 1. Or you can set the application env to force the NIF to compile:

config :rustlerprecompiled, :forcebuild, wireguardex: true

Note about privileges

This library creates and modifies network interfaces. If you'd like to run this library as a non-root user, we recommend adding the CAPNETADMIN Linux capability to the Erlang VM executable:

sudo setcap 'capnetadmin+eip' <erlanginstallationpath>/bin/beam.smp

If you're using asdf-vm to manage dependencies you can do:

sudo setcap 'capnetadmin+eip' $(ls -1 asdf where erlang 24.3.4/erts-*/bin/beam.smp)

This can be handy for development and testing purposes.

Note: This will also give CAPNETADMIN to any other Erlang programs using this beam.smp executable. If this is undesired, consider using a dedicated Erlang installation or beam.smp executable for this library.

Features

  • Manage WireGuard interfaces
  • Doesn't require a WireGuard installation

Tests

Running the tests in this library will also require a Rust installation, as the NIF is compiled locally before running the tests.

Follow these instructions to install Rust.

Then you can run mix test as long as you have the user privileges to create interfaces.

Pre-commit

We use pre-commit to catch any static analysis issues before code is committed. Install with Homebrew: brew install pre-commit or pip: pip install pre-commit.

Acknowledgments

"WireGuard" and the "WireGuard" logo are registered trademarks of Jason A. Donenfeld.

🔗 More in this category

© 2026 GitRepoTrend · firezone/wireguardex · Updated daily from GitHub