Announcing wg2nd: Migrate WireGuard Configurations to networkd
Today, I am excited to release wg2nd
, a tool specifically engineered to convert WireGuard configurations
from the wg-quick(8)
format to systemd-networkd
compatible configurations.
Purpose
wg2nd
serves as a bridge to translate wg-quick
configurations into networkd
configurations without
requiring additional setup. networkd
is a feature-complete network manager, allowing users greater
control over WireGuard tunnels. This tool also addresses potential reliability issues that may arise
when networkd
interferes with tunnels it doesn't manage. Moreover, wg2nd
can batch-convert wg-quick
configurations to networkd
.
Goals of the Project
Compatibility:
wg2nd
supports allwg-quick
configurations except those that involvePreUp
,PostUp
,PreDown
, andPostDown
scripts, which are omitted.Security: Private and symmetric keys are stored in keyfiles with restricted access permissions.
wg2nd
leverages the same formally-verified Curve25519 implementation employed in WireGuard. All operations involving private keys are executed in constant-time. Additionally, the web port operates entirely on the client-side. It does not transmit or store any sensitive data.Reproducibility:
wg2nd
generates configurations deterministically with respect to the input WireGuard configuration. When updates are made to the WireGuard source configurations, only the corresponding elements in the output will be altered. This ensures that configurations from a VPN provider can be batch-converted without generating unnecessary files or inducing unexpected behavioral changes.Keyfiles for both private and symmetric keys are named according to the public key of the relevant interface or peer. These keyfiles are encoded in base32 rather than base64 to avoid issues with the Unix path separator present in base64 encoding. The public key corresponding to a keyfile can be obtained using the following command:
echo $KEY | sed -E 's/\.(priv|sym)key//' | base32 -d | base64
This approach effectively ensures that if two interfaces share the same private key, a single shared keyfile will be generated. The
fwmark
field employs a SipHash of the interface name, enabling the generation of identical network and netdev files across separate program invocations, while minimizing the risk offwmark
collisions.
Compatibility and Limitations
wg2nd
is designed for high compatibility but comes with some caveats:
Dynamic Firewall Installation: Unlike
wg-quick
, which installs a firewall by default when a default route is specified,wg2nd
does not. However, an equivalent firewall can be generated if desired.Pre/Post Interface Setup Scripts:
wg2nd
does not handlePreUp
,PostUp
,PreDown
, andPostDown
script snippets, whichwg-quick
does recognize.FwMark and Table Handling:
wg2nd
uses a deterministic method for generatingfwmark
based on the interface name. This contrasts withwg-quick
, which dynamically checks availability. This deterministic approach is necessary because a static value must be chosen for configuration. However, this could result in a birthday collision if a large number of interfaces are ported. (Such a scenario becomes only remotely probable after porting around 500 interfaces.)
Web Port
The web port has been developed by converting the C
/ C++
implementation into WebAssembly (WASM). It offers an
entirely browser-based experience, converting your WireGuard configurations into a series of Bash commands to configure
the interface. This allows you to experiment within your browser.
The code is dual-licensed under the GPL-2.0 and MIT licenses. Feel free to send me patches via email or submit pull requests through GitHub.
For further details, including installation instructions, please consult the project README.
Happy networking!