package gowgpkg import ( "fmt" "golang.zx2c4.com/wireguard/wgctrl" "golang.zx2c4.com/wireguard/wgctrl/wgtypes" "github.com/vishvananda/netlink" ) type Device struct { Name string PublicKey string PrivateKey string ListenPort int IP netlink.Addr } func DevicesList() ([]Device, error) { client, err := wgctrl.New() if err != nil { return nil, fmt.Errorf("Can't create wgctrl Client: %w", err) } devices, err := client.Devices() if err != nil { return nil, fmt.Errorf("Can't get list of devices: %w", err) } var devList []Device for _, d := range devices { dev, err := convertToDevice(d) if err != nil { return nil, fmt.Errorf("Cant convert wgtypes device to gowgpkg device: %w", err) } devList = append(devList, dev) } return devList, nil } func DevicesGet(name string) (Device, error) { client, err := wgctrl.New() if err != nil { return Device{}, fmt.Errorf("Can't create wgctrl Client: %w", err) } device, err := client.Device(name) if err != nil { return Device{}, fmt.Errorf("Cant get device: %w", err) } d, err := convertToDevice(device) if err != nil { return Device{}, err } return d, nil } func DevicesCreate(name string, ip netlink.Addr, privateKey string, listenPort int) (error) { // Create IP Device la := netlink.NewLinkAttrs() la.Name = name wgDev := &netlink.GenericLink{ LinkAttrs: la, LinkType: "wireguard", } err := netlink.LinkAdd(wgDev) if err != nil { return fmt.Errorf("Cant create Link to Device: %w", err) } err = netlink.AddrAdd(wgDev, &ip) if err != nil { return fmt.Errorf("Cant add ip to device: %w", err) } privkey, err := wgtypes.ParseKey(privateKey) if err != nil { return fmt.Errorf("Cant parse private key: %w", err) } config := wgtypes.Config{ PrivateKey: &privkey, ListenPort: &listenPort, FirewallMark: nil, ReplacePeers: false, Peers: nil, } client, err := wgctrl.New() if err != nil { return fmt.Errorf("Cant create wireguard client: %w", err) } client.ConfigureDevice(name, config) err = netlink.LinkSetUp(wgDev) if err != nil { return fmt.Errorf("Cant start device: %w", err) } return nil } func DeviceDelete(name string) (error) { la := netlink.NewLinkAttrs() la.Name = name dev := &netlink.GenericLink{ LinkAttrs: la, LinkType: "wireguard", } err := netlink.LinkDel(dev) if err != nil { return fmt.Errorf("Cant delete Device: %w", err) } return nil } func convertToDevice(device *wgtypes.Device) (Device, error) { d := Device{} o, err := netlink.LinkByName(device.Name) if err != nil { return Device{}, fmt.Errorf("Cant get device: %w", err) } ips, err := netlink.AddrList(o, 0) if err != nil { return Device{}, fmt.Errorf("Cant get ip: %w", err) } d.Name = device.Name d.PublicKey = device.PublicKey.String() d.PrivateKey = device.PrivateKey.String() d.ListenPort = device.ListenPort d.IP = ips[0] return d, nil }