From d0d9bc5ecd31e0cf5cf1150aba98f2405c4fb6dc Mon Sep 17 00:00:00 2001 From: Abhishek Kondur Date: Thu, 24 Nov 2022 10:47:33 +0530 Subject: [PATCH] connect to ext client by using handshake packet info --- nm-proxy/common/common.go | 8 +- nm-proxy/manager/manager.go | 48 +++--- nm-proxy/nm-proxy.go | 1 - nm-proxy/packet/packet_helper.go | 247 +++++++++++++++++++++++++++++++ nm-proxy/peer/peer.go | 20 +-- nm-proxy/proxy/proxy.go | 245 +++++++++++++++--------------- nm-proxy/proxy/wireguard.go | 10 +- nm-proxy/server/server.go | 50 +++++-- nm-proxy/wg/wg.go | 23 ++- 9 files changed, 470 insertions(+), 182 deletions(-) create mode 100644 nm-proxy/packet/packet_helper.go diff --git a/nm-proxy/common/common.go b/nm-proxy/common/common.go index dfbd6b13..30443568 100644 --- a/nm-proxy/common/common.go +++ b/nm-proxy/common/common.go @@ -15,6 +15,8 @@ var IsHostNetwork bool var IsRelay bool var IsIngressGateway bool var IsRelayed bool +var IsServer bool +var InterfaceName string const ( NmProxyPort = 51722 @@ -74,8 +76,8 @@ type RemotePeer struct { } type ExtClientPeer struct { - Endpoint *net.UDPAddr - context.CancelFunc + CancelFunc context.CancelFunc + CommChan chan *net.UDPAddr } type WgIfaceConf struct { @@ -93,6 +95,8 @@ var RelayPeerMap = make(map[string]map[string]RemotePeer) var ExtClientsWaitTh = make(map[string]ExtClientPeer) +var ExtSourceIpMap = make(map[string]RemotePeer) + // RunCmd - runs a local command func RunCmd(command string, printerr bool) (string, error) { args := strings.Fields(command) diff --git a/nm-proxy/manager/manager.go b/nm-proxy/manager/manager.go index 02bf3f8b..33cfd7f6 100644 --- a/nm-proxy/manager/manager.go +++ b/nm-proxy/manager/manager.go @@ -9,7 +9,6 @@ import ( "net" "reflect" "runtime" - "time" "github.com/gravitl/netmaker/nm-proxy/common" peerpkg "github.com/gravitl/netmaker/nm-proxy/peer" @@ -163,6 +162,7 @@ func (m *ManagerAction) processPayload() (*wg.WGIface, error) { log.Println("failed to get real iface: ", err) } } + common.InterfaceName = m.Payload.InterfaceName wgIface, err = wg.NewWGIFace(m.Payload.InterfaceName, "127.0.0.1/32", wg.DefaultMTU) if err != nil { log.Println("Failed init new interface: ", err) @@ -179,6 +179,7 @@ func (m *ManagerAction) processPayload() (*wg.WGIface, error) { log.Println("falied to update peer: ", err) } m.Payload.Peers = append(m.Payload.Peers[:i], m.Payload.Peers[i+1:]...) + continue } if m.Payload.PeerMap[m.Payload.Peers[i].PublicKey.String()].IsAttachedExtClient { if err := wgIface.Update(m.Payload.Peers[i], false); err != nil { @@ -220,7 +221,7 @@ func (m *ManagerAction) processPayload() (*wg.WGIface, error) { m.Payload.Peers = append(m.Payload.Peers[:i], m.Payload.Peers[i+1:]...) } - log.Println("----> Skip Processing ExtClient: ", m.Payload.Peers[i].PublicKey.String()) + continue } // check if proxy is off for the peer @@ -384,12 +385,11 @@ func (m *ManagerAction) AddInterfaceToProxy() error { shouldProceed = true } if peerConf.IsExtClient && peerConf.IsAttachedExtClient && shouldProceed { - ctx, cancel := context.WithCancel(context.Background()) - common.ExtClientsWaitTh[peerI.PublicKey.String()] = common.ExtClientPeer{ - Endpoint: peerI.Endpoint, - CancelFunc: cancel, - } - go proxy.StartSniffer(ctx, wgInterface.Name, m.Payload.WgAddr, peerConf.Address, wgInterface.Port) + // ctx, cancel := context.WithCancel(context.Background()) + // common.ExtClientsWaitTh[peerI.PublicKey.String()] = common.ExtClientPeer{ + // CancelFunc: cancel, + // } + //go proxy.StartSniffer(ctx, wgInterface.Name, m.Payload.WgAddr, peerConf.Address, wgInterface.Port) } if peerConf.IsExtClient && !peerConf.IsAttachedExtClient { @@ -422,15 +422,16 @@ func (m *ManagerAction) AddInterfaceToProxy() error { go func(wgInterface *wg.WGIface, peer *wgtypes.PeerConfig, isRelayed bool, relayTo *net.UDPAddr, peerConf PeerConf, ingGwAddr string) { addExtClient := false + commChan := make(chan *net.UDPAddr, 100) ctx, cancel := context.WithCancel(context.Background()) common.ExtClientsWaitTh[peerI.PublicKey.String()] = common.ExtClientPeer{ - Endpoint: peer.Endpoint, CancelFunc: cancel, + CommChan: commChan, } defer func() { if addExtClient { log.Println("GOT ENDPOINT for Extclient adding peer...") - go proxy.StartSniffer(ctx, wgInterface.Name, ingGwAddr, 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(), @@ -438,30 +439,31 @@ func (m *ManagerAction) AddInterfaceToProxy() error { IsAttachedExtClient: peerConf.IsAttachedExtClient, Endpoint: peer.Endpoint, } + common.ExtSourceIpMap[peer.Endpoint.String()] = common.RemotePeer{ + Interface: wgInterface.Name, + PeerKey: peer.PublicKey.String(), + IsExtClient: peerConf.IsExtClient, + IsAttachedExtClient: peerConf.IsAttachedExtClient, + Endpoint: peer.Endpoint, + } peerpkg.AddNewPeer(wgInterface, peer, peerConf.Address, isRelayed, peerConf.IsExtClient, peerConf.IsAttachedExtClient, relayedTo) + } + log.Println("Exiting extclient watch Thread for: ", peer.PublicKey.String()) }() for { select { case <-ctx.Done(): - log.Println("Exiting extclient watch Thread for: ", wgInterface.Device.PublicKey.String()) return - default: - wgInterface, err := wg.NewWGIFace(m.Payload.InterfaceName, "127.0.0.1/32", wg.DefaultMTU) - if err != nil { - log.Println("Failed init new interface: ", err) + case endpoint := <-commChan: + if endpoint != nil { + addExtClient = true + peer.Endpoint = endpoint + delete(common.ExtClientsWaitTh, peer.PublicKey.String()) return } - for _, devpeerI := range wgInterface.Device.Peers { - if devpeerI.PublicKey.String() == peer.PublicKey.String() && devpeerI.Endpoint != nil { - peer.Endpoint = devpeerI.Endpoint - addExtClient = true - return - } - } - time.Sleep(time.Second * 5) } } diff --git a/nm-proxy/nm-proxy.go b/nm-proxy/nm-proxy.go index 31f4751b..675fa444 100644 --- a/nm-proxy/nm-proxy.go +++ b/nm-proxy/nm-proxy.go @@ -21,7 +21,6 @@ import ( func Start(ctx context.Context, mgmChan chan *manager.ManagerAction, apiServerAddr string) { log.Println("Starting Proxy...") common.IsHostNetwork = (os.Getenv("HOST_NETWORK") == "" || os.Getenv("HOST_NETWORK") == "on") - hInfo := stun.GetHostInfo(apiServerAddr) stun.Host = hInfo log.Printf("HOSTINFO: %+v", hInfo) diff --git a/nm-proxy/packet/packet_helper.go b/nm-proxy/packet/packet_helper.go new file mode 100644 index 00000000..1090388a --- /dev/null +++ b/nm-proxy/packet/packet_helper.go @@ -0,0 +1,247 @@ +package packet + +import ( + "bytes" + "crypto/hmac" + "crypto/subtle" + "encoding/base64" + "encoding/binary" + "encoding/hex" + "errors" + "hash" + "log" + + "github.com/gravitl/netmaker/nm-proxy/wg" + "golang.org/x/crypto/blake2s" + "golang.org/x/crypto/chacha20poly1305" + "golang.org/x/crypto/curve25519" + "golang.org/x/crypto/poly1305" + "golang.zx2c4.com/wireguard/tai64n" +) + +func init() { + InitialChainKey = blake2s.Sum256([]byte(NoiseConstruction)) + mixHash(&InitialHash, &InitialChainKey, []byte(WGIdentifier)) +} +func mixKey(dst, c *[blake2s.Size]byte, data []byte) { + KDF1(dst, c[:], data) +} + +func mixHash(dst, h *[blake2s.Size]byte, data []byte) { + hash, _ := blake2s.New256(nil) + hash.Write(h[:]) + hash.Write(data) + hash.Sum(dst[:0]) + hash.Reset() +} +func HMAC1(sum *[blake2s.Size]byte, key, in0 []byte) { + mac := hmac.New(func() hash.Hash { + h, _ := blake2s.New256(nil) + return h + }, key) + mac.Write(in0) + mac.Sum(sum[:0]) +} + +func HMAC2(sum *[blake2s.Size]byte, key, in0, in1 []byte) { + mac := hmac.New(func() hash.Hash { + h, _ := blake2s.New256(nil) + return h + }, key) + mac.Write(in0) + mac.Write(in1) + mac.Sum(sum[:0]) +} + +func KDF1(t0 *[blake2s.Size]byte, key, input []byte) { + HMAC1(t0, key, input) + HMAC1(t0, t0[:], []byte{0x1}) +} + +const ( + NoiseConstruction = "Noise_IKpsk2_25519_ChaChaPoly_BLAKE2s" + WGIdentifier = "WireGuard v1 zx2c4 Jason@zx2c4.com" + WGLabelMAC1 = "mac1----" + WGLabelCookie = "cookie--" +) + +const ( + MessageInitiationType = 1 + MessageResponseType = 2 + MessageCookieReplyType = 3 + MessageTransportType = 4 +) +const ( + NoisePublicKeySize = 32 + NoisePrivateKeySize = 32 + NoisePresharedKeySize = 32 +) + +type ( + NoisePublicKey [NoisePublicKeySize]byte + NoisePrivateKey [NoisePrivateKeySize]byte + NoisePresharedKey [NoisePresharedKeySize]byte + NoiseNonce uint64 // padded to 12-bytes +) + +type MessageInitiation struct { + Type uint32 + Sender uint32 + Ephemeral NoisePublicKey + Static [NoisePublicKeySize + poly1305.TagSize]byte + Timestamp [tai64n.TimestampSize + poly1305.TagSize]byte + MAC1 [blake2s.Size128]byte + MAC2 [blake2s.Size128]byte +} + +var ( + InitialChainKey [blake2s.Size]byte + InitialHash [blake2s.Size]byte + ZeroNonce [chacha20poly1305.NonceSize]byte +) + +func KDF2(t0, t1 *[blake2s.Size]byte, key, input []byte) { + var prk [blake2s.Size]byte + HMAC1(&prk, key, input) + HMAC1(t0, prk[:], []byte{0x1}) + HMAC2(t1, prk[:], t0[:], []byte{0x2}) + setZero(prk[:]) +} +func setZero(arr []byte) { + for i := range arr { + arr[i] = 0 + } +} +func isZero(val []byte) bool { + acc := 1 + for _, b := range val { + acc &= subtle.ConstantTimeByteEq(b, 0) + } + return acc == 1 +} +func uapiCfg(cfg ...string) string { + if len(cfg)%2 != 0 { + panic("odd number of args to uapiReader") + } + buf := new(bytes.Buffer) + for i, s := range cfg { + buf.WriteString(s) + sep := byte('\n') + if i%2 == 0 { + sep = '=' + } + buf.WriteByte(sep) + } + return buf.String() +} +func sharedSecret(sk *NoisePrivateKey, pk NoisePublicKey) (ss [NoisePublicKeySize]byte) { + apk := (*[NoisePublicKeySize]byte)(&pk) + ask := (*[NoisePrivateKeySize]byte)(sk) + curve25519.ScalarMult(&ss, ask, apk) + return ss +} + +func ConsumeHandshakeMsg(buf []byte, devicePubKey NoisePublicKey, devicePrivKey NoisePrivateKey) (string, error) { + + var ( + hash [blake2s.Size]byte + chainKey [blake2s.Size]byte + ) + var err error + var msg MessageInitiation + reader := bytes.NewReader(buf[:]) + err = binary.Read(reader, binary.LittleEndian, &msg) + if err != nil { + log.Println("Failed to decode initiation message") + return "", err + } + + if msg.Type != MessageInitiationType { + return "", errors.New("not handshake initiate message") + } + log.Println("-----> HandSHAKE MESSAGE") + mixHash(&hash, &InitialHash, devicePubKey[:]) + mixHash(&hash, &hash, msg.Ephemeral[:]) + mixKey(&chainKey, &InitialChainKey, msg.Ephemeral[:]) + + // decrypt static key + var peerPK NoisePublicKey + var key [chacha20poly1305.KeySize]byte + ss := sharedSecret(&devicePrivKey, msg.Ephemeral) + if isZero(ss[:]) { + return "", errors.New("no secret") + } + KDF2(&chainKey, &key, chainKey[:], ss[:]) + aead, _ := chacha20poly1305.New(key[:]) + _, err = aead.Open(peerPK[:0], ZeroNonce[:], msg.Static[:], hash[:]) + if err != nil { + return "", err + } + setZero(hash[:]) + setZero(chainKey[:]) + return base64.StdEncoding.EncodeToString(peerPK[:]), nil +} + +func loadExactHex(dst []byte, src string) error { + slice, err := hex.DecodeString(src) + if err != nil { + return err + } + if len(slice) != len(dst) { + return errors.New("hex string does not fit the slice") + } + copy(dst, slice) + return nil +} + +func (key NoisePrivateKey) IsZero() bool { + var zero NoisePrivateKey + return key.Equals(zero) +} + +func (key NoisePrivateKey) Equals(tar NoisePrivateKey) bool { + return subtle.ConstantTimeCompare(key[:], tar[:]) == 1 +} + +func (key *NoisePrivateKey) FromHex(src string) (err error) { + err = loadExactHex(key[:], src) + key.clamp() + return +} + +func (key *NoisePrivateKey) FromMaybeZeroHex(src string) (err error) { + err = loadExactHex(key[:], src) + if key.IsZero() { + return + } + key.clamp() + return +} +func (sk *NoisePrivateKey) clamp() { + sk[0] &= 248 + sk[31] = (sk[31] & 127) | 64 +} + +func (key *NoisePublicKey) FromHex(src string) error { + return loadExactHex(key[:], src) +} + +func (key NoisePublicKey) IsZero() bool { + var zero NoisePublicKey + return key.Equals(zero) +} + +func (key NoisePublicKey) Equals(tar NoisePublicKey) bool { + return subtle.ConstantTimeCompare(key[:], tar[:]) == 1 +} + +func (key *NoisePresharedKey) FromHex(src string) error { + return loadExactHex(key[:], src) +} + +func GetDeviceKeys(ifaceName string) (NoisePrivateKey, NoisePublicKey, error) { + wgPrivKey := wg.GetWgIfacePrivKey(ifaceName) + wgPubKey := wg.GetWgIfacePubKey(ifaceName) + + return wgPrivKey, wgPubKey, nil +} diff --git a/nm-proxy/peer/peer.go b/nm-proxy/peer/peer.go index 5a1c4b86..ef2f2b8f 100644 --- a/nm-proxy/peer/peer.go +++ b/nm-proxy/peer/peer.go @@ -41,8 +41,8 @@ func AddNewPeer(wgInterface *wg.WGIface, peer *wgtypes.PeerConfig, peerAddr stri LocalKey: wgInterface.Device.PublicKey.String(), RemoteKey: peer.PublicKey.String(), WgInterface: wgInterface, - - PeerConf: peer, + IsExtClient: isExtClient, + PeerConf: peer, } p := proxy.NewProxy(c) peerPort := common.NmProxyPort @@ -65,15 +65,15 @@ func AddNewPeer(wgInterface *wg.WGIface, peer *wgtypes.PeerConfig, peerAddr stri } log.Printf("----> Established Remote Conn with RPeer: %s, ----> RAddr: %s", peer.PublicKey, remoteConn.String()) - if !(isExtClient && isAttachedExtClient) { - log.Printf("Starting proxy for Peer: %s\n", peer.PublicKey.String()) - err = p.Start(remoteConn) - if err != nil { - return err - } - } else { - log.Println("Not Starting Proxy for Attached ExtClient...") + // if !(isExtClient && isAttachedExtClient) { + log.Printf("Starting proxy for Peer: %s\n", peer.PublicKey.String()) + err = p.Start(remoteConn) + if err != nil { + return err } + // } else { + // log.Println("Not Starting Proxy for Attached ExtClient...") + // } connConf := common.ConnConfig{ Key: peer.PublicKey.String(), diff --git a/nm-proxy/proxy/proxy.go b/nm-proxy/proxy/proxy.go index f7701898..986c99dd 100644 --- a/nm-proxy/proxy/proxy.go +++ b/nm-proxy/proxy/proxy.go @@ -4,13 +4,8 @@ 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" @@ -28,14 +23,14 @@ type Config struct { RemoteKey string LocalKey string WgInterface *wg.WGIface + IsExtClient bool PeerConf *wgtypes.PeerConfig } // Proxy - WireguardProxy proxies type Proxy struct { - Ctx context.Context - Cancel context.CancelFunc - + Ctx context.Context + Cancel context.CancelFunc Config Config RemoteConn *net.UDPAddr LocalConn net.Conn @@ -107,136 +102,136 @@ func getBoardCastAddress() ([]net.Addr, error) { return nil, errors.New("couldn't obtain the broadcast addr") } -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() +// 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.String()) - if (ip.SrcIP.String() == extClientAddr && ip.DstIP.String() != ingGwAddr) || - (ip.DstIP.String() == extClientAddr && ip.SrcIP.String() != ingGwAddr) { +// // 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.String()) +// 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("ip", ip.DstIP.String()) - if err == nil { - c.Write(ip.Payload) - c.Close() - } else { - log.Println("------> Failed to forward packet from sniffer: ", err) +// log.Println("-----> Fowarding PKT From: ", ip.SrcIP, " to: ", ip.DstIP) +// c, err := net.Dial("ip", ip.DstIP.String()) +// if err == nil { +// c.Write(ip.Payload) +// c.Close() +// } else { +// log.Println("------> Failed to forward packet from sniffer: ", err) - } - } +// } +// } - 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) +// } +// } diff --git a/nm-proxy/proxy/wireguard.go b/nm-proxy/proxy/wireguard.go index 01419391..da330053 100644 --- a/nm-proxy/proxy/wireguard.go +++ b/nm-proxy/proxy/wireguard.go @@ -59,14 +59,18 @@ func (p *Proxy) ProxyToRemote() { log.Println("ERRR READ: ", err) continue } + //go func(buf []byte, n int) { ifaceConf := common.WgIFaceMap[p.Config.WgInterface.Name] if peerI, ok := ifaceConf.PeerMap[p.Config.RemoteKey]; ok { var srcPeerKeyHash, dstPeerKeyHash string - buf, n, srcPeerKeyHash, dstPeerKeyHash = packet.ProcessPacketBeforeSending(buf, n, peerI.Config.LocalKey, peerI.Config.Key) - if err != nil { - log.Println("failed to process pkt before sending: ", err) + if !p.Config.IsExtClient { + buf, n, srcPeerKeyHash, dstPeerKeyHash = packet.ProcessPacketBeforeSending(buf, n, peerI.Config.LocalKey, peerI.Config.Key) + if err != nil { + log.Println("failed to process pkt before sending: ", err) + } } + log.Printf("PROXING TO REMOTE!!!---> %s >>>>> %s >>>>> %s [[ SrcPeerHash: %s, DstPeerHash: %s ]]\n", p.LocalConn.LocalAddr(), server.NmProxyServer.Server.LocalAddr().String(), p.RemoteConn.String(), srcPeerKeyHash, dstPeerKeyHash) } else { diff --git a/nm-proxy/server/server.go b/nm-proxy/server/server.go index a39526ae..c791d868 100644 --- a/nm-proxy/server/server.go +++ b/nm-proxy/server/server.go @@ -60,11 +60,13 @@ func (p *ProxyServer) Listen(ctx context.Context) { log.Println("RECV ERROR: ", err) continue } + orgN := n //go func(buffer []byte, source *net.UDPAddr, n int) { var srcPeerKeyHash, dstPeerKeyHash string n, srcPeerKeyHash, dstPeerKeyHash = packet.ExtractInfo(buffer, n) - //log.Printf("--------> RECV PKT , [SRCKEYHASH: %s], SourceIP: [%s] \n", srcPeerKeyHash, source.IP.String()) + log.Printf("--------> RECV PKT , [SRCKEYHASH: %s], SourceIP: [%s] \n", srcPeerKeyHash, source.IP.String()) + if _, ok := common.WgIfaceKeyMap[dstPeerKeyHash]; !ok { // if common.IsIngressGateway { // log.Println("----> fowarding PKT to EXT client...") @@ -125,25 +127,45 @@ func (p *ProxyServer) Listen(ctx context.Context) { log.Println("Failed to proxy to Wg local interface: ", err) //continue } + continue } } } - // // forward to all interfaces - // for _, ifaceCfg := range common.WgIfaceKeyMap { - // log.Println("###--------> Forwarding Unknown PKT to ", ifaceCfg.Interface) - // conn, err := net.DialUDP("udp", nil, ifaceCfg.Endpoint) - // if err == nil { - // _, err := conn.Write(buffer[:n]) - // if err != nil { - // log.Println("Failed to forward the unknown pkt to ifcace: ", ifaceCfg.Interface, err) - // } - // conn.Close() - // } + if peerInfo, ok := common.ExtSourceIpMap[source.String()]; ok { + if ifaceConf, ok := common.WgIFaceMap[peerInfo.Interface]; ok { + if peerI, ok := ifaceConf.PeerMap[peerInfo.PeerKey]; ok { + log.Printf("PROXING TO LOCAL!!!---> %s <<<< %s <<<<<<<< %s [[ RECV PKT [SRCKEYHASH: %s], [DSTKEYHASH: %s], SourceIP: [%s] ]]\n", + peerI.Proxy.LocalConn.RemoteAddr(), peerI.Proxy.LocalConn.LocalAddr(), + fmt.Sprintf("%s:%d", source.IP.String(), source.Port), srcPeerKeyHash, dstPeerKeyHash, source.IP.String()) + _, err = peerI.Proxy.LocalConn.Write(buffer[:orgN]) + if err != nil { + log.Println("Failed to proxy to Wg local interface: ", err) + //continue + } + continue + + } + } + } + // consume handshake message for ext clients + devPriv, devPubkey, err := packet.GetDeviceKeys(common.InterfaceName) + if err == nil { + peerPubKey, err := packet.ConsumeHandshakeMsg(buffer[:orgN], devPubkey, devPriv) + if err != nil { + log.Println("---------> @@@ failed to decode HS: ", err) + } else { + log.Println("--------> Got HandShake from peer: ", peerPubKey, source) + if val, ok := common.ExtClientsWaitTh[peerPubKey]; ok { + val.CommChan <- source + } + } + + } else { + log.Println("failed to get device keys: ", err) + } - // } - //}(buffer, source, n) } } diff --git a/nm-proxy/wg/wg.go b/nm-proxy/wg/wg.go index 308282a3..74d5a473 100644 --- a/nm-proxy/wg/wg.go +++ b/nm-proxy/wg/wg.go @@ -80,18 +80,33 @@ func (w *WGIface) GetWgIface(iface string) error { return nil } -func GetWgIfacePubKey(iface string) string { +func GetWgIfacePubKey(iface string) [32]byte { wgClient, err := wgctrl.New() if err != nil { log.Println("Error fetching pub key: ", iface, err) - return "" + return [32]byte{} } dev, err := wgClient.Device(iface) if err != nil { log.Println("Error fetching pub key: ", iface, err) - return "" + return [32]byte{} } - return dev.PublicKey.String() + + return dev.PublicKey +} + +func GetWgIfacePrivKey(iface string) [32]byte { + wgClient, err := wgctrl.New() + if err != nil { + log.Println("Error fetching pub key: ", iface, err) + return [32]byte{} + } + dev, err := wgClient.Device(iface) + if err != nil { + log.Println("Error fetching pub key: ", iface, err) + return [32]byte{} + } + return dev.PrivateKey } // parseAddress parse a string ("1.2.3.4/24") address to WG Address