wg-portal/internal/wireguard/manager.go

123 lines
2.6 KiB
Go
Raw Normal View History

2020-11-05 13:37:51 -05:00
package wireguard
import (
"sync"
2021-02-26 16:17:04 -05:00
"github.com/pkg/errors"
2020-11-05 13:37:51 -05:00
"golang.zx2c4.com/wireguard/wgctrl"
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
)
// Manager offers a synchronized management interface to the real WireGuard interface.
2020-11-05 13:37:51 -05:00
type Manager struct {
Cfg *Config
wg *wgctrl.Client
mux sync.RWMutex
}
func (m *Manager) Init() error {
var err error
m.wg, err = wgctrl.New()
if err != nil {
2021-02-26 16:17:04 -05:00
return errors.Wrap(err, "could not create WireGuard client")
2020-11-05 13:37:51 -05:00
}
return nil
}
func (m *Manager) GetDeviceInfo(device string) (*wgtypes.Device, error) {
dev, err := m.wg.Device(device)
2020-11-05 13:37:51 -05:00
if err != nil {
2021-02-26 16:17:04 -05:00
return nil, errors.Wrap(err, "could not get WireGuard device")
2020-11-05 13:37:51 -05:00
}
return dev, nil
}
func (m *Manager) GetPeerList(device string) ([]wgtypes.Peer, error) {
2020-11-05 13:37:51 -05:00
m.mux.RLock()
defer m.mux.RUnlock()
dev, err := m.wg.Device(device)
2020-11-05 13:37:51 -05:00
if err != nil {
2021-02-26 16:17:04 -05:00
return nil, errors.Wrap(err, "could not get WireGuard device")
2020-11-05 13:37:51 -05:00
}
return dev.Peers, nil
}
func (m *Manager) GetPeer(device string, pubKey string) (*wgtypes.Peer, error) {
2020-11-05 13:37:51 -05:00
m.mux.RLock()
defer m.mux.RUnlock()
publicKey, err := wgtypes.ParseKey(pubKey)
if err != nil {
2021-02-26 16:17:04 -05:00
return nil, errors.Wrap(err, "invalid public key")
2020-11-05 13:37:51 -05:00
}
peers, err := m.GetPeerList(device)
2020-11-05 13:37:51 -05:00
if err != nil {
2021-02-26 16:17:04 -05:00
return nil, errors.Wrap(err, "could not get WireGuard peers")
2020-11-05 13:37:51 -05:00
}
for _, peer := range peers {
if peer.PublicKey == publicKey {
return &peer, nil
}
}
2021-02-26 16:17:04 -05:00
return nil, errors.Errorf("could not find WireGuard peer: %s", pubKey)
2020-11-05 13:37:51 -05:00
}
func (m *Manager) AddPeer(device string, cfg wgtypes.PeerConfig) error {
2020-11-05 13:37:51 -05:00
m.mux.Lock()
defer m.mux.Unlock()
err := m.wg.ConfigureDevice(device, wgtypes.Config{Peers: []wgtypes.PeerConfig{cfg}})
2020-11-05 13:37:51 -05:00
if err != nil {
2021-02-26 16:17:04 -05:00
return errors.Wrap(err, "could not configure WireGuard device")
2020-11-05 13:37:51 -05:00
}
return nil
}
func (m *Manager) UpdatePeer(device string, cfg wgtypes.PeerConfig) error {
2020-11-07 04:31:48 -05:00
m.mux.Lock()
defer m.mux.Unlock()
cfg.UpdateOnly = true
err := m.wg.ConfigureDevice(device, wgtypes.Config{Peers: []wgtypes.PeerConfig{cfg}})
2020-11-07 04:31:48 -05:00
if err != nil {
2021-02-26 16:17:04 -05:00
return errors.Wrap(err, "could not configure WireGuard device")
2020-11-07 04:31:48 -05:00
}
return nil
}
func (m *Manager) RemovePeer(device string, pubKey string) error {
2020-11-05 13:37:51 -05:00
m.mux.Lock()
defer m.mux.Unlock()
publicKey, err := wgtypes.ParseKey(pubKey)
if err != nil {
2021-02-26 16:17:04 -05:00
return errors.Wrap(err, "invalid public key")
2020-11-05 13:37:51 -05:00
}
peer := wgtypes.PeerConfig{
PublicKey: publicKey,
Remove: true,
}
err = m.wg.ConfigureDevice(device, wgtypes.Config{Peers: []wgtypes.PeerConfig{peer}})
2020-11-05 13:37:51 -05:00
if err != nil {
2021-02-26 16:17:04 -05:00
return errors.Wrap(err, "could not configure WireGuard device")
2020-11-05 13:37:51 -05:00
}
return nil
}
2020-11-07 04:31:48 -05:00
func (m *Manager) UpdateDevice(device string, cfg wgtypes.Config) error {
return m.wg.ConfigureDevice(device, cfg)
2020-11-07 04:31:48 -05:00
}