123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243 |
- package logic
- import (
- "os"
- "os/exec"
- "strings"
- "github.com/gravitl/netmaker/logger"
- "github.com/gravitl/netmaker/models"
- "github.com/gravitl/netmaker/netclient/ncutils"
- "github.com/gravitl/netmaker/netclient/wireguard"
- "github.com/gravitl/netmaker/nm-proxy/manager"
- "golang.zx2c4.com/wireguard/wgctrl"
- "golang.zx2c4.com/wireguard/wgctrl/wgtypes"
- )
- // RemoveConf - removes a configuration for a given WireGuard interface
- func RemoveConf(iface string, printlog bool) error {
- var err error
- confPath := ncutils.GetNetclientPathSpecific() + iface + ".conf"
- err = removeWGQuickConf(confPath, printlog)
- return err
- }
- // HasPeerConnected - checks if a client node has connected over WG
- func HasPeerConnected(node *models.Node) bool {
- client, err := wgctrl.New()
- if err != nil {
- return false
- }
- defer client.Close()
- device, err := client.Device(node.Interface)
- if err != nil {
- return false
- }
- for _, peer := range device.Peers {
- if peer.PublicKey.String() == node.PublicKey {
- if peer.Endpoint != nil {
- return true
- }
- }
- }
- return false
- }
- // IfaceDelta - checks if the new node causes an interface change
- func IfaceDelta(currentNode *models.Node, newNode *models.Node) bool {
- // single comparison statements
- if newNode.Endpoint != currentNode.Endpoint ||
- newNode.PublicKey != currentNode.PublicKey ||
- newNode.Address != currentNode.Address ||
- newNode.Address6 != currentNode.Address6 ||
- newNode.IsEgressGateway != currentNode.IsEgressGateway ||
- newNode.IsIngressGateway != currentNode.IsIngressGateway ||
- newNode.IsRelay != currentNode.IsRelay ||
- newNode.UDPHolePunch != currentNode.UDPHolePunch ||
- newNode.IsPending != currentNode.IsPending ||
- newNode.ListenPort != currentNode.ListenPort ||
- newNode.LocalListenPort != currentNode.LocalListenPort ||
- newNode.MTU != currentNode.MTU ||
- newNode.PersistentKeepalive != currentNode.PersistentKeepalive ||
- newNode.DNSOn != currentNode.DNSOn ||
- newNode.Connected != currentNode.Connected ||
- len(newNode.AllowedIPs) != len(currentNode.AllowedIPs) {
- return true
- }
- // multi-comparison statements
- if newNode.IsEgressGateway == "yes" {
- if len(currentNode.EgressGatewayRanges) != len(newNode.EgressGatewayRanges) {
- return true
- }
- for _, address := range newNode.EgressGatewayRanges {
- if !StringSliceContains(currentNode.EgressGatewayRanges, address) {
- return true
- }
- }
- }
- if newNode.IsRelay == "yes" {
- if len(currentNode.RelayAddrs) != len(newNode.RelayAddrs) {
- return true
- }
- for _, address := range newNode.RelayAddrs {
- if !StringSliceContains(currentNode.RelayAddrs, address) {
- return true
- }
- }
- }
- for _, address := range newNode.AllowedIPs {
- if !StringSliceContains(currentNode.AllowedIPs, address) {
- return true
- }
- }
- return false
- }
- // == Private Functions ==
- // gets the server peers locally
- func getSystemPeers(node *models.Node) (map[string]string, error) {
- peers := make(map[string]string)
- client, err := wgctrl.New()
- if err != nil {
- return peers, err
- }
- defer client.Close()
- device, err := client.Device(node.Interface)
- if err != nil {
- return nil, err
- }
- if device.Peers != nil && len(device.Peers) > 0 {
- for _, peer := range device.Peers {
- if IsBase64(peer.PublicKey.String()) && peer.Endpoint != nil && CheckEndpoint(peer.Endpoint.String()) {
- peers[peer.PublicKey.String()] = peer.Endpoint.String()
- }
- }
- }
- return peers, nil
- }
- func removeWGQuickConf(confPath string, printlog bool) error {
- if _, err := ncutils.RunCmd("wg-quick down "+confPath, printlog); err != nil {
- return err
- }
- return nil
- }
- func setWGConfig(node *models.Node, peerupdate bool) error {
- peers, err := GetPeerUpdate(node)
- if err != nil {
- return err
- }
- privkey, err := FetchPrivKey(node.ID)
- if err != nil {
- return err
- }
- if peerupdate {
- if err := wireguard.SetPeers(node.Interface, node, peers.Peers); err != nil {
- logger.Log(0, "error updating peers", err.Error())
- return err
- }
- // logger.Log(0, "--------> UPDATE PEERS IN PROXY.....")
- // ProxyMgmChan <- &manager.ManagerAction{
- // Action: manager.UpdatePeer,
- // Payload: manager.ManagerPayload{
- // InterfaceName: node.Interface,
- // Peers: peers.Peers,
- // },
- // }
- logger.Log(2, "updated peers on server", node.Name)
- } else {
- err = wireguard.InitWireguard(node, privkey, peers.Peers)
- if err != nil {
- logger.Log(0, "failed to set wg config on server: ", node.Name, err.Error())
- return err
- }
- logger.Log(3, "finished setting wg config on server", node.Name)
- }
- logger.Log(0, "--------> ADD/Update INTERFACE TO PROXY.....")
- proxyPayload, err := GetPeersForProxy(node, false)
- if err != nil {
- logger.Log(0, "failed to get peers for proxy: ", err.Error())
- } else {
- ProxyMgmChan <- &manager.ManagerAction{
- Action: manager.AddInterface,
- Payload: proxyPayload,
- }
- }
- return nil
- }
- func setWGKeyConfig(node *models.Node) error {
- privatekey, err := wgtypes.GeneratePrivateKey()
- if err != nil {
- return err
- }
- privkeystring := privatekey.String()
- publickey := privatekey.PublicKey()
- node.PublicKey = publickey.String()
- err = StorePrivKey(node.ID, privkeystring)
- if err != nil {
- return err
- }
- if node.Action == models.NODE_UPDATE_KEY {
- node.Action = models.NODE_NOOP
- }
- return setWGConfig(node, false)
- }
- func removeLocalServer(node *models.Node) error {
- var err error
- var ifacename = node.Interface
- if err = RemovePrivKey(node.ID); err != nil {
- logger.Log(1, "failed to remove server conf from db", node.ID)
- }
- if ifacename != "" {
- if !ncutils.IsKernel() {
- if err = RemoveConf(ifacename, true); err == nil {
- logger.Log(1, "removed WireGuard interface:", ifacename)
- }
- } else {
- ipExec, err := exec.LookPath("ip")
- if err != nil {
- return err
- }
- out, err := ncutils.RunCmd(ipExec+" link del "+ifacename, false)
- dontprint := strings.Contains(out, "does not exist") || strings.Contains(out, "Cannot find device")
- if err != nil && !dontprint {
- logger.Log(1, "error running command:", ipExec, "link del", ifacename)
- logger.Log(1, out)
- }
- if node.PostDown != "" {
- ncutils.RunCmd(node.PostDown, false)
- }
- }
- }
- home := ncutils.GetNetclientPathSpecific()
- if ncutils.FileExists(home + "netconfig-" + node.Network) {
- _ = os.Remove(home + "netconfig-" + node.Network)
- }
- if ncutils.FileExists(home + "nettoken-" + node.Network) {
- _ = os.Remove(home + "nettoken-" + node.Network)
- }
- if ncutils.FileExists(home + "secret-" + node.Network) {
- _ = os.Remove(home + "secret-" + node.Network)
- }
- if ncutils.FileExists(home + "wgkey-" + node.Network) {
- _ = os.Remove(home + "wgkey-" + node.Network)
- }
- if ncutils.FileExists(home + "nm-" + node.Network + ".conf") {
- _ = os.Remove(home + "nm-" + node.Network + ".conf")
- }
- return err
- }
|