aboutsummaryrefslogtreecommitdiff
path: root/posts/announcing-wg2nd/main.md
blob: fc51748d5108ec2ba7f3e5c6a92bceeeffaaad70 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# 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.

- [wg2nd](https://www.git.flu0r1ne.net/wg2nd) - Source Code
- [wg2nd-web](/wg2nd) - Web Port (contains some limitations)

## 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

1. **Compatibility**: `wg2nd` supports all `wg-quick` configurations except those that involve
    `PreUp`, `PostUp`, `PreDown`, and `PostDown` scripts, which are omitted.

2. **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.

3. **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:

    ```bash
    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 of `fwmark` collisions.

### Compatibility and Limitations

`wg2nd` is designed for high compatibility but comes with some caveats:

1. **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.

2. **Pre/Post Interface Setup Scripts**: `wg2nd` does not handle `PreUp`, `PostUp`, `PreDown`, and `PostDown`
   script snippets, which `wg-quick` does recognize.

3. **FwMark and Table Handling**: `wg2nd` uses a deterministic method for generating `fwmark` based on the interface
   name. This contrasts with `wg-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](https://www.git.flu0r1ne.net/wg2nd/tree/README.md?h=main).

Happy networking!