Design of Monitoring DDoS attacks in libnids

Source: Internet
Author: User

The main file for monitoring DDoS attacks in libnids is in scan. C. The main principle is to call the detect_scan function every time a SYN packet is sent during TCP processing. Check whether a DDoS attack exists based on the set parameters.

The algorithm involves the following two data structures:

  
 9 struct scan { 10   u_int addr; 11   unsigned short port; 12   u_char flags; 13 }; 14  15 struct host { 16   struct host *next; 17   struct host *prev; 18   u_int addr; 19   int modtime; 20   int n_packets; 21   struct scan *packets; 22 };


The original scan_detect algorithm of libnids is mainly used to discover that hackers use the same IP address to scan different hosts or ports using scanners. Count the number of hosts or port numbers of the same source IP address within a period of time.

The number of connections before the launch. If the threshold value scan_num_ports is exceeded, a hacker is considered to be launching an attack on our system.

The main data structure of the algorithm is to construct and maintain a hash table. The element type of the hash table is the header pointer to the bidirectional linked list storing the host node, the host node contains information about each host connected to the libnids protected. The hash table uses the source IP address of the data packet to calculate the hash value, the host with the same hash value will be linked to the next location of the existing host linked list.

The data members of the host node include the Source ip addr, the timestamp modtime received by Syn packet, and the number of SYN packages sent by the same source IP address n_packets, which is used to store the pointer packets of the link information, here we will take it as an array for a better understanding. N_packets indicates the number of packages.

The struct scan information is the dst_address and dst_port of the target host.

The main control flow of the algorithm is as follows:

 64 void 65 detect_scan(struct ip * iph) 66 { 67   int i; 68   struct tcphdr *th; 69   int hash; 70   struct host *this_host; 71   struct host *oldest; 72   int mtime = 2147483647; 73  74   if (nids_params.scan_num_hosts <= 0) 75     return; 76  77   th = (struct tcphdr *) (((char *) iph) + 4 * iph->ip_hl); 78   hash = scan_hash(iph->ip_src.s_addr); 79   this_host = hashhost[hash]; 80   oldest = 0; 81   timenow = 0; 82  83   for (i = 0; this_host && this_host->addr != iph->ip_src.s_addr; i++) { 84     if (this_host->modtime < mtime) { 85       mtime = this_host->modtime; 86       oldest = this_host; 87     } 88     this_host = this_host->next; 89   } 90   if (!this_host) { 91     if (i == 10) 92       this_host = oldest; 93     else { 94       this_host = (struct host *) malloc(sizeof(struct host) + \ 95             (nids_params.scan_num_ports + 1) * sizeof(struct scan)); 96       if (!this_host) 97           nids_params.no_mem("detect_scan"); 98       this_host->packets = (struct scan *) (((char *) this_host) + sizeof(struct host)); 99       if (hashhost[hash]) {100     hashhost[hash]->prev = this_host;101     this_host->next = hashhost[hash];102       }103       else104     this_host->next = 0;105       this_host->prev = 0;106       hashhost[hash] = this_host;107     }108     this_host->addr = iph->ip_src.s_addr;109     this_host->modtime = gettime();110     this_host->n_packets = 0;111   }112   if (this_host->modtime - gettime() > nids_params.scan_delay)113     this_host->n_packets = 0;114   this_host->modtime = gettime();115   for (i = 0; i < this_host->n_packets; i++)116     if (this_host->packets[i].addr == iph->ip_dst.s_addr &&117     this_host->packets[i].port == ntohs(th->th_dport))118       return;119   this_host->packets[this_host->n_packets].addr = iph->ip_dst.s_addr;120   this_host->packets[this_host->n_packets].port = ntohs(th->th_dport);121   this_host->packets[this_host->n_packets].flags = *((unsigned char *) (th) + 13);122   this_host->n_packets++;123   if (this_host->n_packets > nids_params.scan_num_ports) {124     nids_params.syslog(NIDS_WARN_SCAN, 0, 0, this_host);125     this_host->n_packets = 0;126   }127 }

Since there are not many source codes, the code of the entire function is pasted here. This Code provides the processing process for each SYN Packet: first, hash the data according to the source address and find the corresponding table items, find the host node with the same source IP address domain as the source IP address in the host two-way linked list that this table item points.

If no matching host node is found, if the maximum number of host nodes in each linked list is 10, the oldest host node is replaced. Otherwise, the system calls malloc to apply for a new host node and inserts it into an existing linked list or acts as the first element of the linked list based on whether the linked list is empty. Update the time domain of the host node to system time.

If a matched host node is found, <dst_addr, dst_port> Of the SYN packet is used to search for the packets array. If a matched array element is found, the system returns the result directly. If no matching array element exists, add n_packets to 1 and <dst_addr, dst_port> to the array Packets [n_packets.

Determine whether n_packets is greater than the set threshold value. If it is greater than, a warning is given and the n_packets is set to 0.


We can see from the above that this algorithm is a common algorithm. with a slight modification, we can monitor distributed tcp syn flood attacks (such as hash Based on dest ip) and UDP flood attacks.

We can see from the above that this algorithm is less efficient and can only be used in low-speed network environments. To use it in the environment, you need to optimize it. For example, remove malloc, adopt multi-core parallel technology, and use lockless data structures. Stream-based multi-core parallel execution leads to distribution of different destination addresses with the same source address to different CPU cores, which results in cache trashing and performance degradation, this problem can be considered to reduce the lock overhead through CAS atomic operations.


The high-performance code after optimization will not be posted here. It is mainly about algorithm ideas.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.