smegmesh/pkg/wg/wg.go

141 lines
2.5 KiB
Go
Raw Normal View History

2023-09-19 14:45:49 +02:00
package wg
import (
"fmt"
"net"
"os/exec"
2023-10-05 18:48:54 +02:00
crdt "github.com/tim-beatham/wgmesh/pkg/automerge"
2023-09-19 14:45:49 +02:00
"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
}
2023-09-20 00:50:44 +02:00
wgListenPort := 51820
2023-09-19 14:45:49 +02:00
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
}
2023-09-21 19:43:29 +02:00
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
}
2023-09-28 17:55:37 +02:00
cmd = exec.Command("/usr/bin/ip", "addr", "add", hostIp.String()+"/64", "dev", "wgmesh")
2023-09-21 19:43:29 +02:00
if err := cmd.Run(); err != nil {
return err
}
return nil
}
2023-10-05 18:48:54 +02:00
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
}