smegmesh/pkg/wg/wg.go

94 lines
2.0 KiB
Go
Raw Normal View History

2023-09-19 14:45:49 +02:00
package wg
import (
"crypto"
"crypto/rand"
"fmt"
2023-09-19 14:45:49 +02:00
"github.com/tim-beatham/wgmesh/pkg/lib"
2023-10-06 12:52:51 +02:00
logging "github.com/tim-beatham/wgmesh/pkg/log"
2023-09-19 14:45:49 +02:00
"golang.zx2c4.com/wireguard/wgctrl"
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
)
type WgInterfaceManipulatorImpl struct {
client *wgctrl.Client
}
const hashLength = 6
// CreateInterface creates a WireGuard interface
func (m *WgInterfaceManipulatorImpl) CreateInterface(port int, privKey *wgtypes.Key) (string, error) {
rtnl, err := lib.NewRtNetlinkConfig()
if err != nil {
return "", fmt.Errorf("failed to access link: %w", err)
}
defer rtnl.Close()
randomBuf := make([]byte, 32)
_, err = rand.Read(randomBuf)
if err != nil {
return "", err
}
md5 := crypto.MD5.New().Sum(randomBuf)
md5Str := fmt.Sprintf("wg%x", md5)[:hashLength]
err = rtnl.CreateLink(md5Str)
2023-09-19 14:45:49 +02:00
if err != nil {
return "", fmt.Errorf("failed to create link: %w", err)
2023-09-19 14:45:49 +02:00
}
var cfg wgtypes.Config = wgtypes.Config{
PrivateKey: privKey,
ListenPort: &port,
2023-09-19 14:45:49 +02:00
}
err = m.client.ConfigureDevice(md5Str, cfg)
if err != nil {
m.RemoveInterface(md5Str)
return "", fmt.Errorf("failed to configure dev: %w", err)
}
logging.Log.WriteInfof("ip link set up dev %s type wireguard", md5Str)
return md5Str, nil
}
// Add an address to the given interface
func (m *WgInterfaceManipulatorImpl) AddAddress(ifName string, addr string) error {
rtnl, err := lib.NewRtNetlinkConfig()
if err != nil {
return fmt.Errorf("failed to create config: %w", err)
2023-09-21 19:43:29 +02:00
}
defer rtnl.Close()
2023-09-21 19:43:29 +02:00
err = rtnl.AddAddress(ifName, addr)
if err != nil {
err = fmt.Errorf("failed to add address: %w", err)
}
return err
}
// RemoveInterface implements WgInterfaceManipulator.
func (*WgInterfaceManipulatorImpl) RemoveInterface(ifName string) error {
rtnl, err := lib.NewRtNetlinkConfig()
2023-09-21 19:43:29 +02:00
if err != nil {
return fmt.Errorf("failed to create config: %w", err)
2023-09-21 19:43:29 +02:00
}
defer rtnl.Close()
2023-09-21 19:43:29 +02:00
return rtnl.DeleteLink(ifName)
2023-09-21 19:43:29 +02:00
}
func NewWgInterfaceManipulator(client *wgctrl.Client) WgInterfaceManipulator {
return &WgInterfaceManipulatorImpl{client: client}
}