netbird/iface/configuration.go

259 lines
6.3 KiB
Go
Raw Normal View History

Refactor Interface package and update windows driver (#192) * script to generate syso files * test wireguard-windows driver package * set int log * add windows test * add windows test * verbose bash * use cd * move checkout * exit 0 * removed tty flag * artifact path * fix tags and add cache * fix cache * fix cache * test dir * restore artifacts in the root * try dll file * try dll file * copy dll * typo in copy dll * compile test * checkout first * updated cicd * fix add address issue and gen GUID * psexec typo * accept eula * mod tidy before tests * regular test exec and verbose test with psexec * test all * return WGInterface Interface * use WgIfaceName and timeout after 30 seconds * different ports and validate connect 2 peers * Use time.After for timeout and close interface * Use time.After for testing connect peers * WG Interface struct * Update engine and parse address * refactor Linux create and assignAddress * NewWGIface and configuration methods * Update proxy with interface methods * update up command test * resolve lint warnings * remove psexec test * close copied files * add goos before build * run tests on mac,windows and linux * cache by testing os * run on push * fix indentation * adjust test timeouts * remove parallel flag * mod tidy before test * ignore syso files * removed functions and renamed vars * different IPs for connect peers test * Generate syso with DLL * Single Close method * use port from test constant * test: remove wireguard interfaces after finishing engine test * use load_wgnt_from_rsrc Co-authored-by: braginini <bangvalo@gmail.com>
2022-01-17 14:01:58 +01:00
package iface
import (
"fmt"
Refactor Interface package and update windows driver (#192) * script to generate syso files * test wireguard-windows driver package * set int log * add windows test * add windows test * verbose bash * use cd * move checkout * exit 0 * removed tty flag * artifact path * fix tags and add cache * fix cache * fix cache * test dir * restore artifacts in the root * try dll file * try dll file * copy dll * typo in copy dll * compile test * checkout first * updated cicd * fix add address issue and gen GUID * psexec typo * accept eula * mod tidy before tests * regular test exec and verbose test with psexec * test all * return WGInterface Interface * use WgIfaceName and timeout after 30 seconds * different ports and validate connect 2 peers * Use time.After for timeout and close interface * Use time.After for testing connect peers * WG Interface struct * Update engine and parse address * refactor Linux create and assignAddress * NewWGIface and configuration methods * Update proxy with interface methods * update up command test * resolve lint warnings * remove psexec test * close copied files * add goos before build * run tests on mac,windows and linux * cache by testing os * run on push * fix indentation * adjust test timeouts * remove parallel flag * mod tidy before test * ignore syso files * removed functions and renamed vars * different IPs for connect peers test * Generate syso with DLL * Single Close method * use port from test constant * test: remove wireguard interfaces after finishing engine test * use load_wgnt_from_rsrc Co-authored-by: braginini <bangvalo@gmail.com>
2022-01-17 14:01:58 +01:00
log "github.com/sirupsen/logrus"
"golang.zx2c4.com/wireguard/wgctrl"
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
"net"
"time"
)
// GetName returns the interface name
func (w *WGIface) GetName() string {
return w.Name
}
// GetAddress returns the interface address
func (w *WGIface) GetAddress() WGAddress {
return w.Address
}
Refactor Interface package and update windows driver (#192) * script to generate syso files * test wireguard-windows driver package * set int log * add windows test * add windows test * verbose bash * use cd * move checkout * exit 0 * removed tty flag * artifact path * fix tags and add cache * fix cache * fix cache * test dir * restore artifacts in the root * try dll file * try dll file * copy dll * typo in copy dll * compile test * checkout first * updated cicd * fix add address issue and gen GUID * psexec typo * accept eula * mod tidy before tests * regular test exec and verbose test with psexec * test all * return WGInterface Interface * use WgIfaceName and timeout after 30 seconds * different ports and validate connect 2 peers * Use time.After for timeout and close interface * Use time.After for testing connect peers * WG Interface struct * Update engine and parse address * refactor Linux create and assignAddress * NewWGIface and configuration methods * Update proxy with interface methods * update up command test * resolve lint warnings * remove psexec test * close copied files * add goos before build * run tests on mac,windows and linux * cache by testing os * run on push * fix indentation * adjust test timeouts * remove parallel flag * mod tidy before test * ignore syso files * removed functions and renamed vars * different IPs for connect peers test * Generate syso with DLL * Single Close method * use port from test constant * test: remove wireguard interfaces after finishing engine test * use load_wgnt_from_rsrc Co-authored-by: braginini <bangvalo@gmail.com>
2022-01-17 14:01:58 +01:00
// configureDevice configures the wireguard device
func (w *WGIface) configureDevice(config wgtypes.Config) error {
wg, err := wgctrl.New()
if err != nil {
return err
}
defer wg.Close()
// validate if device with name exists
_, err = wg.Device(w.Name)
if err != nil {
return err
}
log.Debugf("got Wireguard device %s", w.Name)
return wg.ConfigureDevice(w.Name, config)
}
// Configure configures a Wireguard interface
// The interface must exist before calling this method (e.g. call interface.Create() before)
func (w *WGIface) Configure(privateKey string, port int) error {
w.mu.Lock()
defer w.mu.Unlock()
Refactor Interface package and update windows driver (#192) * script to generate syso files * test wireguard-windows driver package * set int log * add windows test * add windows test * verbose bash * use cd * move checkout * exit 0 * removed tty flag * artifact path * fix tags and add cache * fix cache * fix cache * test dir * restore artifacts in the root * try dll file * try dll file * copy dll * typo in copy dll * compile test * checkout first * updated cicd * fix add address issue and gen GUID * psexec typo * accept eula * mod tidy before tests * regular test exec and verbose test with psexec * test all * return WGInterface Interface * use WgIfaceName and timeout after 30 seconds * different ports and validate connect 2 peers * Use time.After for timeout and close interface * Use time.After for testing connect peers * WG Interface struct * Update engine and parse address * refactor Linux create and assignAddress * NewWGIface and configuration methods * Update proxy with interface methods * update up command test * resolve lint warnings * remove psexec test * close copied files * add goos before build * run tests on mac,windows and linux * cache by testing os * run on push * fix indentation * adjust test timeouts * remove parallel flag * mod tidy before test * ignore syso files * removed functions and renamed vars * different IPs for connect peers test * Generate syso with DLL * Single Close method * use port from test constant * test: remove wireguard interfaces after finishing engine test * use load_wgnt_from_rsrc Co-authored-by: braginini <bangvalo@gmail.com>
2022-01-17 14:01:58 +01:00
log.Debugf("configuring Wireguard interface %s", w.Name)
log.Debugf("adding Wireguard private key")
key, err := wgtypes.ParseKey(privateKey)
if err != nil {
return err
}
fwmark := 0
config := wgtypes.Config{
PrivateKey: &key,
ReplacePeers: true,
FirewallMark: &fwmark,
ListenPort: &port,
}
err = w.configureDevice(config)
if err != nil {
return fmt.Errorf("received error \"%v\" while configuring interface %s with port %d", err, w.Name, port)
}
return nil
Refactor Interface package and update windows driver (#192) * script to generate syso files * test wireguard-windows driver package * set int log * add windows test * add windows test * verbose bash * use cd * move checkout * exit 0 * removed tty flag * artifact path * fix tags and add cache * fix cache * fix cache * test dir * restore artifacts in the root * try dll file * try dll file * copy dll * typo in copy dll * compile test * checkout first * updated cicd * fix add address issue and gen GUID * psexec typo * accept eula * mod tidy before tests * regular test exec and verbose test with psexec * test all * return WGInterface Interface * use WgIfaceName and timeout after 30 seconds * different ports and validate connect 2 peers * Use time.After for timeout and close interface * Use time.After for testing connect peers * WG Interface struct * Update engine and parse address * refactor Linux create and assignAddress * NewWGIface and configuration methods * Update proxy with interface methods * update up command test * resolve lint warnings * remove psexec test * close copied files * add goos before build * run tests on mac,windows and linux * cache by testing os * run on push * fix indentation * adjust test timeouts * remove parallel flag * mod tidy before test * ignore syso files * removed functions and renamed vars * different IPs for connect peers test * Generate syso with DLL * Single Close method * use port from test constant * test: remove wireguard interfaces after finishing engine test * use load_wgnt_from_rsrc Co-authored-by: braginini <bangvalo@gmail.com>
2022-01-17 14:01:58 +01:00
}
// GetListenPort returns the listening port of the Wireguard endpoint
func (w *WGIface) GetListenPort() (*int, error) {
log.Debugf("getting Wireguard listen port of interface %s", w.Name)
//discover Wireguard current configuration
wg, err := wgctrl.New()
if err != nil {
return nil, err
}
defer wg.Close()
d, err := wg.Device(w.Name)
if err != nil {
return nil, err
}
log.Debugf("got Wireguard device listen port %s, %d", w.Name, d.ListenPort)
return &d.ListenPort, nil
}
// UpdatePeer updates existing Wireguard Peer or creates a new one if doesn't exist
// Endpoint is optional
func (w *WGIface) UpdatePeer(peerKey string, allowedIps string, keepAlive time.Duration, endpoint *net.UDPAddr, preSharedKey *wgtypes.Key) error {
w.mu.Lock()
defer w.mu.Unlock()
Refactor Interface package and update windows driver (#192) * script to generate syso files * test wireguard-windows driver package * set int log * add windows test * add windows test * verbose bash * use cd * move checkout * exit 0 * removed tty flag * artifact path * fix tags and add cache * fix cache * fix cache * test dir * restore artifacts in the root * try dll file * try dll file * copy dll * typo in copy dll * compile test * checkout first * updated cicd * fix add address issue and gen GUID * psexec typo * accept eula * mod tidy before tests * regular test exec and verbose test with psexec * test all * return WGInterface Interface * use WgIfaceName and timeout after 30 seconds * different ports and validate connect 2 peers * Use time.After for timeout and close interface * Use time.After for testing connect peers * WG Interface struct * Update engine and parse address * refactor Linux create and assignAddress * NewWGIface and configuration methods * Update proxy with interface methods * update up command test * resolve lint warnings * remove psexec test * close copied files * add goos before build * run tests on mac,windows and linux * cache by testing os * run on push * fix indentation * adjust test timeouts * remove parallel flag * mod tidy before test * ignore syso files * removed functions and renamed vars * different IPs for connect peers test * Generate syso with DLL * Single Close method * use port from test constant * test: remove wireguard interfaces after finishing engine test * use load_wgnt_from_rsrc Co-authored-by: braginini <bangvalo@gmail.com>
2022-01-17 14:01:58 +01:00
log.Debugf("updating interface %s peer %s: endpoint %s ", w.Name, peerKey, endpoint)
//parse allowed ips
_, ipNet, err := net.ParseCIDR(allowedIps)
if err != nil {
return err
}
peerKeyParsed, err := wgtypes.ParseKey(peerKey)
if err != nil {
return err
}
peer := wgtypes.PeerConfig{
PublicKey: peerKeyParsed,
ReplaceAllowedIPs: true,
AllowedIPs: []net.IPNet{*ipNet},
PersistentKeepaliveInterval: &keepAlive,
PresharedKey: preSharedKey,
Endpoint: endpoint,
}
config := wgtypes.Config{
Peers: []wgtypes.PeerConfig{peer},
}
err = w.configureDevice(config)
if err != nil {
return fmt.Errorf("received error \"%v\" while updating peer on interface %s with settings: allowed ips %s, endpoint %s", err, w.Name, allowedIps, endpoint.String())
}
return nil
Refactor Interface package and update windows driver (#192) * script to generate syso files * test wireguard-windows driver package * set int log * add windows test * add windows test * verbose bash * use cd * move checkout * exit 0 * removed tty flag * artifact path * fix tags and add cache * fix cache * fix cache * test dir * restore artifacts in the root * try dll file * try dll file * copy dll * typo in copy dll * compile test * checkout first * updated cicd * fix add address issue and gen GUID * psexec typo * accept eula * mod tidy before tests * regular test exec and verbose test with psexec * test all * return WGInterface Interface * use WgIfaceName and timeout after 30 seconds * different ports and validate connect 2 peers * Use time.After for timeout and close interface * Use time.After for testing connect peers * WG Interface struct * Update engine and parse address * refactor Linux create and assignAddress * NewWGIface and configuration methods * Update proxy with interface methods * update up command test * resolve lint warnings * remove psexec test * close copied files * add goos before build * run tests on mac,windows and linux * cache by testing os * run on push * fix indentation * adjust test timeouts * remove parallel flag * mod tidy before test * ignore syso files * removed functions and renamed vars * different IPs for connect peers test * Generate syso with DLL * Single Close method * use port from test constant * test: remove wireguard interfaces after finishing engine test * use load_wgnt_from_rsrc Co-authored-by: braginini <bangvalo@gmail.com>
2022-01-17 14:01:58 +01:00
}
// AddAllowedIP adds a prefix to the allowed IPs list of peer
func (w *WGIface) AddAllowedIP(peerKey string, allowedIP string) error {
w.mu.Lock()
defer w.mu.Unlock()
log.Debugf("adding allowed IP to interface %s and peer %s: allowed IP %s ", w.Name, peerKey, allowedIP)
_, ipNet, err := net.ParseCIDR(allowedIP)
if err != nil {
return err
}
peerKeyParsed, err := wgtypes.ParseKey(peerKey)
if err != nil {
return err
}
peer := wgtypes.PeerConfig{
PublicKey: peerKeyParsed,
UpdateOnly: true,
ReplaceAllowedIPs: false,
AllowedIPs: []net.IPNet{*ipNet},
}
config := wgtypes.Config{
Peers: []wgtypes.PeerConfig{peer},
}
err = w.configureDevice(config)
if err != nil {
return fmt.Errorf("received error \"%v\" while adding allowed Ip to peer on interface %s with settings: allowed ips %s", err, w.Name, allowedIP)
}
return nil
}
// RemoveAllowedIP removes a prefix from the allowed IPs list of peer
func (w *WGIface) RemoveAllowedIP(peerKey string, allowedIP string) error {
w.mu.Lock()
defer w.mu.Unlock()
log.Debugf("removing allowed IP from interface %s and peer %s: allowed IP %s ", w.Name, peerKey, allowedIP)
_, ipNet, err := net.ParseCIDR(allowedIP)
if err != nil {
return err
}
peerKeyParsed, err := wgtypes.ParseKey(peerKey)
if err != nil {
return err
}
existingPeer, err := getPeer(w.Name, peerKey)
if err != nil {
return err
}
newAllowedIPs := existingPeer.AllowedIPs
for i, existingAllowedIP := range existingPeer.AllowedIPs {
if existingAllowedIP.String() == ipNet.String() {
newAllowedIPs = append(existingPeer.AllowedIPs[:i], existingPeer.AllowedIPs[i+1:]...)
break
}
}
if err != nil {
return err
}
peer := wgtypes.PeerConfig{
PublicKey: peerKeyParsed,
UpdateOnly: true,
ReplaceAllowedIPs: true,
AllowedIPs: newAllowedIPs,
}
config := wgtypes.Config{
Peers: []wgtypes.PeerConfig{peer},
}
err = w.configureDevice(config)
if err != nil {
return fmt.Errorf("received error \"%v\" while removing allowed IP from peer on interface %s with settings: allowed ips %s", err, w.Name, allowedIP)
}
return nil
}
func getPeer(ifaceName, peerPubKey string) (wgtypes.Peer, error) {
wg, err := wgctrl.New()
if err != nil {
return wgtypes.Peer{}, err
}
defer func() {
err = wg.Close()
if err != nil {
log.Errorf("got error while closing wgctl: %v", err)
}
}()
wgDevice, err := wg.Device(ifaceName)
if err != nil {
return wgtypes.Peer{}, err
}
for _, peer := range wgDevice.Peers {
if peer.PublicKey.String() == peerPubKey {
return peer, nil
}
}
return wgtypes.Peer{}, fmt.Errorf("peer not found")
}
Refactor Interface package and update windows driver (#192) * script to generate syso files * test wireguard-windows driver package * set int log * add windows test * add windows test * verbose bash * use cd * move checkout * exit 0 * removed tty flag * artifact path * fix tags and add cache * fix cache * fix cache * test dir * restore artifacts in the root * try dll file * try dll file * copy dll * typo in copy dll * compile test * checkout first * updated cicd * fix add address issue and gen GUID * psexec typo * accept eula * mod tidy before tests * regular test exec and verbose test with psexec * test all * return WGInterface Interface * use WgIfaceName and timeout after 30 seconds * different ports and validate connect 2 peers * Use time.After for timeout and close interface * Use time.After for testing connect peers * WG Interface struct * Update engine and parse address * refactor Linux create and assignAddress * NewWGIface and configuration methods * Update proxy with interface methods * update up command test * resolve lint warnings * remove psexec test * close copied files * add goos before build * run tests on mac,windows and linux * cache by testing os * run on push * fix indentation * adjust test timeouts * remove parallel flag * mod tidy before test * ignore syso files * removed functions and renamed vars * different IPs for connect peers test * Generate syso with DLL * Single Close method * use port from test constant * test: remove wireguard interfaces after finishing engine test * use load_wgnt_from_rsrc Co-authored-by: braginini <bangvalo@gmail.com>
2022-01-17 14:01:58 +01:00
// RemovePeer removes a Wireguard Peer from the interface iface
func (w *WGIface) RemovePeer(peerKey string) error {
w.mu.Lock()
defer w.mu.Unlock()
Refactor Interface package and update windows driver (#192) * script to generate syso files * test wireguard-windows driver package * set int log * add windows test * add windows test * verbose bash * use cd * move checkout * exit 0 * removed tty flag * artifact path * fix tags and add cache * fix cache * fix cache * test dir * restore artifacts in the root * try dll file * try dll file * copy dll * typo in copy dll * compile test * checkout first * updated cicd * fix add address issue and gen GUID * psexec typo * accept eula * mod tidy before tests * regular test exec and verbose test with psexec * test all * return WGInterface Interface * use WgIfaceName and timeout after 30 seconds * different ports and validate connect 2 peers * Use time.After for timeout and close interface * Use time.After for testing connect peers * WG Interface struct * Update engine and parse address * refactor Linux create and assignAddress * NewWGIface and configuration methods * Update proxy with interface methods * update up command test * resolve lint warnings * remove psexec test * close copied files * add goos before build * run tests on mac,windows and linux * cache by testing os * run on push * fix indentation * adjust test timeouts * remove parallel flag * mod tidy before test * ignore syso files * removed functions and renamed vars * different IPs for connect peers test * Generate syso with DLL * Single Close method * use port from test constant * test: remove wireguard interfaces after finishing engine test * use load_wgnt_from_rsrc Co-authored-by: braginini <bangvalo@gmail.com>
2022-01-17 14:01:58 +01:00
log.Debugf("Removing peer %s from interface %s ", peerKey, w.Name)
peerKeyParsed, err := wgtypes.ParseKey(peerKey)
if err != nil {
return err
}
peer := wgtypes.PeerConfig{
PublicKey: peerKeyParsed,
Remove: true,
}
config := wgtypes.Config{
Peers: []wgtypes.PeerConfig{peer},
}
err = w.configureDevice(config)
if err != nil {
return fmt.Errorf("received error \"%v\" while removing peer %s from interface %s", err, peerKey, w.Name)
}
return nil
Refactor Interface package and update windows driver (#192) * script to generate syso files * test wireguard-windows driver package * set int log * add windows test * add windows test * verbose bash * use cd * move checkout * exit 0 * removed tty flag * artifact path * fix tags and add cache * fix cache * fix cache * test dir * restore artifacts in the root * try dll file * try dll file * copy dll * typo in copy dll * compile test * checkout first * updated cicd * fix add address issue and gen GUID * psexec typo * accept eula * mod tidy before tests * regular test exec and verbose test with psexec * test all * return WGInterface Interface * use WgIfaceName and timeout after 30 seconds * different ports and validate connect 2 peers * Use time.After for timeout and close interface * Use time.After for testing connect peers * WG Interface struct * Update engine and parse address * refactor Linux create and assignAddress * NewWGIface and configuration methods * Update proxy with interface methods * update up command test * resolve lint warnings * remove psexec test * close copied files * add goos before build * run tests on mac,windows and linux * cache by testing os * run on push * fix indentation * adjust test timeouts * remove parallel flag * mod tidy before test * ignore syso files * removed functions and renamed vars * different IPs for connect peers test * Generate syso with DLL * Single Close method * use port from test constant * test: remove wireguard interfaces after finishing engine test * use load_wgnt_from_rsrc Co-authored-by: braginini <bangvalo@gmail.com>
2022-01-17 14:01:58 +01:00
}