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.
Add wireguardex
to your dependencies:
def deps do
[
{:wireguardex, "~> 0.3"}
]
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"
private_key = Wireguardex.generate_private_key()
{:ok, public_key} = Wireguardex.get_public_key(private_key)
listen_port = 58210
fwmark = 1234
:ok =
device_config() # <-- Start configuring the devices
# Here we set configuration for the device
|> private_key(private_key)
|> public_key(public_key)
|> listen_port(listen_port)
|> fwmark(fwmark)
|> set_device(interface_name) # <-- This actually creates the interface
After creation you could also add peers:
# Create a peer
peer =
peer_config()
|> public_key(public_key)
|> preshared_key(Wireguardex.generate_preshared_key())
|> endpoint("127.0.0.1:1234")
|> persistent_keepalive_interval(30)
|> allowed_ips(["255.0.0.0/24", "127.0.0.0/16"])
# Add peer to existing device
:ok = Wireguardex.add_peer(interface_name, peer)
And easily remove it afterwards using its public key:
:ok = Wireguardex.remove_peer(interface_name, public_key)
To get information on an existing device:
{:ok, device} = Wireguardex.get_device(interface_name)
Finally to delete a device:
:ok = Wireguardex.delete_device(interface_name)
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 :rustler_precompiled, :force_build, wireguardex: true
This library creates and modifies network interfaces. If you'd like to run this library as a non-root user, we recommend adding the CAP_NET_ADMIN
Linux capability to the Erlang VM executable:
sudo setcap 'cap_net_admin+eip' <erlang_installation_path>/bin/beam.smp
If you're using asdf-vm to manage dependencies you can do:
sudo setcap 'cap_net_admin+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 CAP_NET_ADMIN
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.
- Manage WireGuard interfaces
- Doesn't require a WireGuard installation
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.
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
.
"WireGuard" and the "WireGuard" logo are registered trademarks of Jason A. Donenfeld.