Skip to content

Commit

Permalink
Merge pull request #78 from netfoundry/v0.9.1-release-candidate
Browse files Browse the repository at this point in the history
Added code to ensure there are no ipv4 masquerade port collions
  • Loading branch information
r-caamano authored Oct 2, 2024
2 parents 49c8476 + ab54016 commit 411dffa
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 36 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file. The format
---
###

# [0.9.1] - 2024-10-01

- Added code to test if masquerade dst ip and src_port/dst_port/protocol combination is free before allocating new random
source port to ensure no collisions will occur.

###

# [0.9.0] - 2024-09-24
- Added several new Arguments to zfw to allow for direct system call integrations with
ziti-edge-tunnel ```-A --add-user-rules```, ```-H --init-tc <iface>```, ```-Z, --init-xdp <iface>```, ```-B, bind-saddr-add <cidr>```,
Expand Down
13 changes: 12 additions & 1 deletion src/zfw.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@
#define MASQUERADE_ENTRY_REMOVED 33
#define REVERSE_MASQUERADE_ENTRY_ADDED 34
#define MASQUERADE_ENTRY_ADDED 35
#define MASQUERADE_NO_FREE_TCP_SRC_PORTS_FOUND 36
#define MASQUERADE_NO_FREE_UDP_SRC_PORTS_FOUND 37

bool ddos = false;
bool add = false;
Expand Down Expand Up @@ -259,7 +261,7 @@ char *direction_string;
char *masq_interface;
char check_alt[IF_NAMESIZE];

const char *argp_program_version = "0.9.0";
const char *argp_program_version = "0.9.1";
struct ring_buffer *ring_buffer;

__u32 if_list[MAX_IF_LIST_ENTRIES];
Expand Down Expand Up @@ -3403,6 +3405,15 @@ static int process_events(void *ctx, void *data, size_t len)
{
state = "MASQUERADE_ENTRY_REMOVED";
}
else if (code == MASQUERADE_NO_FREE_TCP_SRC_PORTS_FOUND)
{
state = "MASQUERADE_NO_FREE_TCP_SRC_PORTS_FOUND";
}
else if (code == MASQUERADE_NO_FREE_UDP_SRC_PORTS_FOUND)
{
state = "MASQUERADE_NO_FREE_UDP_SRC_PORTS_FOUND";
}


if (state)
{
Expand Down
12 changes: 11 additions & 1 deletion src/zfw_monitor.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@
#define MASQUERADE_ENTRY_REMOVED 33
#define REVERSE_MASQUERADE_ENTRY_ADDED 34
#define MASQUERADE_ENTRY_ADDED 35
#define MASQUERADE_NO_FREE_TCP_SRC_PORTS_FOUND 36
#define MASQUERADE_NO_FREE_UDP_SRC_PORTS_FOUND 37

bool logging = false;
bool monitor = false;
Expand All @@ -85,7 +87,7 @@ char check_alt[IF_NAMESIZE];
char doc[] = "zfw_monitor -- ebpf firewall monitor tool";
const char *rb_map_path = "/sys/fs/bpf/tc/globals/rb_map";
const char *tproxy_map_path = "/sys/fs/bpf/tc/globals/zt_tproxy_map";
const char *argp_program_version = "0.9.0";
const char *argp_program_version = "0.9.1";
union bpf_attr rb_map;
int rb_fd = -1;

Expand Down Expand Up @@ -530,6 +532,14 @@ static int process_events(void *ctx, void *data, size_t len)
{
state = "MASQUERADE_ENTRY_REMOVED";
}
else if (code == MASQUERADE_NO_FREE_TCP_SRC_PORTS_FOUND)
{
state = "MASQUERADE_NO_FREE_TCP_SRC_PORTS_FOUND";
}
else if (code == MASQUERADE_NO_FREE_UDP_SRC_PORTS_FOUND)
{
state = "MASQUERADE_NO_FREE_UDP_SRC_PORTS_FOUND";
}

if (state)
{
Expand Down
42 changes: 22 additions & 20 deletions src/zfw_tc_ingress.c
Original file line number Diff line number Diff line change
Expand Up @@ -749,13 +749,15 @@ static inline struct masq_value *get_masquerade(struct masq_key key){
}

/*Remove entry from masq state table*/
static inline void del_masq(struct masq_key key){
bpf_map_delete_elem(&masquerade_map, &key);
static inline int del_masq(struct masq_key key){
int ret = bpf_map_delete_elem(&masquerade_map, &key);
return ret;
}

/*Remove entry from reverse masq state table*/
static inline void del_reverse_masq(struct masq_reverse_key key){
bpf_map_delete_elem(&masquerade_reverse_map, &key);
static inline int del_reverse_masq(struct masq_reverse_key key){
int ret = bpf_map_delete_elem(&masquerade_reverse_map, &key);
return ret;
}

static inline struct masq_value *get_reverse_masquerade(struct masq_reverse_key key){
Expand Down Expand Up @@ -2111,14 +2113,14 @@ int bpf_sk_splice(struct __sk_buff *skb){
mk.__in46_u_dest.ip = iph->saddr;
mk.ifindex = event.ifindex;
mk.protocol = IPPROTO_TCP;
del_masq(mk);
if(local_diag->verbose){
int dm_ret = del_masq(mk);
if(!dm_ret && local_diag->verbose){
event.tracking_code = MASQUERADE_ENTRY_REMOVED;
send_event(&event);
}
}
del_reverse_masq(rk);
if(local_diag->verbose){
int drm_ret = del_reverse_masq(rk);
if(!drm_ret && local_diag->verbose){
event.tracking_code = REVERSE_MASQUERADE_ENTRY_REMOVED;
send_event(&event);
}
Expand Down Expand Up @@ -2151,14 +2153,14 @@ int bpf_sk_splice(struct __sk_buff *skb){
mk.__in46_u_dest.ip = iph->saddr;
mk.ifindex = event.ifindex;
mk.protocol = IPPROTO_TCP;
del_masq(mk);
if(local_diag->verbose){
int dm_ret = del_masq(mk);
if(!dm_ret && local_diag->verbose){
event.tracking_code = MASQUERADE_ENTRY_REMOVED;
send_event(&event);
}
}
del_reverse_masq(rk);
if(local_diag->verbose){
int drm_ret = del_reverse_masq(rk);
if(!drm_ret && local_diag->verbose){
event.tracking_code = REVERSE_MASQUERADE_ENTRY_REMOVED;
send_event(&event);
}
Expand Down Expand Up @@ -2321,14 +2323,14 @@ int bpf_sk_splice(struct __sk_buff *skb){
mk.__in46_u_dest.ip = iph->saddr;
mk.ifindex = event.ifindex;
mk.protocol = IPPROTO_UDP;
del_masq(mk);
if(local_diag->verbose){
int dm_ret = del_masq(mk);
if(!dm_ret && local_diag->verbose){
event.tracking_code = MASQUERADE_ENTRY_REMOVED;
send_event(&event);
}
}
del_reverse_masq(rk);
if(local_diag->verbose){
int drm_ret = del_reverse_masq(rk);
if(!drm_ret && local_diag->verbose){
event.tracking_code = REVERSE_MASQUERADE_ENTRY_REMOVED;
send_event(&event);
}
Expand Down Expand Up @@ -2374,14 +2376,14 @@ int bpf_sk_splice(struct __sk_buff *skb){
mk.__in46_u_dest.ip = iph->saddr;
mk.ifindex = event.ifindex;
mk.protocol = IPPROTO_UDP;
del_masq(mk);
if(local_diag->verbose){
int dm_ret = del_masq(mk);
if(!dm_ret && local_diag->verbose){
event.tracking_code = MASQUERADE_ENTRY_REMOVED;
send_event(&event);
}
}
del_reverse_masq(rk);
if(local_diag->verbose){
int drm_ret = del_reverse_masq(rk);
if(!drm_ret && local_diag->verbose){
event.tracking_code = REVERSE_MASQUERADE_ENTRY_REMOVED;
send_event(&event);
}
Expand Down
74 changes: 60 additions & 14 deletions src/zfw_tc_outbound_track.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@
#define MASQUERADE_ENTRY_REMOVED 33
#define REVERSE_MASQUERADE_ENTRY_ADDED 34
#define MASQUERADE_ENTRY_ADDED 35
#define MASQUERADE_NO_FREE_TCP_SRC_PORTS_FOUND 36
#define MASQUERADE_NO_FREE_UDP_SRC_PORTS_FOUND 37
#define memcpy(dest, src, n) __builtin_memcpy((dest), (src), (n))

struct bpf_event{
Expand Down Expand Up @@ -557,17 +559,19 @@ static inline struct masq_value *get_masquerade(struct masq_key key){
}

/*Remove entry from masq state table*/
static inline void del_masq(struct masq_key key){
bpf_map_delete_elem(&masquerade_map, &key);
static inline int del_masq(struct masq_key key){
int ret = bpf_map_delete_elem(&masquerade_map, &key);
return ret;
}

static inline void insert_reverse_masquerade(struct masq_value mv, struct masq_reverse_key key){
bpf_map_update_elem(&masquerade_reverse_map, &key, &mv,0);
}

/*Remove entry from reverse masq state table*/
static inline void del_reverse_masq(struct masq_reverse_key key){
bpf_map_delete_elem(&masquerade_reverse_map, &key);
static inline int del_reverse_masq(struct masq_reverse_key key){
int ret = bpf_map_delete_elem(&masquerade_reverse_map, &key);
return ret;
}

static inline struct masq_value *get_reverse_masquerade(struct masq_reverse_key key){
Expand Down Expand Up @@ -2339,7 +2343,28 @@ int bpf_sk_splice6(struct __sk_buff *skb){
rand_source_port = revv->o_sport;
}
else{
rand_source_port = bpf_htons(1024 + bpf_get_prandom_u32() % (65535 -1023));
int tcount = 0;
while(true){
rand_source_port = bpf_htons(1024 + bpf_get_prandom_u32() % (65535 -1023));
struct masq_key tmk = {0};
tmk.__in46_u_dest.ip = tuple->ipv4.daddr;
tmk.dport = tuple->ipv4.dport;
tmk.sport = rand_source_port;
tmk.ifindex = skb->ifindex;
tmk.protocol = IPPROTO_TCP;
struct masq_value *tmvptr = get_masquerade(tmk);
if(!tmvptr){
break;
}
tcount++;
if(tcount > 5000){
if(local_diag->verbose){
event.tracking_code = MASQUERADE_NO_FREE_TCP_SRC_PORTS_FOUND;
send_event(&event);
}
return TC_ACT_SHOT;
}
}
struct masq_value rev_new_val = {0};
rev_new_val.o_sport = rand_source_port;
rev_new_val.__in46_u_origin.ip = 0;
Expand Down Expand Up @@ -2465,8 +2490,8 @@ int bpf_sk_splice6(struct __sk_buff *skb){
rk.__in46_u_dest.ip = tcp_state_key.__in46_u_dst.ip;
rk.__in46_u_src.ip = tcp_state_key.__in46_u_src.ip;
rk.protocol = IPPROTO_TCP;
del_reverse_masq(rk);
if(local_diag->verbose){
int drm_ret = del_reverse_masq(rk);
if(!drm_ret && local_diag->verbose){
event.tracking_code = REVERSE_MASQUERADE_ENTRY_REMOVED;
send_event(&event);
}
Expand All @@ -2476,8 +2501,8 @@ int bpf_sk_splice6(struct __sk_buff *skb){
mk.__in46_u_dest.ip = iph->daddr;
mk.ifindex = event.ifindex;
mk.protocol = IPPROTO_TCP;
del_masq(mk);
if(local_diag->verbose){
int dm_ret = del_masq(mk);
if(!dm_ret && local_diag->verbose){
event.tracking_code = MASQUERADE_ENTRY_REMOVED;
send_event(&event);
}
Expand Down Expand Up @@ -2513,8 +2538,8 @@ int bpf_sk_splice6(struct __sk_buff *skb){
rk.__in46_u_dest.ip = tcp_state_key.__in46_u_dst.ip;
rk.__in46_u_src.ip = tcp_state_key.__in46_u_src.ip;
rk.protocol = IPPROTO_TCP;
del_reverse_masq(rk);
if(local_diag->verbose){
int drm_ret = del_reverse_masq(rk);
if(!drm_ret && local_diag->verbose){
event.tracking_code = REVERSE_MASQUERADE_ENTRY_REMOVED;
send_event(&event);
}
Expand All @@ -2524,8 +2549,8 @@ int bpf_sk_splice6(struct __sk_buff *skb){
mk.__in46_u_dest.ip = iph->daddr;
mk.ifindex = event.ifindex;
mk.protocol = IPPROTO_TCP;
del_masq(mk);
if(local_diag->verbose){
int dm_ret = del_masq(mk);
if(!dm_ret && local_diag->verbose){
event.tracking_code = MASQUERADE_ENTRY_REMOVED;
send_event(&event);
}
Expand Down Expand Up @@ -2590,7 +2615,28 @@ int bpf_sk_splice6(struct __sk_buff *skb){
rand_source_port = revv->o_sport;
}
else{
rand_source_port = bpf_htons(1024 + bpf_get_prandom_u32() % (65535 -1023));
int tcount = 0;
while(true){
rand_source_port = bpf_htons(1024 + bpf_get_prandom_u32() % (65535 -1023));
struct masq_key tmk = {0};
tmk.__in46_u_dest.ip = tuple->ipv4.daddr;
tmk.dport = tuple->ipv4.dport;
tmk.sport = rand_source_port;
tmk.ifindex = skb->ifindex;
tmk.protocol = IPPROTO_UDP;
struct masq_value *tmvptr = get_masquerade(tmk);
if(!tmvptr){
break;
}
tcount++;
if(tcount > 5000){
if(local_diag->verbose){
event.tracking_code = MASQUERADE_NO_FREE_UDP_SRC_PORTS_FOUND;
send_event(&event);
}
return TC_ACT_SHOT;
}
}
struct masq_value rev_new_val = {0};
rev_new_val.o_sport = rand_source_port;
rev_new_val.__in46_u_origin.ip = 0;
Expand Down

0 comments on commit 411dffa

Please sign in to comment.