diff --git a/nm-proxy/manager/manager.go b/nm-proxy/manager/manager.go index aeb4f096..09e218dd 100644 --- a/nm-proxy/manager/manager.go +++ b/nm-proxy/manager/manager.go @@ -32,6 +32,7 @@ type ProxyAction string type ManagerPayload struct { InterfaceName string `json:"interface_name"` + WgAddr string `json:"wg_addr"` Peers []wgtypes.PeerConfig `json:"peers"` PeerMap map[string]PeerConf `json:"peer_map"` IsRelayed bool `json:"is_relayed"` @@ -76,7 +77,7 @@ func StartProxyManager(manageChan chan *ManagerAction) { switch mI.Action { case AddInterface: - mI.ExtClients() + mI.SetIngressGateway() err := mI.AddInterfaceToProxy() if err != nil { log.Printf("failed to add interface: [%s] to proxy: %v\n ", mI.Payload.InterfaceName, err) @@ -108,7 +109,7 @@ func (m *ManagerAction) RelayUpdate() { common.IsRelay = m.Payload.IsRelay } -func (m *ManagerAction) ExtClients() { +func (m *ManagerAction) SetIngressGateway() { common.IsIngressGateway = m.Payload.IsIngress } @@ -367,9 +368,9 @@ func (m *ManagerAction) AddInterfaceToProxy() error { shouldProceed = true } if peerConf.IsExtClient && peerConf.IsAttachedExtClient && shouldProceed { - //ctx, cancel := context.WithCancel(context.Background()) - //common.ExtClientsWaitTh[wgInterface.Name] = append(common.ExtClientsWaitTh[wgInterface.Name], cancel) - //go proxy.StartSniffer(ctx, wgInterface.Name, peerConf.Address, wgInterface.Port) + ctx, cancel := context.WithCancel(context.Background()) + common.ExtClientsWaitTh[wgInterface.Name] = append(common.ExtClientsWaitTh[wgInterface.Name], cancel) + go proxy.StartSniffer(ctx, wgInterface.Name, m.Payload.WgAddr, peerConf.Address, wgInterface.Port) } if peerConf.IsExtClient && !peerConf.IsAttachedExtClient { @@ -400,14 +401,14 @@ func (m *ManagerAction) AddInterfaceToProxy() error { log.Println("Extclient endpoint not updated yet....skipping") // TODO - watch the interface for ext client update go func(wgInterface *wg.WGIface, peer *wgtypes.PeerConfig, - isRelayed bool, relayTo *net.UDPAddr, peerConf PeerConf) { + isRelayed bool, relayTo *net.UDPAddr, peerConf PeerConf, ingGwAddr string) { addExtClient := false ctx, cancel := context.WithCancel(context.Background()) common.ExtClientsWaitTh[wgInterface.Name] = append(common.ExtClientsWaitTh[wgInterface.Name], cancel) defer func() { if addExtClient { log.Println("GOT ENDPOINT for Extclient adding peer...") - //go proxy.StartSniffer(ctx, wgInterface.Name, peerConf.Address, wgInterface.Port) + go proxy.StartSniffer(ctx, wgInterface.Name, ingGwAddr, peerConf.Address, wgInterface.Port) common.PeerKeyHashMap[fmt.Sprintf("%x", md5.Sum([]byte(peer.PublicKey.String())))] = common.RemotePeer{ Interface: wgInterface.Name, PeerKey: peer.PublicKey.String(), @@ -443,7 +444,7 @@ func (m *ManagerAction) AddInterfaceToProxy() error { } - }(wgInterface, &peerI, isRelayed, relayedTo, peerConf) + }(wgInterface, &peerI, isRelayed, relayedTo, peerConf, m.Payload.WgAddr) continue } diff --git a/nm-proxy/proxy/proxy.go b/nm-proxy/proxy/proxy.go index e86969fa..2810b9bd 100644 --- a/nm-proxy/proxy/proxy.go +++ b/nm-proxy/proxy/proxy.go @@ -4,8 +4,13 @@ import ( "context" "errors" "fmt" + "log" "net" + "time" + "github.com/google/gopacket" + "github.com/google/gopacket/layers" + "github.com/google/gopacket/pcap" "github.com/gravitl/netmaker/nm-proxy/common" "github.com/gravitl/netmaker/nm-proxy/wg" "golang.zx2c4.com/wireguard/wgctrl/wgtypes" @@ -102,132 +107,135 @@ func getBoardCastAddress() ([]net.Addr, error) { return nil, errors.New("couldn't obtain the broadcast addr") } -// func StartSniffer(ctx context.Context, ifaceName, extClientAddr string, port int) { -// log.Println("Starting Packet Sniffer for iface: ", ifaceName) -// var ( -// snapshotLen int32 = 1024 -// promiscuous bool = false -// err error -// timeout time.Duration = 1 * time.Microsecond -// handle *pcap.Handle -// ) -// // Open device -// handle, err = pcap.OpenLive(ifaceName, snapshotLen, promiscuous, timeout) -// if err != nil { -// log.Println("failed to start sniffer for iface: ", ifaceName, err) -// return -// } -// // if err := handle.SetBPFFilter(fmt.Sprintf("src %s and port %d", extClientAddr, port)); err != nil { -// // log.Println("failed to set bpf filter: ", err) -// // return -// // } -// defer handle.Close() +func StartSniffer(ctx context.Context, ifaceName, ingGwAddr, extClientAddr string, port int) { + log.Println("Starting Packet Sniffer for iface: ", ifaceName) + var ( + snapshotLen int32 = 1024 + promiscuous bool = false + err error + timeout time.Duration = 1 * time.Microsecond + handle *pcap.Handle + ) + // Open device + handle, err = pcap.OpenLive(ifaceName, snapshotLen, promiscuous, timeout) + if err != nil { + log.Println("failed to start sniffer for iface: ", ifaceName, err) + return + } + // if err := handle.SetBPFFilter(fmt.Sprintf("src %s and port %d", extClientAddr, port)); err != nil { + // log.Println("failed to set bpf filter: ", err) + // return + // } + defer handle.Close() -// // var tcp layers.TCP -// // var icmp layers.ICMPv4 -// // var udp layers.UDP -// // parser := gopacket.NewDecodingLayerParser(layers.LayerTypeIPv4, &udp, &tcp, &icmp) + // var tcp layers.TCP + // var icmp layers.ICMPv4 + // var udp layers.UDP + // parser := gopacket.NewDecodingLayerParser(layers.LayerTypeIPv4, &udp, &tcp, &icmp) -// packetSource := gopacket.NewPacketSource(handle, handle.LinkType()) -// for { -// select { -// case <-ctx.Done(): -// log.Println("Stopping packet sniffer for iface: ", ifaceName, " port: ", port) -// return -// default: -// packet, err := packetSource.NextPacket() -// if err == nil { -// //processPkt(ifaceName, packet) -// ipLayer := packet.Layer(layers.LayerTypeIPv4) -// if ipLayer != nil { -// fmt.Println("IPv4 layer detected.") -// ip, _ := ipLayer.(*layers.IPv4) + packetSource := gopacket.NewPacketSource(handle, handle.LinkType()) + for { + select { + case <-ctx.Done(): + log.Println("Stopping packet sniffer for iface: ", ifaceName, " port: ", port) + return + default: + packet, err := packetSource.NextPacket() + if err == nil { + //processPkt(ifaceName, packet) + ipLayer := packet.Layer(layers.LayerTypeIPv4) + if ipLayer != nil { + fmt.Println("IPv4 layer detected.") + ip, _ := ipLayer.(*layers.IPv4) -// // IP layer variables: -// // Version (Either 4 or 6) -// // IHL (IP Header Length in 32-bit words) -// // TOS, Length, Id, Flags, FragOffset, TTL, Protocol (TCP?), -// // Checksum, SrcIP, DstIP -// fmt.Println("#########################") -// fmt.Printf("From %s to %s\n", ip.SrcIP, ip.DstIP) -// fmt.Println("Protocol: ", ip.Protocol) -// if ip.DstIP.String() == extClientAddr || ip.SrcIP.String() == extClientAddr { -// if ifacePeers, ok := common.PeerAddrMap[ifaceName]; ok { -// if peerConf, ok := ifacePeers[ip.DstIP.String()]; ok { -// log.Println("-----> Fowarding PKT From ExtClient: ", extClientAddr, " to: ", peerConf) -// //server.NmProxyServer.Server.WriteTo(packet.Data(), ) -// } + // IP layer variables: + // Version (Either 4 or 6) + // IHL (IP Header Length in 32-bit words) + // TOS, Length, Id, Flags, FragOffset, TTL, Protocol (TCP?), + // Checksum, SrcIP, DstIP + fmt.Println("#########################") + fmt.Printf("From %s to %s\n", ip.SrcIP, ip.DstIP) + fmt.Println("Protocol: ", ip.Protocol) + if (ip.SrcIP.String() == extClientAddr && ip.DstIP.String() != ingGwAddr) || + (ip.DstIP.String() == extClientAddr && ip.SrcIP.String() != ingGwAddr) { -// } -// } + log.Println("-----> Fowarding PKT From: ", ip.SrcIP, " to: ", ip.DstIP) + c, err := net.Dial(fmt.Sprintf("ip:%s", ip.Protocol), ip.DstIP.String()) + if err == nil { + c.Write(ip.Payload) + } else { + log.Println("------> Failed to forward packet from sniffer: ", err) + c.Close() + } + } -// fmt.Println("#########################") -// } -// } -// } + fmt.Println("#########################") + } + } + } -// } -// } + } +} -// func processPkt(iface string, packet gopacket.Packet) { -// // Let's see if the packet is an ethernet packet -// // ethernetLayer := packet.Layer(layers.LayerTypeEthernet) -// // if ethernetLayer != nil { -// // fmt.Println("Ethernet layer detected.") -// // ethernetPacket, _ := ethernetLayer.(*layers.Ethernet) -// // fmt.Println("Source MAC: ", ethernetPacket.SrcMAC) -// // fmt.Println("Destination MAC: ", ethernetPacket.DstMAC) -// // // Ethernet type is typically IPv4 but could be ARP or other -// // fmt.Println("Ethernet type: ", ethernetPacket.EthernetType) -// // fmt.Println() -// // } +func processPkt(iface string, packet gopacket.Packet) { + // Let's see if the packet is an ethernet packet + // ethernetLayer := packet.Layer(layers.LayerTypeEthernet) + // if ethernetLayer != nil { + // fmt.Println("Ethernet layer detected.") + // ethernetPacket, _ := ethernetLayer.(*layers.Ethernet) + // fmt.Println("Source MAC: ", ethernetPacket.SrcMAC) + // fmt.Println("Destination MAC: ", ethernetPacket.DstMAC) + // // Ethernet type is typically IPv4 but could be ARP or other + // fmt.Println("Ethernet type: ", ethernetPacket.EthernetType) + // fmt.Println() + // } -// // Let's see if the packet is IP (even though the ether type told us) -// ipLayer := packet.Layer(layers.LayerTypeIPv4) -// if ipLayer != nil { -// fmt.Println("IPv4 layer detected.") -// ip, _ := ipLayer.(*layers.IPv4) + // Let's see if the packet is IP (even though the ether type told us) + ipLayer := packet.Layer(layers.LayerTypeIPv4) + if ipLayer != nil { + fmt.Println("IPv4 layer detected.") + ip, _ := ipLayer.(*layers.IPv4) -// // IP layer variables: -// // Version (Either 4 or 6) -// // IHL (IP Header Length in 32-bit words) -// // TOS, Length, Id, Flags, FragOffset, TTL, Protocol (TCP?), -// // Checksum, SrcIP, DstIP -// fmt.Printf("From %s to %s\n", ip.SrcIP, ip.DstIP) -// fmt.Println("Protocol: ", ip.Protocol) -// fmt.Println() + // IP layer variables: + // Version (Either 4 or 6) + // IHL (IP Header Length in 32-bit words) + // TOS, Length, Id, Flags, FragOffset, TTL, Protocol (TCP?), + // Checksum, SrcIP, DstIP + fmt.Printf("From %s to %s\n", ip.SrcIP, ip.DstIP) + fmt.Println("Protocol: ", ip.Protocol) + fmt.Println() -// } + } -// // udpLayer := packet.Layer(layers.LayerTypeUDP) -// // if udpLayer != nil { -// // udp, _ := udpLayer.(*layers.UDP) -// // fmt.Printf("UDP: From port %d to %d\n", udp.SrcPort, udp.DstPort) -// // fmt.Println() -// // } + // udpLayer := packet.Layer(layers.LayerTypeUDP) + // if udpLayer != nil { + // udp, _ := udpLayer.(*layers.UDP) + // fmt.Printf("UDP: From port %d to %d\n", udp.SrcPort, udp.DstPort) + // fmt.Println() + // } -// // // Iterate over all layers, printing out each layer type -// // fmt.Println("All packet layers:") -// // for _, layer := range packet.Layers() { -// // fmt.Println("- ", layer.LayerType()) -// // } + // // Iterate over all layers, printing out each layer type + // fmt.Println("All packet layers:") + // for _, layer := range packet.Layers() { + // fmt.Println("- ", layer.LayerType()) + // } -// // When iterating through packet.Layers() above, -// // if it lists Payload layer then that is the same as -// // this applicationLayer. applicationLayer contains the payload -// // applicationLayer := packet.ApplicationLayer() -// // if applicationLayer != nil { -// // fmt.Println("Application layer/Payload found.") -// // fmt.Printf("%s\n", applicationLayer.Payload()) + // When iterating through packet.Layers() above, + // if it lists Payload layer then that is the same as + // this applicationLayer. applicationLayer contains the payload + // applicationLayer := packet.ApplicationLayer() + // if applicationLayer != nil { + // fmt.Println("Application layer/Payload found.") + // fmt.Printf("%s\n", applicationLayer.Payload()) -// // // Search for a string inside the payload -// // if strings.Contains(string(applicationLayer.Payload()), "HTTP") { -// // fmt.Println("HTTP found!") -// // } -// // } + // // Search for a string inside the payload + // if strings.Contains(string(applicationLayer.Payload()), "HTTP") { + // fmt.Println("HTTP found!") + // } + // } -// // Check for errors -// if err := packet.ErrorLayer(); err != nil { -// fmt.Println("Error decoding some part of the packet:", err) -// } -// } + // Check for errors + if err := packet.ErrorLayer(); err != nil { + fmt.Println("Error decoding some part of the packet:", err) + } +}