wireguard-negotiator/README.md

97 lines
3.3 KiB
Markdown
Raw Permalink Normal View History

2019-12-19 19:48:52 +08:00
2019-12-19 18:03:15 +08:00
# wireguard-negotiator
2019-12-19 19:48:52 +08:00
Not-very-secure manual WireGuard negotiator
2019-12-19 19:48:52 +08:00
## Purpose
`wireguard-negotiator` is built for scenarios where a simple mechanism to exchange and manually accept WireGuard keys is needed. This makes it slightly easier to provision a group of Linux WireGuard peers that peer with a "server".
In summary:
* Set up "client" keys
2019-12-19 19:48:52 +08:00
* Exchange keys over HTTP(S)
2019-12-20 17:41:49 +08:00
* Exchange IP addressing
* Manually gate new "clients"
2019-12-19 20:52:27 +08:00
* Sets up network interface on the "client"
2019-12-19 19:48:52 +08:00
* Generate Ansible INI inventory
2019-12-19 20:52:27 +08:00
The primary scenario this tool is going to be used for is to manage machines using Ansible within an unknown LAN behind NAT. I am planning to use it for FOSSASIA Summit 2020.
2019-12-19 19:48:52 +08:00
## Limitations
* Linux-only
* Relies on the `wg` and `systemctl` commands
* Server manages existing config files only
2019-12-19 19:48:52 +08:00
* Removing peers is a manual process
# Usage
2019-12-20 17:41:49 +08:00
## Server
The "server" manages a WireGuard interface, treating a WireGuard configuration file as a database. It assumes this interface and configuration exists.
2019-12-20 17:41:49 +08:00
2019-12-21 18:50:10 +08:00
```
wireguard-negotiator server --endpoint wireguard-endpoint:port
```
1. On start:
1. Read and apply WireGuard configuration file if `--apply-on-start` is set (Equivalent to wg setconf)
2. Read from interface PublicKey and ListenPort
3. Read from interface all IPNets
2. On request:
1. Check if PublicKey is already configured in a Peer or pending
2. Assign first/random available IP for every interface IPNet
1. Unavailable is any existing interface IPNets, Peer AllowedIPs and pending IPs
3. Gate requests
4. Switch rejected
1. If rejected, remove from pending
5. Apply Config with ReplacePeers false and new Peer
6. Save Device into WireGuard configuration file (Almost equivalent to wg showconf)
7. Return PeerConfigResponse
It can generate an Ansible inventory on the same system. This reads off the same WireGuard configuration file as a database.
```
wireguard-negotiator ansible-inventory --group test > inventory
```
The "server" exposes the HTTP server with the following endpoints:
2019-12-20 17:41:49 +08:00
### `POST /request`
Request for the assignment of an IP address and accepted as a peer. This blocks until the server has finished configuring the peer.
2019-12-20 17:41:49 +08:00
#### Request Body
Content-Type: application/x-www-form-urlencoded
| Name | Description | Required |
|------|-------------|----------|
| PublicKey | The public key of the "client" peer | X |
#### Response Body
Content-Type: application/json
| Name | Type | Description |
|------|------|-------------|
| PublicKey | String | Base64 encoded public key of the "server" peer |
| Endpoint | String | The endpoint of the "server" peer |
| PersistentKeepaliveInterval | Number | Suggests a PersistentKeepaliveInterval |
| AllowedIPs | []String | List of allowed IP addresses in CIDR notation |
| InterfaceIPs | []String | List of IP addresses assigned to the "client" interface |
## Client
The "client" sets up a WireGuard interface, and relies on network backends to do so. *It should not be run more than once*. The following network backends are supported:
- (Not implemented) `none`: Creates an interface and WireGuard configuration file
- `networkd`: Creates a `systemd.netdev` and `systemd.network` file in `/etc/systemd/network`
2019-12-20 17:41:49 +08:00
It obtains peer and interface configuration by performing `POST /request` to the "server".
2019-12-21 18:50:10 +08:00
```
wireguard-negotiator request --server https://url-of-server
```