diff --git a/CHANGELOG.md b/CHANGELOG.md index 37ad83d..8ed2cc6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). --- +# [0.5.15] - 2024-04-12 + +### + +- Added map to track tcp syn count for packets sent to the firewall ip address on port 443. + # [0.5.14] - 2024-04-02 ### diff --git a/src/zfw.c b/src/zfw.c index d42df7a..55d40c2 100644 --- a/src/zfw.c +++ b/src/zfw.c @@ -139,6 +139,7 @@ const char *if_tun_map_path = "/sys/fs/bpf/tc/globals/ifindex_tun_map"; const char *transp_map_path = "/sys/fs/bpf/tc/globals/zet_transp_map"; const char *rb_map_path = "/sys/fs/bpf/tc/globals/rb_map"; const char *ddos_map_path = "/sys/fs/bpf/tc/globals/ddos_protect_map"; +const char *syn_count_map = "/sys/fs/bpf/tc/globals/syn_count_map"; char doc[] = "zfw -- ebpf firewall configuration tool"; const char *if_map_path; char *diag_interface; @@ -155,7 +156,7 @@ char *tc_interface; char *log_file_name; char *object_file; char *direction_string; -const char *argp_program_version = "0.5.14"; +const char *argp_program_version = "0.5.15"; struct ring_buffer *ring_buffer; __u8 if_list[MAX_IF_LIST_ENTRIES]; @@ -432,10 +433,10 @@ void disable_ebpf() disable = true; tc = true; interface_tc(); - const char *maps[12] = {tproxy_map_path, diag_map_path, if_map_path, count_map_path, + const char *maps[13] = {tproxy_map_path, diag_map_path, if_map_path, count_map_path, udp_map_path, matched_map_path, tcp_map_path, tun_map_path, if_tun_map_path, - transp_map_path, rb_map_path, ddos_map_path}; - for (int map_count = 0; map_count < 12; map_count++) + transp_map_path, rb_map_path, ddos_map_path, syn_count_map}; + for (int map_count = 0; map_count < 13; map_count++) { int stat = remove(maps[map_count]); diff --git a/src/zfw_tc_ingress.c b/src/zfw_tc_ingress.c index ebb9a7c..6077a09 100644 --- a/src/zfw_tc_ingress.c +++ b/src/zfw_tc_ingress.c @@ -237,6 +237,14 @@ struct { __uint(map_flags, BPF_F_NO_PREALLOC); } zet_transp_map SEC(".maps"); +struct { + __uint(type, BPF_MAP_TYPE_ARRAY); + __uint(key_size, sizeof(uint32_t)); + __uint(value_size,sizeof(uint32_t)); + __uint(max_entries, 1); + __uint(pinning, LIBBPF_PIN_BY_NAME); +} syn_count_map SEC(".maps"); + struct { __uint(type, BPF_MAP_TYPE_LRU_HASH); __uint(key_size, sizeof(uint32_t)); @@ -467,6 +475,32 @@ static inline void clear_match_tracker(struct match_key key){ bpf_map_delete_elem(&matched_map, &key); } +/*Function to get stored syn count*/ +static inline __u32 get_syn_count(__u32 key){ + __u32 *sc; + sc = bpf_map_lookup_elem(&syn_count_map,&key); + if(sc){ + return *sc; + } + return -1; +} + +/*Function to clear matched tracker*/ +static inline void clear_syn_count(__u32 key){ + uint32_t sc = 0; + bpf_map_update_elem(&syn_count_map, &key, &sc,0); +} + +/*Function to increment syn count*/ +static inline void inc_syn_count(__u32 key){ + __u32 *sc; + sc = bpf_map_lookup_elem(&syn_count_map,&key); + if(sc){ + *sc += 1; + bpf_map_update_elem(&syn_count_map, &key, sc,0); + } +} + /*Function to check if ip is in ddos whitelist*/ static inline bool *get_ddos_list(unsigned int key){ bool *match; @@ -898,6 +932,23 @@ int bpf_sk_splice(struct __sk_buff *skb){ if ((unsigned long)(tcph + 1) > (unsigned long)skb->data_end){ return TC_ACT_SHOT; } + if(tcph->syn && (bpf_ntohs(tuple->ipv4.dport) == 443) && local_ip4 && local_ip4->count){ + uint8_t addresses = 0; + if(local_ip4->count < MAX_ADDRESSES){ + addresses = local_ip4->count; + }else{ + addresses = MAX_ADDRESSES; + } + for(int x = 0; x < addresses; x++){ + if((tuple->ipv4.daddr == local_ip4->ipaddr[x]) && !local_diag->ssh_disable){ + if(local_diag->verbose){ + event.proto = IPPROTO_TCP; + send_event(&event); + } + inc_syn_count(0); + } + } + } tcp_state_key.daddr = tuple->ipv4.saddr; tcp_state_key.saddr = tuple->ipv4.daddr; tcp_state_key.sport = tuple->ipv4.dport;