diff --git a/README.md b/README.md index e63a0db..599b8a1 100644 --- a/README.md +++ b/README.md @@ -29,12 +29,27 @@ The primary scenario this tool is going to be used for is to manage machines usi ## Server -The "server" manages a WireGuard interface, ~~treating a WireGuard configuration file as a database~~ (TODO). It assumes this interface and configuration exists. It only adds new peers to the configuration file and interface, and does not delete existing configuration. +The "server" manages a WireGuard interface, treating a WireGuard configuration file as a database. It assumes this interface and configuration exists. ``` 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. ``` @@ -45,7 +60,7 @@ The "server" exposes the HTTP server with the following endpoints: ### `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, therefore the client SHOULD NOT timeout. +Request for the assignment of an IP address and accepted as a peer. This blocks until the server has finished configuring the peer. #### Request Body diff --git a/cmd/server.go b/cmd/server.go index 930db66..1af5126 100644 --- a/cmd/server.go +++ b/cmd/server.go @@ -35,7 +35,7 @@ var CmdServer = &cli.Command{ Aliases: []string{"c"}, Value: "", DefaultText: "/etc/wireguard/.conf", - Usage: "Path to the existing WireGuard configuration file", + Usage: "Path to the existing WireGuard configuration file. WARNING: wireguard-negotiator will remove any comments in the file", }, &cli.StringFlag{ Name: "endpoint", diff --git a/go.mod b/go.mod index e730cf4..0d0756c 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module github.com/serverwentdown/wireguard-negotiator go 1.13 require ( + github.com/google/go-cmp v0.3.1 github.com/urfave/cli/v2 v2.0.0 golang.zx2c4.com/wireguard/wgctrl v0.0.0-20191219145116-fa6499c8e75f gopkg.in/ini.v1 v1.51.0 diff --git a/go.sum b/go.sum index b217b8a..4ca0c86 100644 --- a/go.sum +++ b/go.sum @@ -2,6 +2,7 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/jsimonetti/rtnetlink v0.0.0-20190606172950-9527aa82566a/go.mod h1:Oz+70psSo5OFh8DBl0Zv2ACw7Esh6pPUphlvZG9x7uw= github.com/mdlayher/genetlink v0.0.0-20191205172946-651acf4b47ef/go.mod h1:0rJ0h4itni50A86M2kHcgS85ttZazNt7a8H2a2cw0Gc= diff --git a/lib/wgconfig.go b/lib/wgconfig.go index 182083e..8f2b0f3 100644 --- a/lib/wgconfig.go +++ b/lib/wgconfig.go @@ -1,7 +1,14 @@ package lib import ( -//"golang.zx2c4.com/wireguard/wgctrl/wgtypes" + "io" + + "golang.zx2c4.com/wireguard/wgctrl/wgtypes" ) // ReadConfig is yet another INI-like configuration file parser, but for WireGuard +func ReadConfig(r io.Reader) (wgtypes.Config, error) { + tmp := make([]byte, 1000) + r.Read(tmp) + return wgtypes.Config{}, nil +} diff --git a/lib/wgconfig_test.go b/lib/wgconfig_test.go index ea0869f..d5e4c93 100644 --- a/lib/wgconfig_test.go +++ b/lib/wgconfig_test.go @@ -1,8 +1,14 @@ package lib -import "testing" +import ( + "strings" + "testing" -var testGoodConfiguration1 = ` + "github.com/google/go-cmp/cmp" + "golang.zx2c4.com/wireguard/wgctrl/wgtypes" +) + +const testGoodConfig1 = ` # Test = Example comment [Interface] @@ -18,6 +24,15 @@ AllowedIPs = 192.168.10.40/32, 2001:470:ed5d:a::28/128 PublicKey = wXU+vSTdEoIwSi+Tmv35SCOFg17wCAwnmYxeQPpbzDg= ` -func TestReadConfig(t *testing.T) { +var testGoodConfig1Want = wgtypes.Config{} +func TestReadConfig1(t *testing.T) { + buf := strings.NewReader(testGoodConfig1) + got, err := ReadConfig(buf) + if err != nil { + t.Fatalf("config read failed: %w", err) + } + if diff := cmp.Diff(testGoodConfig1Want, got); diff != "" { + t.Fatalf("returned config is not what is wanted: \n%s", diff) + } }