From 8c97b871c1bb0523fa6c393eaa92bc2115745abb Mon Sep 17 00:00:00 2001 From: r-caamano Date: Thu, 5 Sep 2024 02:08:38 +0000 Subject: [PATCH] Reverting to static PAT for udp DNS --- CHANGELOG.md | 2 ++ src/zfw_tc_ingress.c | 32 ++++++++++--------- src/zfw_tc_outbound_track.c | 62 +++++++++++++++++++++---------------- 3 files changed, 55 insertions(+), 41 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6b1d15b..2539c69 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ All notable changes to this project will be documented in this file. The format - Fixed incorrect waitpid success/failure conditional checks in zfw.c and zfw_tunnel_wrapper.c. This did not cause an operational issue but would not report correctly in case system call failures. - Updated README with latest ```zfw -Q``` printout. +- Reverting to static PAT masquerade for DNS due to random udp checksum calculation failures that seem to only affect DNS. Will re-add back when a solution + is found. ### # [0.8.15] - 2024-08-26 diff --git a/src/zfw_tc_ingress.c b/src/zfw_tc_ingress.c index 97af5a4..b368bc9 100644 --- a/src/zfw_tc_ingress.c +++ b/src/zfw_tc_ingress.c @@ -2138,22 +2138,26 @@ int bpf_sk_splice(struct __sk_buff *skb){ if ((unsigned long)(udph + 1) > (unsigned long)skb->data_end){ return TC_ACT_SHOT; } - udph->dest = mv->o_sport; - bpf_l4_csum_replace(skb, sizeof(struct ethhdr) + sizeof(struct iphdr) + offsetof(struct udphdr, check), mk.sport , mv->o_sport, flags | 2); - iph = (struct iphdr *)(skb->data + sizeof(*eth)); - if ((unsigned long)(iph + 1) > (unsigned long)skb->data_end){ - return TC_ACT_SHOT; - } - tuple = (struct bpf_sock_tuple *)(void*)(long)&iph->saddr; - if(!tuple){ - return TC_ACT_SHOT; - } - tuple_len = sizeof(tuple->ipv4); - if ((unsigned long)tuple + tuple_len > (unsigned long)skb->data_end){ - return TC_ACT_SHOT; + if(udph->dest != mv->o_sport){ + udph->dest = mv->o_sport; + bpf_l4_csum_replace(skb, sizeof(struct ethhdr) + sizeof(struct iphdr) + offsetof(struct udphdr, check), mk.sport , mv->o_sport, flags | 2); + iph = (struct iphdr *)(skb->data + sizeof(*eth)); + if ((unsigned long)(iph + 1) > (unsigned long)skb->data_end){ + return TC_ACT_SHOT; + } + tuple = (struct bpf_sock_tuple *)(void*)(long)&iph->saddr; + if(!tuple){ + return TC_ACT_SHOT; + } + tuple_len = sizeof(tuple->ipv4); + if ((unsigned long)tuple + tuple_len > (unsigned long)skb->data_end){ + return TC_ACT_SHOT; + } } }else{ - udph->dest = mv->o_sport; + if(udph->dest != mv->o_sport){ + udph->dest = mv->o_sport; + } } } } diff --git a/src/zfw_tc_outbound_track.c b/src/zfw_tc_outbound_track.c index 226e6ff..4ac2a98 100644 --- a/src/zfw_tc_outbound_track.c +++ b/src/zfw_tc_outbound_track.c @@ -2573,20 +2573,24 @@ int bpf_sk_splice6(struct __sk_buff *skb){ revk.protocol = IPPROTO_UDP; revk.ifindex = skb->ifindex; __u16 rand_source_port = 0; - struct masq_value *revv = get_reverse_masquerade(revk); - if(revv){ - rand_source_port = revv->o_sport; - } - else{ - rand_source_port = bpf_htons(1024 + bpf_get_prandom_u32() % (65535 -1023)); - struct masq_value rev_new_val = {0}; - rev_new_val.o_sport = rand_source_port; - rev_new_val.__in46_u_origin.ip = 0; - insert_reverse_masquerade(rev_new_val,revk); - if(local_diag->verbose){ - event.tracking_code = REVERSE_MASQUERADE_ENTRY_ADDED; - send_event(&event); + if(tuple->ipv4.dport != bpf_ntohs(53)){ + struct masq_value *revv = get_reverse_masquerade(revk); + if(revv){ + rand_source_port = revv->o_sport; } + else{ + rand_source_port = bpf_htons(1024 + bpf_get_prandom_u32() % (65535 -1023)); + struct masq_value rev_new_val = {0}; + rev_new_val.o_sport = rand_source_port; + rev_new_val.__in46_u_origin.ip = 0; + insert_reverse_masquerade(rev_new_val,revk); + if(local_diag->verbose){ + event.tracking_code = REVERSE_MASQUERADE_ENTRY_ADDED; + send_event(&event); + } + } + }else{ + rand_source_port = tuple->ipv4.sport; } __u32 l3_sum = bpf_csum_diff((__u32 *)&tuple->ipv4.saddr, sizeof(tuple->ipv4.saddr), (__u32 *)&local_ip4->ipaddr[0], sizeof(local_ip4->ipaddr[0]), 0); struct masq_value mv = {0}; @@ -2647,22 +2651,26 @@ int bpf_sk_splice6(struct __sk_buff *skb){ if ((unsigned long)(udph + 1) > (unsigned long)skb->data_end){ return TC_ACT_SHOT; } - udph->source = rand_source_port; - bpf_l4_csum_replace(skb, sizeof(struct ethhdr) + sizeof(struct iphdr) + offsetof(struct udphdr, check), mv.o_sport , rand_source_port, flags | 2); - iph = (struct iphdr *)(skb->data + sizeof(*eth)); - if ((unsigned long)(iph + 1) > (unsigned long)skb->data_end){ - return TC_ACT_SHOT; - } - tuple = (struct bpf_sock_tuple *)(void*)(long)&iph->saddr; - if(!tuple){ - return TC_ACT_SHOT; + if(rand_source_port != udph->source){ + udph->source = rand_source_port; + bpf_l4_csum_replace(skb, sizeof(struct ethhdr) + sizeof(struct iphdr) + offsetof(struct udphdr, check), mv.o_sport , rand_source_port, flags | 2); + iph = (struct iphdr *)(skb->data + sizeof(*eth)); + if ((unsigned long)(iph + 1) > (unsigned long)skb->data_end){ + return TC_ACT_SHOT; + } + tuple = (struct bpf_sock_tuple *)(void*)(long)&iph->saddr; + if(!tuple){ + return TC_ACT_SHOT; + } + tuple_len = sizeof(tuple->ipv4); + if ((unsigned long)tuple + tuple_len > (unsigned long)skb->data_end){ + return TC_ACT_SHOT; + } } - tuple_len = sizeof(tuple->ipv4); - if ((unsigned long)tuple + tuple_len > (unsigned long)skb->data_end){ - return TC_ACT_SHOT; - } }else{ - udph->source = rand_source_port; + if(rand_source_port != udph->source){ + udph->source = rand_source_port; + } } } struct udp_state *ustate = get_udp(udp_state_key);