2023-09-19 14:45:49 +02:00
|
|
|
package wg
|
|
|
|
|
|
|
|
import (
|
2023-11-01 11:39:46 +01:00
|
|
|
"errors"
|
2023-10-28 17:38:25 +02:00
|
|
|
"fmt"
|
2023-09-19 14:45:49 +02:00
|
|
|
"net"
|
|
|
|
"os/exec"
|
|
|
|
|
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"
|
|
|
|
)
|
|
|
|
|
2023-10-28 17:38:25 +02:00
|
|
|
// createInterface uses ip link to create an interface. If the interface exists
|
|
|
|
// it returns an error
|
|
|
|
func createInterface(ifName string) error {
|
2023-09-19 14:45:49 +02:00
|
|
|
_, err := net.InterfaceByName(ifName)
|
|
|
|
|
2023-10-28 17:38:25 +02:00
|
|
|
if err == nil {
|
2023-11-01 12:58:10 +01:00
|
|
|
err = flushInterface(ifName)
|
|
|
|
return err
|
2023-10-28 17:38:25 +02:00
|
|
|
}
|
|
|
|
|
2023-09-19 14:45:49 +02:00
|
|
|
// Check if the interface exists
|
2023-10-28 17:38:25 +02:00
|
|
|
cmd := exec.Command("/usr/bin/ip", "link", "add", "dev", ifName, "type", "wireguard")
|
2023-09-19 14:45:49 +02:00
|
|
|
|
2023-10-28 17:38:25 +02:00
|
|
|
if err := cmd.Run(); err != nil {
|
|
|
|
return err
|
2023-09-19 14:45:49 +02:00
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2023-10-28 17:38:25 +02:00
|
|
|
type WgInterfaceManipulatorImpl struct {
|
|
|
|
client *wgctrl.Client
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m *WgInterfaceManipulatorImpl) CreateInterface(params *CreateInterfaceParams) error {
|
|
|
|
err := createInterface(params.IfName)
|
2023-09-19 14:45:49 +02:00
|
|
|
|
|
|
|
if err != nil {
|
2023-10-24 17:00:46 +02:00
|
|
|
return err
|
2023-09-19 14:45:49 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
privateKey, err := wgtypes.GeneratePrivateKey()
|
|
|
|
|
|
|
|
if err != nil {
|
2023-10-24 17:00:46 +02:00
|
|
|
return err
|
2023-09-19 14:45:49 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
var cfg wgtypes.Config = wgtypes.Config{
|
|
|
|
PrivateKey: &privateKey,
|
2023-10-28 17:38:25 +02:00
|
|
|
ListenPort: ¶ms.Port,
|
2023-09-19 14:45:49 +02:00
|
|
|
}
|
|
|
|
|
2023-10-28 17:38:25 +02:00
|
|
|
m.client.ConfigureDevice(params.IfName, cfg)
|
2023-10-24 17:00:46 +02:00
|
|
|
return nil
|
2023-09-19 14:45:49 +02:00
|
|
|
}
|
2023-09-21 19:43:29 +02:00
|
|
|
|
2023-10-28 17:38:25 +02:00
|
|
|
// flushInterface flushes the specified interface
|
|
|
|
func flushInterface(ifName string) error {
|
|
|
|
_, err := net.InterfaceByName(ifName)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return &WgError{msg: fmt.Sprintf("Interface %s does not exist cannot flush", ifName)}
|
|
|
|
}
|
|
|
|
|
|
|
|
cmd := exec.Command("/usr/bin/ip", "addr", "flush", "dev", ifName)
|
2023-09-21 19:43:29 +02:00
|
|
|
|
|
|
|
if err := cmd.Run(); err != nil {
|
2023-10-28 17:38:25 +02:00
|
|
|
logging.Log.WriteErrorf(fmt.Sprintf("%s error flushing interface %s", err.Error(), ifName))
|
|
|
|
return &WgError{msg: fmt.Sprintf("Failed to flush interface %s", ifName)}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// EnableInterface flushes the interface and sets the ip address of the
|
|
|
|
// interface
|
|
|
|
func (m *WgInterfaceManipulatorImpl) EnableInterface(ifName string, ip string) error {
|
2023-11-01 11:39:46 +01:00
|
|
|
if len(ifName) == 0 {
|
|
|
|
return errors.New("ifName not provided")
|
|
|
|
}
|
|
|
|
|
2023-10-28 17:38:25 +02:00
|
|
|
err := flushInterface(ifName)
|
|
|
|
|
|
|
|
if err != nil {
|
2023-09-21 19:43:29 +02:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2023-11-01 11:39:46 +01:00
|
|
|
cmd := exec.Command("/usr/bin/ip", "link", "set", "up", "dev", ifName)
|
|
|
|
|
|
|
|
if err := cmd.Run(); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2023-09-21 19:43:29 +02:00
|
|
|
hostIp, _, err := net.ParseCIDR(ip)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2023-11-01 11:39:46 +01:00
|
|
|
cmd = exec.Command("/usr/bin/ip", "addr", "add", hostIp.String()+"/64", "dev", ifName)
|
2023-09-21 19:43:29 +02:00
|
|
|
|
|
|
|
if err := cmd.Run(); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
2023-10-28 17:38:25 +02:00
|
|
|
|
|
|
|
func NewWgInterfaceManipulator(client *wgctrl.Client) WgInterfaceManipulator {
|
|
|
|
return &WgInterfaceManipulatorImpl{client: client}
|
|
|
|
}
|