mirror of
https://github.com/tim-beatham/smegmesh.git
synced 2024-12-13 01:50:53 +01:00
141 lines
2.5 KiB
Go
141 lines
2.5 KiB
Go
package wg
|
|
|
|
import (
|
|
"fmt"
|
|
"net"
|
|
"os/exec"
|
|
|
|
crdt "github.com/tim-beatham/wgmesh/pkg/automerge"
|
|
"golang.zx2c4.com/wireguard/wgctrl"
|
|
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
|
)
|
|
|
|
/*
|
|
* All WireGuard mesh interface called wgmesh
|
|
*/
|
|
func CreateInterface(ifName string) error {
|
|
_, err := net.InterfaceByName(ifName)
|
|
|
|
// Check if the interface exists
|
|
if err != nil {
|
|
cmd := exec.Command("/usr/bin/ip", "link", "add", "dev", ifName, "type", "wireguard")
|
|
|
|
if err := cmd.Run(); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
/*
|
|
* Create and configure a new WireGuard client
|
|
*/
|
|
func CreateClient(ifName string) (*wgctrl.Client, error) {
|
|
err := CreateInterface(ifName)
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
client, err := wgctrl.New()
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
wgListenPort := 51820
|
|
privateKey, err := wgtypes.GeneratePrivateKey()
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
var cfg wgtypes.Config = wgtypes.Config{
|
|
PrivateKey: &privateKey,
|
|
ListenPort: &wgListenPort,
|
|
}
|
|
|
|
client.ConfigureDevice(ifName, cfg)
|
|
return client, nil
|
|
}
|
|
|
|
func EnableInterface(ifName string, ip string) error {
|
|
cmd := exec.Command("/usr/bin/ip", "link", "set", "up", "dev", ifName)
|
|
|
|
if err := cmd.Run(); err != nil {
|
|
fmt.Println(err.Error())
|
|
return err
|
|
}
|
|
|
|
hostIp, _, err := net.ParseCIDR(ip)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
cmd = exec.Command("/usr/bin/ip", "addr", "add", hostIp.String()+"/64", "dev", "wgmesh")
|
|
|
|
if err := cmd.Run(); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func convertMeshNode(node crdt.MeshNodeCrdt) (*wgtypes.PeerConfig, error) {
|
|
peerEndpoint, err := net.ResolveUDPAddr("udp", node.WgEndpoint)
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
peerPublic, err := wgtypes.ParseKey(node.PublicKey)
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
allowedIps := make([]net.IPNet, 1)
|
|
_, ipnet, err := net.ParseCIDR(node.WgHost)
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
allowedIps[0] = *ipnet
|
|
|
|
peerConfig := wgtypes.PeerConfig{
|
|
PublicKey: peerPublic,
|
|
Endpoint: peerEndpoint,
|
|
AllowedIPs: allowedIps,
|
|
}
|
|
|
|
return &peerConfig, nil
|
|
}
|
|
|
|
func UpdateWgConf(devName string, nodes map[string]crdt.MeshNodeCrdt, client wgctrl.Client) error {
|
|
peerConfigs := make([]wgtypes.PeerConfig, len(nodes))
|
|
|
|
var count int = 0
|
|
|
|
for _, n := range nodes {
|
|
peer, err := convertMeshNode(n)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
peerConfigs[count] = *peer
|
|
count++
|
|
}
|
|
|
|
cfg := wgtypes.Config{
|
|
Peers: peerConfigs,
|
|
ReplacePeers: true,
|
|
}
|
|
|
|
client.ConfigureDevice(devName, cfg)
|
|
return nil
|
|
}
|