diff --git a/client/internal/dns/service_listener.go b/client/internal/dns/service_listener.go index d9997d543..f0f34f3c9 100644 --- a/client/internal/dns/service_listener.go +++ b/client/internal/dns/service_listener.go @@ -26,6 +26,7 @@ type serviceViaListener struct { dnsMux *dns.ServeMux customAddr *netip.AddrPort server *dns.Server + fakeIP string listenIP string listenPort int listenerIsRunning bool @@ -67,8 +68,9 @@ func (s *serviceViaListener) Listen() error { s.server.Addr = fmt.Sprintf("%s:%d", s.listenIP, s.listenPort) if s.shouldApplyPortFwd() { + s.fakeIP = getLastIPFromNetwork(s.wgInterface.Address().Network, 1) s.ebpfService = ebpf.GetEbpfManagerInstance() - err = s.ebpfService.LoadDNSFwd(s.listenIP, s.listenPort) + err = s.ebpfService.LoadDNSFwd(s.fakeIP, s.listenIP, s.listenPort) if err != nil { log.Warnf("failed to load DNS port fwd, custom port may not support well: %s", err) s.ebpfService = nil @@ -132,7 +134,14 @@ func (s *serviceViaListener) RuntimePort() int { } func (s *serviceViaListener) RuntimeIP() string { - return s.listenIP + s.listenerFlagLock.Lock() + defer s.listenerFlagLock.Unlock() + + if s.ebpfService != nil { + return s.fakeIP + } else { + return s.listenIP + } } func (s *serviceViaListener) setListenerStatus(running bool) { diff --git a/client/internal/ebpf/bpf_bpfeb.o b/client/internal/ebpf/bpf_bpfeb.o index 0559da486..c506a4350 100644 Binary files a/client/internal/ebpf/bpf_bpfeb.o and b/client/internal/ebpf/bpf_bpfeb.o differ diff --git a/client/internal/ebpf/bpf_bpfel.o b/client/internal/ebpf/bpf_bpfel.o index 05fa42ecd..f05d0ac4b 100644 Binary files a/client/internal/ebpf/bpf_bpfel.o and b/client/internal/ebpf/bpf_bpfel.o differ diff --git a/client/internal/ebpf/dns_fwd_linux.go b/client/internal/ebpf/dns_fwd_linux.go index e3ea6a4af..c2002c7b0 100644 --- a/client/internal/ebpf/dns_fwd_linux.go +++ b/client/internal/ebpf/dns_fwd_linux.go @@ -10,12 +10,13 @@ import ( ) const ( - mapKeyDNSIP uint32 = 0 - mapKeyDNSPort uint32 = 1 + mapKeyFakeIP uint32 = 0 + mapKeyDNSIP uint32 = 1 + mapKeyDNSPort uint32 = 2 ) -func (tf *GeneralManager) LoadDNSFwd(ip string, dnsPort int) error { - log.Debugf("load ebpf DNS forwarder: address: %s:%d", ip, dnsPort) +func (tf *GeneralManager) LoadDNSFwd(fakeIp, dnsIp string, dnsPort int) error { + log.Debugf("load ebpf DNS forwarder: address: %s:%d", dnsIp, dnsPort) tf.lock.Lock() defer tf.lock.Unlock() @@ -24,7 +25,12 @@ func (tf *GeneralManager) LoadDNSFwd(ip string, dnsPort int) error { return err } - err = tf.bpfObjs.NbMapDnsIp.Put(mapKeyDNSIP, ip2int(ip)) + err = tf.bpfObjs.NbMapDnsIp.Put(mapKeyFakeIP, ip2int(fakeIp)) + if err != nil { + return err + } + + err = tf.bpfObjs.NbMapDnsIp.Put(mapKeyDNSIP, ip2int(dnsIp)) if err != nil { return err } diff --git a/client/internal/ebpf/manager.go b/client/internal/ebpf/manager.go index 95c2fdc28..1aa940ff1 100644 --- a/client/internal/ebpf/manager.go +++ b/client/internal/ebpf/manager.go @@ -1,7 +1,7 @@ package ebpf type Manager interface { - LoadDNSFwd(ip string, dnsPort int) error + LoadDNSFwd(fakeIP, dnsIP string, dnsPort int) error FreeDNSFwd() error LoadWgProxy(proxyPort, wgPort int) error FreeWGProxy() error diff --git a/client/internal/ebpf/manager_linux.go b/client/internal/ebpf/manager_linux.go index b1d986f20..a68a114f2 100644 --- a/client/internal/ebpf/manager_linux.go +++ b/client/internal/ebpf/manager_linux.go @@ -74,6 +74,7 @@ func (tf *GeneralManager) loadXdp() error { Program: tf.bpfObjs.NbXdpProg, Interface: iFace.Index, }) + return err } diff --git a/client/internal/ebpf/src/dns_fwd.c b/client/internal/ebpf/src/dns_fwd.c index 5228c7e75..f59ed11a8 100644 --- a/client/internal/ebpf/src/dns_fwd.c +++ b/client/internal/ebpf/src/dns_fwd.c @@ -1,5 +1,7 @@ -const __u32 map_key_dns_ip = 0; -const __u32 map_key_dns_port = 1; + +const __u32 map_key_fake_ip = 0; +const __u32 map_key_dns_ip = 1; +const __u32 map_key_dns_port = 2; struct bpf_map_def SEC("maps") nb_map_dns_ip = { .type = BPF_MAP_TYPE_ARRAY, @@ -15,6 +17,7 @@ struct bpf_map_def SEC("maps") nb_map_dns_port = { .max_entries = 10, }; +__be32 fake_ip = 0; __be32 dns_ip = 0; __be16 dns_port = 0; @@ -22,8 +25,16 @@ __be16 dns_port = 0; __be16 GENERAL_DNS_PORT = 13568; bool read_settings() { - __u16 *port_value; + __u32 *fake_ip_value; __u32 *ip_value; + __u16 *port_value; + + // read fake ip + fake_ip_value = bpf_map_lookup_elem(&nb_map_dns_ip, &map_key_fake_ip); + if(!fake_ip_value) { + return false; + } + fake_ip = htonl(*fake_ip_value); // read dns ip ip_value = bpf_map_lookup_elem(&nb_map_dns_ip, &map_key_dns_ip); @@ -46,17 +57,17 @@ int xdp_dns_fwd(struct iphdr *ip, struct udphdr *udp) { if(!read_settings()){ return XDP_PASS; } - bpf_printk("dns port: %d", ntohs(dns_port)); - bpf_printk("dns ip: %d", ntohl(dns_ip)); } - if (udp->dest == GENERAL_DNS_PORT && ip->daddr == dns_ip) { + if (udp->dest == GENERAL_DNS_PORT && ip->daddr == fake_ip) { udp->dest = dns_port; + ip->daddr = dns_ip; return XDP_PASS; } if (udp->source == dns_port && ip->saddr == dns_ip) { udp->source = GENERAL_DNS_PORT; + ip->saddr = fake_ip; return XDP_PASS; } diff --git a/client/internal/ebpf/wg_proxy_linux.go b/client/internal/ebpf/wg_proxy_linux.go index bdaa3da06..a149383e4 100644 --- a/client/internal/ebpf/wg_proxy_linux.go +++ b/client/internal/ebpf/wg_proxy_linux.go @@ -2,7 +2,9 @@ package ebpf -import log "github.com/sirupsen/logrus" +import ( + log "github.com/sirupsen/logrus" +) const ( mapKeyProxyPort uint32 = 0 @@ -35,6 +37,7 @@ func (tf *GeneralManager) LoadWgProxy(proxyPort, wgPort int) error { return err } return nil + } func (tf *GeneralManager) FreeWGProxy() error {