Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wgctrl: add a high-level configuration interface #41

Open
mdlayher opened this issue May 13, 2019 · 6 comments
Open

wgctrl: add a high-level configuration interface #41

mdlayher opened this issue May 13, 2019 · 6 comments
Labels
question Further information is requested

Comments

@mdlayher
Copy link
Member

The current interface only implements the raw configuration parameters expected by WireGuard devices, but it could be nice to implement some kind of higher level interface to ease configuration for end users.

Perhaps a transactional interface would be nice (named and exact operations TBD):

m, err := wgctrl.NewManager()

err := m.Apply("wg0", func(tx *wgctrl.Transaction) error {
    tx.SetPrivateKey(wgtypes.GeneratePrivateKey()),
    tx.ClearPeers()
    tx.AddPeer(peer)
    
    return tx.Commit()
})
@the-maldridge
Copy link

the-maldridge commented May 20, 2019

here's an example of what I've currently got to configure an interface. Its quite messy and misses certain configuration values, but my use case is just managing keys and addresses. It also is quite messy in terms of time complexity making multiple passes to figure out what to change.

https://github.com/the-maldridge/locksmith/blob/wg-driver/internal/keyhole/util.go#L20

Easily the most annoying part of this is trying to diff out the addresses, which at the time of this comment remains un-implemented. The goal though is to be idempotent in applying desired intent, rather than specifying individual deltas.

EDIT: I realized that checking the addresses wasn't complex, just annoying, so my implementation does that now too.

@mdlayher
Copy link
Member Author

It would seem to me that perhaps it makes sense to expose a couple of APIs here that can be composed with the existing c.ConfigureDevice() method.

package wgctrl

// Converge calculates *wgtypes.Config which applies only the changes needed to update a
// device from the current device configuration to the desired configuration.
func Converge(current *wgtypes.Device, desired *wgtypes.Config) (*wgtypes.Config, error) {}

// A Change is a function which expresses a high level WireGuard device operation, such as
// adding or removing an individual peer.
type Change func(current *wgtypes.Config) (*wgtypes.Config, error)

// Apply produces a *wgtypes.Config expressed via a several of higher level operations, such
// as adding or removing individual peers.
func Apply(changes []Change) (*wgtypes.Config, error) {}

Then, I could envision something like (pseudo-code of course):

c, _ := wgctrl.New()

d, _ := c.Device("wg0")

addPeer, _ := wgctrl.Apply(
    // Maybe it makes more sense to express convergence this way?
    // wgctrl.Initial(d),
    wgctrl.ClearPeers(),
    wgctrl.AddPeer(pubkey, []net.IPNet{"2001:db8::/32"}),
)

conf, _ := wgctrl.Converge(d, addPeer)

_ = c.ConfigureDevice(d.Name, conf)

@mdlayher mdlayher added the question Further information is requested label Oct 28, 2019
@JordanDeBeer
Copy link

I have a workload that could use a declarative interface. I could look at implementing it here instead of "client-side" if this sort of functionality is desired.

@the-maldridge
Copy link

@JordanDeBeer I think that would be a good idea. I would be happy to collaborate here and try to move my implementation here as well. That way there would be one implementation rather than us each having our own in our separate projects.

@stv0g
Copy link
Contributor

stv0g commented Feb 8, 2022

I have implemented (de-)serialization of wg/wg-quick configuration files to/from wgtypes.Config here: https://github.com/stv0g/wice/blob/master/internal/wg/device_config.go

I would be willing to contribute this to wgctrl as well.

@SLoeuillet
Copy link

SLoeuillet commented Dec 1, 2023

If someone is interrested, there is wgrest which uses wgctrl-go code and exposes a REST API to configure wireguard : https://github.com/suquant/wgrest

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

5 participants