From ce5e7bee4affb5c991de3a7e20913fb3fd6beee5 Mon Sep 17 00:00:00 2001 From: Abhishek Kondur Date: Mon, 7 Nov 2022 10:44:14 +0530 Subject: [PATCH] route inbound packets to relayed node --- logic/peers.go | 16 +++++++++--- nm-proxy/manager/manager.go | 52 +++++++++++++++++++++++++------------ nm-proxy/peer/peer.go | 3 +-- nm-proxy/proxy/wireguard.go | 4 +-- nm-proxy/server/server.go | 13 +++++++++- 5 files changed, 62 insertions(+), 26 deletions(-) diff --git a/logic/peers.go b/logic/peers.go index 79d5e966..bde4d8ac 100644 --- a/logic/peers.go +++ b/logic/peers.go @@ -45,15 +45,23 @@ func GetPeersForProxy(node *models.Node, onlyPeers bool) (manager.ManagerPayload logger.Log(1, "failed to relayed nodes: ", node.Name, err.Error()) proxyPayload.IsRelay = false } else { - relayPeersMap := make(map[string][]wgtypes.PeerConfig) + relayPeersMap := make(map[string]manager.RelayedConf) for _, relayedNode := range relayedNodes { payload, err := GetPeersForProxy(&relayedNode, true) if err == nil { - relayPeersMap[relayedNode.PublicKey] = payload.Peers + relayedEndpoint, udpErr := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", relayedNode.Endpoint, relayedNode.LocalListenPort)) + if udpErr == nil { + relayPeersMap[relayedNode.PublicKey] = manager.RelayedConf{ + RelayedPeerEndpoint: relayedEndpoint, + RelayedPeerPubKey: relayedNode.PublicKey, + Peers: payload.Peers, + } + } + } } proxyPayload.IsRelay = true - proxyPayload.RelayedPeers = relayPeersMap + proxyPayload.RelayedPeerConf = relayPeersMap } } } @@ -89,7 +97,7 @@ func GetPeersForProxy(node *models.Node, onlyPeers bool) (manager.ManagerPayload if !onlyPeers && peer.IsRelayed == "yes" { relayNode := FindRelay(&peer) if relayNode != nil { - relayTo, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", peer.Endpoint, peer.LocalListenPort)) + relayTo, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", relayNode.Endpoint, relayNode.LocalListenPort)) if err == nil { peerConfMap[peer.PublicKey] = manager.PeerConf{ IsRelayed: true, diff --git a/nm-proxy/manager/manager.go b/nm-proxy/manager/manager.go index 25e7464d..df577a19 100644 --- a/nm-proxy/manager/manager.go +++ b/nm-proxy/manager/manager.go @@ -17,13 +17,19 @@ import ( type ProxyAction string type ManagerPayload struct { - InterfaceName string `json:"interface_name"` - Peers []wgtypes.PeerConfig `json:"peers"` - PeerMap map[string]PeerConf `json:"peer_map"` - IsRelayed bool `json:"is_relayed"` - RelayedTo *net.UDPAddr `json:"relayed_to"` - IsRelay bool `json:"is_relay"` - RelayedPeers map[string][]wgtypes.PeerConfig `json:"relayed_peers"` + InterfaceName string `json:"interface_name"` + Peers []wgtypes.PeerConfig `json:"peers"` + PeerMap map[string]PeerConf `json:"peer_map"` + IsRelayed bool `json:"is_relayed"` + RelayedTo *net.UDPAddr `json:"relayed_to"` + IsRelay bool `json:"is_relay"` + RelayedPeerConf map[string]RelayedConf `json:"relayed_conf"` +} + +type RelayedConf struct { + RelayedPeerEndpoint *net.UDPAddr `json:"relayed_peer_endpoint"` + RelayedPeerPubKey string `json:"relayed_peer_pub_key"` + Peers []wgtypes.PeerConfig `json:"relayed_peers"` } type PeerConf struct { IsRelayed bool `json:"is_relayed"` @@ -80,21 +86,22 @@ func (m *ManagerAction) RelayUpdate() { func (m *ManagerAction) RelayPeers() { common.IsRelay = true - for relayedNodePubKey, peers := range m.Payload.RelayedPeers { - for _, peer := range peers { - if _, ok := common.RelayPeerMap[relayedNodePubKey]; !ok { - common.RelayPeerMap[relayedNodePubKey] = make(map[string]common.RemotePeer) - } + for relayedNodePubKey, relayedNodeConf := range m.Payload.RelayedPeerConf { + relayedNodePubKeyHash := fmt.Sprintf("%x", md5.Sum([]byte(relayedNodePubKey))) + if _, ok := common.RelayPeerMap[relayedNodePubKeyHash]; !ok { + common.RelayPeerMap[relayedNodePubKeyHash] = make(map[string]common.RemotePeer) + } + for _, peer := range relayedNodeConf.Peers { peer.Endpoint.Port = common.NmProxyPort - relayedNodePubKeyHash := fmt.Sprintf("%x", md5.Sum([]byte(relayedNodePubKey))) remotePeerKeyHash := fmt.Sprintf("%x", md5.Sum([]byte(peer.PublicKey.String()))) - if _, ok := common.RelayPeerMap[relayedNodePubKeyHash]; !ok { - common.RelayPeerMap[relayedNodePubKeyHash] = make(map[string]common.RemotePeer) - } common.RelayPeerMap[relayedNodePubKeyHash][remotePeerKeyHash] = common.RemotePeer{ Endpoint: peer.Endpoint, } } + relayedNodeConf.RelayedPeerEndpoint.Port = common.NmProxyPort + common.RelayPeerMap[relayedNodePubKeyHash][relayedNodePubKeyHash] = common.RemotePeer{ + Endpoint: relayedNodeConf.RelayedPeerEndpoint, + } } } @@ -192,8 +199,19 @@ func (m *ManagerAction) AddInterfaceToProxy() error { Interface: ifaceName, PeerKey: peerI.PublicKey.String(), } + var isRelayed bool + var relayedTo *net.UDPAddr + if m.Payload.IsRelayed { + isRelayed = true + relayedTo = m.Payload.RelayedTo + } else { + if val, ok := m.Payload.PeerMap[peerI.PublicKey.String()]; ok { + isRelayed = val.IsRelayed + relayedTo = val.RelayedTo + } + } - peerpkg.AddNewPeer(wgInterface, &peerI, m.Payload.IsRelayed, m.Payload.RelayedTo) + peerpkg.AddNewPeer(wgInterface, &peerI, isRelayed, relayedTo) } log.Printf("------> PEERHASHMAP: %+v\n", common.PeerKeyHashMap) return nil diff --git a/nm-proxy/peer/peer.go b/nm-proxy/peer/peer.go index 26755490..0df2a9c7 100644 --- a/nm-proxy/peer/peer.go +++ b/nm-proxy/peer/peer.go @@ -8,7 +8,6 @@ import ( "github.com/gravitl/netmaker/nm-proxy/common" "github.com/gravitl/netmaker/nm-proxy/proxy" - "github.com/gravitl/netmaker/nm-proxy/server" "github.com/gravitl/netmaker/nm-proxy/wg" "golang.zx2c4.com/wireguard/wgctrl/wgtypes" ) @@ -47,7 +46,7 @@ func AddNewPeer(wgInterface *wg.WGIface, peer *wgtypes.PeerConfig, isRelayed boo peerEndpoint := peer.Endpoint.IP.String() if isRelayed { - go server.NmProxyServer.KeepAlive(peer.Endpoint.IP.String(), common.NmProxyPort) + //go server.NmProxyServer.KeepAlive(peer.Endpoint.IP.String(), common.NmProxyPort) peerEndpoint = relayTo.IP.String() } remoteConn, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", peerEndpoint, common.NmProxyPort)) diff --git a/nm-proxy/proxy/wireguard.go b/nm-proxy/proxy/wireguard.go index f0034a27..58aa8e49 100644 --- a/nm-proxy/proxy/wireguard.go +++ b/nm-proxy/proxy/wireguard.go @@ -63,8 +63,8 @@ func (p *Proxy) ProxyToRemote() { if err != nil { log.Println("failed to process pkt before sending: ", err) } - log.Printf("PROXING TO REMOTE!!!---> %s >>>>> %s [[ DstPort: %d, SrcPeerHash: %s, DstPeerHash: %s ]]\n", - server.NmProxyServer.Server.LocalAddr().String(), p.RemoteConn.String(), peerI.Config.RemoteWgPort, srcPeerKeyHash, dstPeerKeyHash) + log.Printf("PROXING TO REMOTE!!!---> %s >>>>> %s [[ SrcPeerHash: %s, DstPeerHash: %s ]]\n", + server.NmProxyServer.Server.LocalAddr().String(), p.RemoteConn.String(), srcPeerKeyHash, dstPeerKeyHash) } else { log.Printf("Peer: %s not found in config\n", p.Config.RemoteKey) continue diff --git a/nm-proxy/server/server.go b/nm-proxy/server/server.go index 0ffac14c..06bfb847 100644 --- a/nm-proxy/server/server.go +++ b/nm-proxy/server/server.go @@ -46,7 +46,7 @@ func (p *ProxyServer) Listen() { var srcPeerKeyHash, dstPeerKeyHash string n, srcPeerKeyHash, dstPeerKeyHash = packet.ExtractInfo(buffer, n) //log.Printf("--------> RECV PKT [DSTPORT: %d], [SRCKEYHASH: %s], SourceIP: [%s] \n", localWgPort, srcPeerKeyHash, source.IP.String()) - if common.IsRelay && dstPeerKeyHash != "" { + if common.IsRelay && dstPeerKeyHash != "" && srcPeerKeyHash != "" { if _, ok := common.WgIfaceKeyMap[dstPeerKeyHash]; !ok { log.Println("----------> Relaying######") @@ -60,6 +60,17 @@ func (p *ProxyServer) Listen() { log.Println("Failed to send to remote: ", err) } } + } else { + if remoteMap, ok := common.RelayPeerMap[dstPeerKeyHash]; ok { + if conf, ok := remoteMap[dstPeerKeyHash]; ok { + log.Printf("--------> Relaying BACK TO RELAYED NODE PKT [ SourceIP: %s ], [ SourceKeyHash: %s ], [ DstIP: %s ], [ DstHashKey: %s ] \n", + source.String(), srcPeerKeyHash, conf.Endpoint.String(), dstPeerKeyHash) + _, err = NmProxyServer.Server.WriteToUDP(buffer[:n+32], conf.Endpoint) + if err != nil { + log.Println("Failed to send to remote: ", err) + } + } + } } }