Gomesh

I needed to use implement a Mesh VPN for a project and I like Wireguard but somehow compiling all the necessary config files (for something like 20 or more members of the mesh) by hand was something that did not appeal to me.

After some searching around (GIYF) I found a project that seems to solve my issues wg-meshconf but that was a Python implementation and I didn’t wanted to have that kind of dependency. Since space is cheap these days I was willing to have a bigger executable if that meant not having Python so I started a new project implementing a Wireguard Mesh VPN configuration generator in Go. The idea was to have a “database” containing all the required information about the members with possibility to add and delete members and a command to generate the configuration files.

I used Cobra one of the best frameworks available to build Go CLI applications. As the “database” a simple JSON file is sufficient and there you go. One of the challenges was managing the keys used by wireguard which are in fact 32 random bytes massaged according to https://cr.yp.to/ecdh.html and converted to a string. I opted to use the Wireguard implementation instead of sporting my own although in the future that might change. This is how it looks now:

import (
	"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
    )

// GenerateKey will return a base64 encoded string
// suitable for using as a Wireguyard PrivateKey
func GenerateKey() (string, error) {
    privatekey, err := wgtypes.GeneratePrivateKey()
    if err != nil {
        return "", err
    }
    privkeystring := privatekey.String()
    return privkeystring, nil
}

And without depending on wireguard it could look like:

import (
    "crypto/rand"
    "encoding/base64"
    )


// GeneratePrivateKey generates a Key
func GeneratePrivateKey() (string, error) {

    key := make([]byte, 32)
    if _, err := rand.Read(b); err != nil {
        return "", err
    }

    // Modify random bytes using algorithm described at:
    // https://cr.yp.to/ecdh.html.
    key[0] &= 248
    key[31] &= 127
    key[31] |= 64


    return base64.StdEncoding.EncodeToString(key[:]), nil
}

Having an own implementation of the key algorithm will drop the dependency on the wireguard import but will add a dependency on golang.org/x/crypto/curve25519 since we will need that in order to compute the Wireguard PublicKey from the PrivateKey. So dependency wise is not really a gain, what would be interesting though is to implement the more secure algorithm that generates a PrivateKey from 128 bytes instead of 32. But that is left for a maybe future implementation. Until then cheers and visit Gomesh to check for a new release.