Institute of Parallel and Distributed Systems University of Stuttgart Universitätsstraße 38 D–70569 Stuttgart Masterarbeit Design and Implementation of a DDoS Defense Mechanism Based on Network QoS Models David Augustat Course of Study: Informatik Examiner: Prof. Dr. phil. nat. Christian Becker Supervisor: M.Sc. Robin Laidig Commenced: April 2, 2024 Completed: October 30, 2024 Abstract Distributed denial-of-service (DDoS) attacks have become increasingly prevalent and disruptive to online services, negatively impacting their availability. Many existing DDoS mitigation methods rely on endpoint defense, leaving network-level interventions at routers underexplored. This work proposes the DPTB DDoS Defense (DDD) mechanism, a novel network-level DDoS defense based on the Dynamic Priority Token Bucket (DPTB) Quality of Service model developed at the University of Stuttgart. DDD mitigates DDoS attacks inside the routers of a network by categorizing hosts into non-attackers, potential attackers, and definitive attackers, with responses that range from de-prioritization to blocking. The mechanism features a TCP SYN flooding protection along with two strategies, Bidirectional DDD and Downstream Reporting, to address downstream-intensive DDoS attacks such as HTTP flooding. To evaluate DDD, we implement it with the OMNeT++ network simulation framework and assess its performance against UDP flooding, TCP SYN flooding, and HTTP flooding attacks. Our findings indicate that DDD outperforms traditional Rate Limiting in all three attack types, effectively mitigating malicious traffic while allowing legitimate packets. The TCP SYN flooding protection proves to be highly effective, leading to nearly perfect discrimination between legitimate and malicious traffic. DDD achieves lower average response times than Rate Limiting for legitimate HTTP requests during an HTTP flooding attack. This work contributes a novel QoS-based DDoS defense mechanism, an implementation of this mechanism in OMNeT++, and a comprehensive analysis, positioning DDD as a viable improvement over existing QoS-based DDoS defenses for mitigating network and transport layer DDoS attacks. Kurzfassung Distributed-Denial-of-Service-Angriffe (DDoS) treten immer häufiger auf und stören Online-Dienste, indem sie deren Verfügbarkeit beeinträchtigen. Viele bestehende DDoS-Abwehrmechanismen beschränken sich auf Abwehr am Server-Endpunkt und lassen Eingriffe auf Netzwerkebene an den Routern unerforscht. Diese Arbeit schlägt den DPTB-DDoS-Defense-Mechanismus (DDD) vor, eine neuartige DDoS-Abwehr auf Netzwerkebene, die auf dem Dynamic-Priority-Token- Bucket (DPTB) Dienstgütemodell basiert, das an der Universität Stuttgart entwickelt wurde. DDD bekämpft DDoS-Angriffe innerhalb der Router eines Netzwerks, indem Hosts in Nicht-Angreifer, potenzielle Angreifer und definitive Angreifer kategorisiert werden, wobei die Reaktionen von der Prioritätsreduktion bis zum Blockieren reichen. Der Mechanismus bietet einen Schutz vor TCP-SYN-Flooding-Angriffen sowie zwei Strategien, Bidirectional-DDD und Downstream- Reporting, um downstream-intensive DDoS-Angriffe wie HTTP-Flooding abzuwehren. Um DDD zu evaluieren, implementieren wir das Verfahren mit dem OMNeT++-Netzwerksimulationsframework und bewerten seine Performanz beim Abwehren von UDP-Flooding-, TCP-SYN-Flooding- und HTTP-Flooding-Angriffen. Unsere Ergebnisse zeigen, dass DDD bei allen drei Angriffsarten besser abschneidet als herkömmliches Rate-Limiting, da es den bösartigen Datenverkehr wirksam abschwächt und gleichzeitig legitime Pakete durchlässt. Der Schutz vor TCP-SYN-Flooding erweist sich als äußerst effektiv und führt zu einer nahezu perfekten Unterscheidung zwischen legitimem und bösartigem Netzwerkverkehr. DDD erreicht für legitime HTTP-Anfragen während eines HTTP- Flooding-Angriffs niedrigere durchschnittliche Antwortzeiten als Rate-Limiting. Diese Arbeit liefert einen neuartigen, dienstgütebasierten DDoS-Abwehrmechanismus, eine Implementierung dieses 3 Mechanismus in OMNeT++ und eine umfassende Analyse, die zum Schluss kommt, dass DDD eine deutliche Verbesserung gegenüber bestehenden dienstgütebasierten DDoS-Abwehrmechanismen zur Eindämmung von DDoS-Angriffen auf Netzwerk- und Transportebene darstellt. 4 Contents 1 Introduction 13 2 Background 15 2.1 DDoS Attacks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 2.2 Quality of Service (QoS) Models . . . . . . . . . . . . . . . . . . . . . . . . . 17 2.3 OMNeT++ and INET . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 3 Related Work 23 3.1 Apiecionek et al.: History-Based DDoS Detection and Blocking . . . . . . . . . 23 3.2 Oktian et al.: DoS Protection in OpenFlow Networks . . . . . . . . . . . . . . 23 3.3 Buragohain et al.: SDN-Based DDoS Mitigation . . . . . . . . . . . . . . . . . 24 3.4 Kirdan et al.: Rate Limiting on the Subnet Level . . . . . . . . . . . . . . . . . 24 3.5 Zhang et al.: Dynamic DDoS Defense Using Confidence Value . . . . . . . . . 25 3.6 Differences to This Work . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 4 System Model and Problem Statement 27 4.1 System Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 4.2 Problem Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 5 Design 31 5.1 General Approach . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 5.2 Bidirectional DDD and Downstream Reporting . . . . . . . . . . . . . . . . . . 33 5.3 TCP SYN Flooding Protection . . . . . . . . . . . . . . . . . . . . . . . . . . 34 5.4 Preventing IP Spoofing Attacks . . . . . . . . . . . . . . . . . . . . . . . . . . 35 5.5 Choosing Parameters for DDD . . . . . . . . . . . . . . . . . . . . . . . . . . 36 6 Implementation 39 6.1 Collecting Statistics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 6.2 Implementing Custom Queueing Algorithms With INET . . . . . . . . . . . . . 40 6.3 Rate Limiting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42 6.4 DDD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44 6.5 HTTP Server and Browser . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47 6.6 TCP SYN Flooding Attacker Application . . . . . . . . . . . . . . . . . . . . . 49 6.7 Network Simulation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49 7 Evaluation 53 7.1 Metrics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53 7.2 Simulation Setup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 7.3 Influence of Simulation Duration . . . . . . . . . . . . . . . . . . . . . . . . . 55 7.4 Behavior of DDD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 5 7.5 Comparison With Existing DDoS Defense Mechanisms . . . . . . . . . . . . . 61 7.6 Summary of Results . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68 8 Conclusion and Outlook 71 A Appendix 73 Bibliography 77 6 List of Figures 2.1 Illustration of a Token Bucket . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 2.2 Visualization of DPTB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 4.1 Network structure considered in this work . . . . . . . . . . . . . . . . . . . . . 28 4.2 Internal structure of the routers . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 5.1 Packet processing in a DDD smart router . . . . . . . . . . . . . . . . . . . . . . 32 5.2 Bidirectional DDD interfering with TCP’s congestion control mechanism. . . . . 34 5.3 Detailed view on packet processing in a DDD smart router . . . . . . . . . . . . 35 6.1 UML class diagram of the queueing implementations . . . . . . . . . . . . . . . 42 6.2 Example network in OMNeT++ . . . . . . . . . . . . . . . . . . . . . . . . . . 51 7.1 Influence of simulation time on Packet Discrimination Score . . . . . . . . . . . 56 7.2 Behavior of DDD for different 𝑓𝑟 and 𝑓𝑏 . . . . . . . . . . . . . . . . . . . . . . 57 7.3 Influence of share of smart routers on Packet Discrimination Score . . . . . . . . 59 7.4 Influence of malicious client share on Packet Discrimination Score . . . . . . . . 60 7.5 Influence of the distribution of malicious clients . . . . . . . . . . . . . . . . . . 61 7.6 Packet Discrimination Score for UDP flooding among various defense mechanisms 64 7.7 Upstream Packet Discrimination Score for TCP SYN flooding among various defense mechanisms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66 7.8 Total Score of various DDoS defense methods at defending an HTTP flooding attack 67 7.9 Upstream Packet Discrimination Scores of various DDoS defense methods at defending an HTTP flooding attack . . . . . . . . . . . . . . . . . . . . . . . . . 68 7.10 Comparison of average response times using different DDoS defense mechanisms in an HTTP flooding attack . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69 7.11 Comparison of response-to-request ratios using different DDoS defense mechanisms in an HTTP flooding attack . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 A.1 UDP flooding: Percentage of good upstream packets that were dropped . . . . . . 73 A.2 UDP flooding: Percentage of bad upstream packets that were dropped . . . . . . 73 A.3 TCP SYN flooding: Percentage of good upstream packets that were dropped . . . 74 A.4 TCP SYN flooding: Percentage of bad upstream packets that were dropped . . . . 74 A.5 HTTP flooding: Percentage of good upstream packets that were dropped . . . . . 75 A.6 HTTP flooding: Percentage of bad upstream packets that were dropped . . . . . . 75 A.7 HTTP flooding: Downstream Packet Discrimination Score . . . . . . . . . . . . 76 7 List of Listings 6.1 Code in the DynamicPriorityTokenBucket class to update the bucket level and calculate the priority class of a packet. (slightly simplified) . . . . . . . . . . . . 45 9 Acronyms ACK Acknowledgement. AS Autonomous System. BGP Border Gateway Protocol. CPU Central Processing Unit. CSS Cascading Style Sheets. DDD DPTB DDoS Defense. DDD-B Bidirectional DDD. DDD-DR DDD with Downstream Reporting. DDoS Distributed Denial of Service. DoS Denial of Service. DPTB Dynamic Priority Token Bucket. FIFO first in, first out. HTML Hypertext Markup Language. HTTP Hypertext Transfer Protocol. ICMP Internet Control Message Protocol. ID Identifier. IoT Internet of Things. IP Internet Protocol. JS JavaScript. MAC Medium Access Control. NED Network Description. OMNeT++ Objective Modular Network Testbed in C++. QoS Quality of Service. RAM Random-Access Memory. RED Random Early Detection. RL Rate Limiting. 11 Acronyms RL-B Bidirectional Rate Limiting. RL-U Unidirectional Rate Limiting. RNG Random Number Generator. SDN Software-Defined Networking. SSH Secure Shell (Protocol). TCB Transmission Control Block. TCP Transmission Control Protocol. UDP User Datagram Protocol. UML Unified Modeling Language. UTC Coordinated Universal Time. 12 1 Introduction Distributed denial-of-service (DDoS) attacks have become a growing problem for operators of online services in recent years, with no end in sight. In the first half of 2024, Cloudflare registered 8.5 million DDoS attacks on their network, with a 20 % increase from last year [Clo24b]. DDoS attacks negatively impact the availability of a server by sending large amounts of network traffic to it via the internet [ZFS17]. These attacks are typically carried out by botnets consisting of compromised computers. The omnipresence of IoT (Internet of Things) devices has given rise to such botnets, as these devices commonly lack basic cybersecurity measures [AAB+17]. The ubiquity of DDoS attacks necessitates the development of effective DDoS defense mechanisms. A lot of research already exists in the field of DDoS mitigation [MR04]. However, most DDoS defense mechanisms work at the server endpoint and do not make use of the routers inside the network to defend DDoS attacks closer to the source. While there exist multiple DDoS defense mechanisms that work on routers and focus on the network and transport layer, these approaches are usually rather simplistic and only use basic Quality of Service methods like Rate Limiting to mitigate attacks [ACD14; KREC18; OLL14]. This thesis proposes the DPTB DDoS Defense (DDD) mechanism, a network-level DDoS defense approach based on a Quality of Service model. DDD focuses on network and transport layer DDoS attacks and is implemented on the routers of large networks like the Internet. This enables it to mitigate DDoS attacks close to their origin, keeping the load inside the network and at the server’s endpoint low. The defense mechanism is based on a modified version of the Dynamic Priority Token Bucket (DPTB) Quality of Service model developed at the University of Stuttgart. DPTB is an extension of the Token Bucket algorithm and introduces multiple traffic classes to which data streams are mapped based on their behavior. DDD uses DPTB to classify hosts into one of three categories: no DDoS attacker, potential DDoS attacker, and definitive DDoS attacker. While the middle category decreases the host’s priority, the latter category gets the host blocked on the router. DDD features a special TCP SYN flooding protection to recognize and mitigate TCP SYN flooding attacks despite their low traffic volume. The proposed mechanism also comes with two strategies to treat downstream traffic from the server to the client: Bidirectional DDD and Downstream Reporting. These approaches are supposed to provide a more effective defense against downstream-heavy DDoS attack types like HTTP flooding. DDD includes several measures against IP spoofing to prevent the approach itself from being misused to lock out other legitimate clients from the network using spoofed sender IP addresses. To evaluate the performance of DDD and compare it to existing DDoS defense approaches, we implement the approach using the OMNeT++ network simulation framework and the INET network component library. The DDD mechanism itself is implemented as a custom packet queueing module inside INET’s router component. We conduct evaluations on three common types of DDoS attacks, namely UDP flooding, TCP SYN flooding, and HTTP flooding, to examine the effectiveness of DDD in mitigating these attacks. We evaluate how DDD performs under different shares and 13 1 Introduction distributions of malicious clients in the network and how the percentage of DDD-capable routers impacts its effectiveness. It was found that the share of malicious clients has a low impact on DDD’s performance, as this mechanism treats each client individually. DDD performed a bit worse with a clustered distribution of malicious clients than with an even distribution of attackers within the network. We found that there is a linear relationship between the share of DDD-capable routers in the network and DDD’s performance at defending UDP flooding attacks. We also look at how the choice of parameters for DDD influences its performance, finding that small values for DDD’s 𝑓𝑟 and 𝑓𝑏 parameters yield better performance while posing stricter limitations for legitimate clients. DDD is compared against two variants of Rate Limiting, another network-level DDoS defense mechanism based on QoS models. We found that DDD outperforms Rate Limiting at mitigating UDP flooding, TCP SYN flooding, and HTTP flooding attacks. DDD’s TCP SYN flooding protection proved highly effective at defending SYN flooding attacks, blocking up to 100 % of malicious traffic while letting through almost all legitimate packets. DDD with Downstream Reporting has shown to be significantly more effective than Bidirectional DDD in defending against HTTP flooding attacks. DDD could deliver lower average response times for legitimate HTTP requests during an ongoing HTTP flooding attack while providing similar response-to-request ratios as Rate Limiting. This work makes the following contributions to the research field of QoS-based DDoS defense mechanisms: • The proposal of DDD, a new network-level DDoS defense mechanism based on the more advanced DPTB QoS model. • An implementation of DDD as an OMNeT++/INET module to perform simulations with various kinds of DDoS attacks. • Software tools to comfortably generate suitable OMNeT++ test networks, perform simulations on them, and analyze their results. • An in-depth analysis of DDD’s behavior under different network conditions and parameter choices. • A comparison of DDD to another common QoS-based DDoS defense mechanism at the defense of three common types of DDoS attacks. The rest of this thesis is structured as follows: In Chapter 2 several essential concepts used in this work are introduced. Next, in Chapter 3 existing research related to this paper’s scope is discussed. In Chapter 4, the considered system model is introduced, and the problem statement is given. In Chapter 5 we present the design of the DDD mechanism in detail and in Chapter 6 we cover the implementation of this approach in OMNeT++. Chapter 7 provides an in-depth analysis of DDD’s behavior and compares DDD to Rate Limiting. Finally, Chapter 8 summarizes the results of this work and provides an outlook for future work. 14 2 Background There are multiple technologies and concepts that are important for this work. This chapter briefly introduces them. First, the concept of a DDoS attack and various types of this attack are introduced. Then, two important Quality of Service models, namely the Token Bucket algorithm and Dynamic Priority Token Bucket (DPTB), are addressed. Finally, we briefly introduce the OMNeT++ simulation framework and the INET network component suite. 2.1 DDoS Attacks A distributed denial-of-service (DDoS) attack is the type of cyber attack addressed in this work. This section will first introduce the concept of DDoS attacks and then present three types of DDoS attacks that are considered in this work, namely UDP flooding, TCP SYN flooding, and HTTP flooding. 2.1.1 General Description A denial-of-service (DoS) attack intends to exhaust the resources of another computer (usually a server), such that the availability of this computer to legitimate users is negatively impacted. Examples of these resources include memory and disk space, limits of simultaneous connections as well as network resources (bandwidth). The exhaustion is typically created by sending large amounts of network traffic from one or multiple attacker-controlled computers to the targeted computer [ZFS17]. A distributed denial-of-service (DDoS) attack is a specific type of DoS attack where the attacker not only uses one or a few hosts to attack the server but instead uses a large number (thousands or even millions) of hosts that are often distributed over large parts of the Internet. This makes the attack harder to defend since one cannot simply block a small number of IP addresses in the server’s firewall to lock out the attackers. It is also harder to discriminate malicious hosts from legitimate ones: Each malicious host on their own may only send a small amount of malicious traffic, but the traffic from all malicious hosts combined is enough to affect the availability of the targeted server significantly [MR04]. In many cases, the malicious hosts are victims themselves: Often, they are hacked computers or IoT devices that were turned into so-called “zombies”, forming an attacker-controlled botnet. The formation of botnets has been a growing problem in recent years due to the presence of (often insecure) IoT devices. For instance, the Mirai DDoS botnet infected 600,000 hosts (mostly IoT devices) by just trying out common Telnet login credentials on devices on the Internet [AAB+17]. 15 2 Background 2.1.2 UDP Flooding In a UDP flooding DDoS attack, malicious clients send large amounts of UDP packets to the server, causing high bandwidth usage. The goal of a UDP flooding attack is not to overload the server but rather to use up the entire bandwidth of the server’s network connection so that legitimate users cannot reach it. This means that the server does not even need to have an open UDP port for this attack to work since the packets only need to arrive at the server but do not need to be processed. In fact, many UDP flooding attacks send their packets to random ports of the server, which are usually not open [ION22]. 2.1.3 TCP SYN Flooding To open a TCP connection, a so-called “Three-way handshake” is required: First, the client sends a SYN message together with its chosen sequence number 𝑥, then the server responds with a SYN+ACK message that contains 𝑥 + 1 and the server’s sequence number 𝑦. We say that the connection is now “half-open”. Finally, the client confirms the connection establishment by sending a ACK message containing the number 𝑦 + 1. The server must then check whether the number from the ACK message is actually 𝑦 +1 with the 𝑦 the server chose in the previous step. If the numbers differ, the connection must be rejected [Edd22]. The problem with this mechanism is that the server must store its chosen sequence number 𝑦 together with the client’s IP address and port number until the ACK message is received. This state is stored in a so-called “transmission control block” (TCB) inside a “SYN backlog” of limited size. If the client never sends the ACK message, the TCB must be stored indefinitely or at least until a timeout occurs. A TCP SYN flooding attack exploits this behavior: In such an attack, the malicious clients send large amounts of SYN messages to the server. For each received SYN message, the server must send a SYN+ACK message and, more importantly, create and store a TCB. The client never sends a confirming ACK message. Consequently, the server’s SYN backlog fills up until no new connections can be accepted anymore [ION23a]. On Linux systems, the number of TCBs inside the SYN backlog can be configured in the file /proc/sys/net/ipv4/tcp_max_syn_backlog [Vei14]. A look at five different Linux machines revealed that the default value varies but typically lies in the range of 128 to 4096 simultaneous half-open connections, where the value is usually higher on machines with more resources. This means that only a few TCP SYN messages are required for an effective DDoS attack. 2.1.4 HTTP Flooding While the other two attacks work on the transport layer, HTTP flooding attacks an application layer protocol. In this attack, malicious clients send large numbers of HTTP requests to the server; usually GET or POST requests. Each request forces the server to use part of its resources, for instance to generate the HTML code of a web page. If many requests are sent, this uses up all the server’s resources, making it unable to process requests from legitimate clients [ION23b]. 16 2.2 Quality of Service (QoS) Models For HTTP GET requests, there is also an amplification effect: The requests from client to server are usually small (700-800 bytes [Goo09]) while the responses are typically much larger as they contain the website’s data, e.g., images, HTML, CSS or JavaScript files. This means that a client only has to send very little data to make the server use up a significant portion of its available bandwidth. This effect can be used to congest the server’s uplink to the Internet. 2.2 Quality of Service (QoS) Models A computer network’s Quality of Service (QoS) specifies a minimum level of service that a participant of this network can expect from it. This minimum level of service is typically defined by performance-relevant metrics like bandwidth, latency, jitter, or packet loss [Dor14]. The Quality of Service is usually defined in a so-called “contract” between the participant and the network. Quality of Service Models ensure that participants adhere to their contract by applying traffic shaping or policing [Rot21]. In this section, we introduce two QoS models that are relevant for this work. First, we present the Token Bucket algorithm, and then we explain the Dynamic Priority Token Bucket QoS model. 2.2.1 Token Bucket The Token Bucket algorithm is a Quality of Service model that can be used to limit the average data rate of a sender, more formally, to ensure that a sender holds to the contract that it has with the network. For this purpose, there is an imaginary bucket that can hold up to 𝑏 tokens. For each bit the sender wants to send, one token must be removed from the bucket. The bucket is constantly refilled at a rate 𝑟 (tokens per second), but if the bucket already contains 𝑏 tokens, all excess tokens are discarded, ensuring that the bucket does not “overflow” [Aug23; TW10]. If the sender wants to send a bit while the bucket is empty, this is considered a violation of contract. In this case, the bit (or packet) is dropped, flagged as non-conforming, or held back in a queue until enough tokens are there to send the packet. The principle of operation of a Token Bucket is illustrated in Figure 2.1. In this work, we always consider the case where non-conforming traffic is dropped. A Token Bucket allows the sender to permanently send at the sustainable rate 𝑟 or lower, but temporary bursts at a higher data rate are possible for at most 𝑇max = 𝑏 𝑅 − 𝑟 seconds, where 𝑅 is the maximum egress bandwidth of the sender [Rot21]. 2.2.2 Dynamic Priority Token Bucket (DPTB) The Dynamic Priority Token Bucket (DPTB) is a Quality of Service model developed at the IPVS at the University of Stuttgart [LDR+23]. DPTB is an extension of the Token Bucket algorithm introducing multiple traffic classes with different latency guarantees. While Token Bucket-based 17 2 Background Bit 3 Bit 2 Bit 1Bit 4Bit 5 Sender bucket size b [tokens] token refill rate r [tokens/s] ... Figure 2.1: Illustration of a Token Bucket. For each transmitted bit, a token must be removed from the bucket. Source: [Aug23] = 0 Priority Classes ...... Token Bucket M ap pi ng always Severity Level "No contract violation" Severity Level Severity Level Tokens ... Figure 2.2: Visualization of DPTB. Source: [LHA+24] approaches only allow for two traffic classes - high priority for contract-conforming traffic and best effort for contract-violating traffic, DPTB can differentiate traffic into an arbitrary number of so-called priority classes. The principle of operation of DPTB is illustrated in 2.2. The lowest possible fill level in the normal Token Bucket algorithm is zero. In DPTB, however, we consider a token bucket (defined by refill rate 𝑟 and positive capacity 𝑏) that can also have arbitrary negative fill levels. Let 𝑆0, . . . , 𝑆𝑛 be so-called severity levels that determine how severely the sender violates the contract specified by 𝑟 and 𝑏. 18 2.2 Quality of Service (QoS) Models Every severity level 𝑆𝑖 is associated with a threshold 𝑇ℎ(𝑆𝑖) ≤ 0. It always is 𝑇ℎ(𝑆0) = 0 and 𝑇ℎ(𝑆𝑛) = −∞. The thresholds mark non-positive fill levels on the token bucket. If the fill level of the token bucket falls below 𝑇ℎ(𝑆𝑖), this marks a contract violation of severity 𝑆𝑖+1 [LHA+24]. It holds that for 𝑖 > 𝑗 , it is 𝑇ℎ(𝑆𝑖) > 𝑇ℎ(𝑆 𝑗), i.e., the larger 𝑖, the more severe the contract violation. If for the current level 𝑙 it is 𝑙 ≥ 0 = 𝑇ℎ(𝑆0), the contract is not violated, whereas in all other cases, a violation is present. Every severity level 𝑆𝑖 is mapped to a priority class 𝐶 𝑗 by the mapping 𝐶𝑙𝑎𝑠𝑠 : 𝑆 → 𝐶. Each priority class has different QoS guarantees. There is a special “best effort” class 𝐶𝐵𝐸 , which has no guarantees at all and only uses the bandwidth left over by all other priority classes. The highest severity level is always mapped to this class, i.e., 𝐶𝑙𝑎𝑠𝑠(𝑆𝑛) = 𝐶𝐵𝐸 . Every priority class 𝐶 𝑗 is associated with a cost value through the mapping 𝐶𝑜𝑠𝑡 (𝐶 𝑗). This is the cost of sending one bit in this priority class. When the sender sends a packet of size 𝑞 bits in priority class 𝐶 𝑗 , the value 𝑞 ·𝐶𝑜𝑠𝑡 (𝐶 𝑗) is deducted from the level of the token bucket. This makes the cost of one bit dynamic, such that sending data in priority classes with worse QoS guarantees costs fewer tokens. For 𝐶𝐵𝐸 , it is 𝐶𝑜𝑠𝑡 (𝐶𝐵𝐸) = 0 to ensure that the bucket level does not fall any lower. In total, we have the following mapping chain: Fill Level → Threshold → Severity Level → Priority Class → Cost Value Now, when a packet of size 𝑞 is to be sent, the following steps are performed [Aug23]: 1. Determine the severity level: 𝑆𝑖 , 𝑖 := min{ 𝑗 | 𝑙 − 𝐶𝑜𝑠𝑡 (𝐶𝑙𝑎𝑠𝑠(𝑆𝑖)) · 𝑞 ≥ 𝑇ℎ(𝑆𝑖), 0 ≤ 𝑗 ≤ 𝑛} i.e., for every severity level, we calculate the theoretical fill level after the packet has been sent with the priority class associated with this severity level. We then select the lowest severity level 𝑆𝑖 for which the new fill level of the bucket would still be above 𝑇ℎ(𝑆𝑖). 2. Update the bucket level: 𝑙 := 𝑙 − 𝑞 · 𝐶𝑜𝑠𝑡 (𝐶𝑙𝑎𝑠𝑠(𝑆𝑖)) 3. Send the packet with priority 𝐶𝑙𝑎𝑠𝑠(𝑆𝑖). Each priority class 𝐶 𝑗 has a separate queue 𝑄 𝑗 where all packets sent with this priority are buffered. Strict priority queueing is then used to select the next packet to send: The scheduler always takes a packet from the highest-priority queue 𝑄𝑘 that is non-empty: 𝑄𝑘 , 𝑘 := min{ 𝑗 |𝑄 𝑗 is non-empty, 0 ≤ 𝑗 ≤ 𝑚} This way, if a packet from the highest priority is ready to send, it gets sent immediately. In contrast, packets from the second-highest priority can only be sent when there are no packets in the highest-priority queue, and so forth. 19 2 Background 2.3 OMNeT++ and INET OMNeT++ and INET form the base of the implementation of this thesis. In this section, we will first introduce the simulation framework OMNeT++ and then look at the network component library INET. 2.3.1 OMNeT++ OMNeT++ [Ope24a] is an event-based simulation framework primarily targeted towards network simulation. It is written in C++, and since its code is publicly available, it can be extended by modifying the source code. The central idea of OMNeT++ is that complex components can be constructed from simpler components hierarchically. To specify modules, their parameters, and the connections between them, OMNeT++ has a domain-specific description language called “NED”, short for “network description”. Networks in OMNeT++ can be built from three basic types of components [Ope24b]: • Simple Module: Simple modules form atomic components that cannot be subdivided further. They are defined by a C++ class extending cModule and a NED file. The C++ class defines the behavior of the module. Most importantly, two methods must be overridden: initialize() and handleMessage(cMessage *msg). initialize is called during the initialization phase of the network. All code that should be executed at the beginning of the simulation, e.g., initializing variables, should be part of this method. handleMessage is called whenever the module receives a message. The module should then process the message accordingly. Messages can be sent by other modules through a channel. The NED file makes the simple module available to the OMNeT++ ecosystem and also specifies which parameters the module requires and what statistics it exposes. • Compound Module: Compound Modules combine multiple submodules (simple or com- pound modules) into more complex ones. This can be done hierarchically, i.e., a compound module might contain another compound module that contains simple modules. The modules inside a compound module are interconnected using channels (see below). A compound module consists of only a NED file but not a C++ class since compound modules themselves do not implement any logic. The NED file specifies which submodules it contains and how these submodules are connected to each other. • Channel: Channels are used to connect modules (simple modules or compound modules) to each other. Similarly to simple modules, their behavior is specified in a C++ class extending cChannel. A NED file is required to add the channel to the OMNeT++ ecosystem and to declare the parameters of the channel. A network can be defined with a NED file, similar to a compound module. The NED file specifies the modules that the network consists of as well as the connections between the modules. A separate INI file can be used to configure the properties of a network and its modules. It can also be used to configure simulation-specific parameters, like the simulation duration. In this work, we always use OMNeT++ version 6.0.3. 20 2.3 OMNeT++ and INET 2.3.2 INET OMNeT++ itself does not provide any network components like hosts, routers, and switches. However, INET [And23] is a library that integrates with OMNeT++ and provides components for all sorts of network applications. All these components are implemented as compound modules and channels. The most important components for this work are the following: • The StandardHost is an implementation of a host in an Ethernet network. It implements an entire network stack, including TCP/IP and UDP/IP. It is possible to run one or multiple applications on the host. These can be implemented as simple modules that implement the IApp interface. There are also readily available applications for common use cases, e.g., IpApp for sending/receiving IP packets or TCPTrafficGeneratorApp for sending data through TCP connections. • The Router implements an IP router stack. Multiple Ethernet interfaces can be defined to create multiple ports on the router. • The EthernetLink component implements an Ethernet connection between two Ethernet- capable components (e.g., a StandardHost and a Router). Multiple subtypes for different bandwidths are available, e.g., Eth100M for 100 Mbit/s and Eth1G for 1 GBit/s connections. Important for this work is the packet queueing inside the Router component. This happens in the EthernetInterface modules in the routers. The EthernetInterface is a compound module consisting of an EthernetMac module and a module extending the IPacketQueue interface. The latter is used as the egress queueing mechanism. The queueing module receives the outgoing packets for its parent interface, buffers them, and forwards them to the EthernetMac as soon as it is done sending the previous packet. By default, the EthernetQueue module is used for the packet queue. This module implements a basic FIFO queue. However, it is possible to replace the EthernetQueue with another module implementing the IPacketQueue interface by changing the Router module’s configuration. This can be used to implement custom queueing mechanisms inside the routers. In this work, we always use INET version 4.5.2. 21 3 Related Work In this chapter, we discuss multiple related studies that also focus on network-level DDoS protection using Quality of Service methods. We begin with Apiecionek et al.’s history-based DDoS classification approach. Next, we look at two defense mechanisms for OpenFlow networks by Oktian et al. and Buragohain et al. Then, we introduce Kirdan et al.’s approach, which uses Rate Limiting on the subnet level to counteract DDoS attacks. Finally, Zhang et al.’s confidence-based DDoS detection and defense mechanism is discussed. 3.1 Apiecionek et al.: History-Based DDoS Detection and Blocking Apiecionek et al. [ACD14] propose a DDoS defense mechanism based on Quality of Service methods. It is assumed that a router processes multiple data streams. At the ingress of a router, all incoming packets are processed using fair packet queueing. This ensures that the bandwidth is shared equally among the streams. Additionally, all packets are registered in a history. The history is a rotating log of all incoming packets, limited to a specific time window. In normal operation, packets go directly from the fair queue’s output to the router’s egress port. However, when the number of active streams increases beyond a certain threshold, the router assumes that a DDoS attack is present. In this case, each packet is classified by a recognition module. Packets classified as DDoS are dropped using a modified Random Early Detection (RED) mechanism, while non-malicious packets are forwarded to the egress port. The recognition module uses the history as a source of truth for how traffic looked before the DDoS attack. If a packet does not match the traffic patterns from the history, it is classified as malicious. An exception is packets from streams established before the start of the DDoS attack: These packets are automatically flagged as non-malicious. The authors argue that this method effectively protects ongoing sessions from an upcoming DDoS attack. However, they argue that for longer-lasting attacks, the approach faces the issue that malicious traffic becomes dominant in the history, causing the recognition module to classify malicious traffic as non-malicious. 3.2 Oktian et al.: DoS Protection in OpenFlow Networks Oktian et al. present “Dossy” [OLL14], a mechanism supposed to defeat various kinds of DoS and spoofing attacks in OpenFlow networks. The mechanism incorporates two different defense strategies: Blocking and Quality of Service. 23 3 Related Work Blocking means that maliciously behaving network participants are completely blocked, i.e., all their packets are dropped. It is used to defeat spoofing attacks, particularly MAC address and IP address spoofing. Also, so-called garbage message attacks are mitigated with this method. In a garbage message attack, a malicious sender sends useless packets to other nodes, initiating new flows. This forces the OpenFlow controller to create many flow entries. These flow entries fill up the flow table of the network switches so that no new flows can be accepted anymore, effectively leading to a denial of service. Quality of Service is used to counteract data flooding (“Bulky Message”) attacks, where a node sends a large amount of data to another node. According to the authors, blocking is not suitable here as it is difficult to differentiate legitimate high-data-rate traffic from a flooding attack. Instead, if a stream’s bandwidth usage exceeds a threshold, it gets limited to a significantly lower bandwidth. This concept is also known as Rate Limiting. 3.3 Buragohain et al.: SDN-Based DDoS Mitigation Buragohain et al. propose “FlowTrApp” [BM16], a DDoS defense method for data centers based on software-defined networking. This system uses OpenFlow controllers to classify traffic flows based on two metrics: Flow rate (data rate of the flow) and flow duration (how long the flow persists). The authors define lower and upper bounds on both of these metrics to discriminate malicious flows from legitimate ones. Violations of these bounds are then sorted into five different categories: High-rate spikes, Short-lived High Rate, Long-lived High Rate, Idle User, and Long-lived Low Rate. Each flow has a malCounter variable that is initialized to zero. Every time a flow violates the bounds of the flow rate or flow duration, the malCounter is incremented by one, and the egress flow rate of the stream gets decreased to the lower bound flow_ratemin as a punishment. When the counter exceeds a certain threshold, the flow gets blocked for a certain amount of time. The authors evaluated the performance of FlowTrApp using the Mininet [Min21] network emulator. It was found that FlowTrApp could successfully defeat UDP flooding attacks. The authors also compared the approach to the mechanism presented by Oktian et al. [OLL14] (see Section 3.2) with regard to TCP flooding attacks. They found that FlowTrApp let pass an average of 2500 malicious packets per second while the approach by Oktian et al. allowed more than 5000 malicious packets per second, meaning that FlowTrApp performed significantly better. 3.4 Kirdan et al.: Rate Limiting on the Subnet Level Kirdan et al. [KREC18] from the Technical University of Munich propose “MoonPol”, a traffic policer for DDoS mitigation. This approach can be summarized as “Rate Limiting on the subnet level”: The authors assume a network with multiple subnets, such as the Internet. Each subnet of the network has a contract with the router, specified by the token refill rate 𝑟 and the bucket capacity 𝑏 of a Token Bucket (see Section 2.2.1 for details). The units for 𝑟 and 𝑏 are packets per second and packets, i.e., the size of the packets is not considered in this approach but only their count. The router maintains the state of this token bucket for each subnet. Whenever a packet arrives at the 24 3.5 Zhang et al.: Dynamic DDoS Defense Using Confidence Value router, the subnet ID of its sender is determined, and a token is deducted from the token bucket belonging to this subnet ID. When no tokens are left in the bucket, the packet gets dropped without an error message. For performance reasons, the bucket is not refilled before each processed packet but only after every 𝑛 packets. As large values for 𝑛 can result in a square-shaped egress data rate, a trade-off exists between good performance and a well-shaped data rate. The authors found that 1 million is an optimal choice for 𝑛. 3.5 Zhang et al.: Dynamic DDoS Defense Using Confidence Value Zhang et al. [ZP06] propose a DDoS defense mechanism that is distributed among multiple routers of a network. Each router observes the network traffic on its own to detect malicious behavior. A variety of indicators, like high data rates, sudden changes in ICMP or UDP packet prevalence, or a lack of symmetry in TCP traffic, are used to detect potential DDoS attacks. The routers also use a so-called “gossip-based communication mechanism”: When a router detects malicious behavior, it informs neighboring routers about it through a peer-to-peer network. For each sender, a confidence value 𝑐 is calculated, indicating how likely it is that the sender is malicious. A value of zero means that the sender is legitimate, and one means that the sender is definitely malicious. Depending on the confidence value a different amount of Rate Limiting is applied to the traffic of a sender. To be more specific, the outgoing data rate is limited to rateout = ratein · 𝜆(𝑐) where 𝜆 is a function that produces high values for 𝑐 close to zero and low values for 𝑐 close to one. Thus, a sender that is more likely to be malicious gets a stricter rate limit. 3.6 Differences to This Work As discussed in the previous sections, there are several DDoS protection methods for the network and transport layers that rely on Quality of Service methods. However, the discussed related papers all focus on relatively simple Quality of Service mechanisms like Token Buckets [KREC18] or Random Early Detection [ACD14]. In contrast, this thesis proposes a DDoS defense mechanism based on the Dynamic Priority Token Bucket, a more advanced QoS model. The suitability of DPTB for DDoS protection has never been investigated before. Most network-level DDoS defense methods either only use blocking of senders [ACD14] or Rate Limiting [KREC18; OLL14; ZP06]. In opposition, this thesis presents a hybrid approach that first reduces the priority of potentially malicious senders and later blocks them completely when the malicious behavior is long-lasting or more severe. All papers discussed above only consider the upstream traffic from client to server (except [ZP06], which looks at the upstream-downstream symmetry in TCP connections). While this may be suitable for upstream-heavy attacks like UDP flooding, it is problematic in attacks like HTTP flooding where only a low load is put on the upstream, but the responses sent by the server cause congestion in the downstream. Meanwhile, the defense method proposed in this paper also considers the downstream traffic to detect malicious behavior. 25 3 Related Work We noticed that many studies on network-level DDoS protection only consider the case where all routers in the network support the proposed defense mechanism. In contrast, this study assesses how the prevalence of the defense method on the routers influences the effectiveness of DDoS protection. We also evaluate how the number and distribution of malicious clients in the network influence the performance of the defense mechanism. 26 4 System Model and Problem Statement This section will first introduce the system model we consider in this work. Then, the problem statement of this thesis will be formulated. 4.1 System Model This section introduces the system model that we assume in this work. Generally speaking, we assume that one server and multiple clients are connected to a computer network consisting of links and routers. The clients communicate with the server, e.g., by uploading data or browsing web pages. Clients can be separated into two homogeneous groups: Good/legitimate clients are hosts accessing the web server for valid reasons. Bad/malicious clients, on the other hand, are attacker-controlled bots that perform a DDoS attack on the server. This network structure will be described more thoroughly in the following. Afterward, we introduce a model for the internal structure of a router as we consider it in this work. Finally, we state the types of DDoS attacks considered in this work. 4.1.1 Considered Network Structure This work considers a tree-shaped network structure with the target server at the tree’s root. The inner nodes of the tree are routers, and the leaf nodes are clients accessing the server. The edges are network links. The network can be specified by three parameters: • 𝑘: Number of router layers • ℓ: Number of direct sub-routers per router • 𝑚: Number of clients per router in the lowest router layer A visualization of such a network can be seen in Figure 4.1. We can calculate the total numbers of clients and routers in the network using the following formulas: # Clients = ℓ𝑘−1 · 𝑚 # Routers = 𝑘−1∑︁ 𝑖=0 ℓ𝑖 Each router can either be a smart router or a normal router. Smart routers implement a DDoS defense mechanism. Normal routers have a simple FIFO queue at each of their network interfaces and, therefore, treat all packets equally. The presence of normal routers represents the fact that large networks are usually not under the control of a single party, but different parties control different 27 4 System Model and Problem Statement Server C R RR R R RR R RR C C C C C... ... C C C C C C... ... ... ... ... ... ... ... Router Layers R R C CNormal Router Smart Router Good Client Bad Client Figure 4.1: The network structure considered in this work. The distribution of smart routers and bad clients is only an example. parts of the network (e.g., autonomous systems (AS) in the Internet [HB96]). Some parties might implement DDoS defense mechanisms in their subnet while other parties might not, i.e., their routers are normal routers. Each client can be either a good or a malicious client. Good clients are legitimate users who have no intention of attacking the server or network. Meanwhile, malicious clients perform a DDoS attack on the server. The malicious clients are also connected to an attacker-controlled server (C2 server, command & control server) that instructs clients on how to behave. As this work does not focus on C2 servers, we will ignore their presence in the rest of this paper. 4.1.2 Considered Internal Router Structure This section introduces the internal structure of the routers considered in the network described in Section 4.1.1. This internal structure is visualized in Figure 4.2. A router consists of 𝑛 + 1 ∈ {ℓ + 1, 𝑚 + 1} Ethernet interfaces, of which eth0 points towards the web server and all other interfaces point towards the clients. Additionally, there is a central routing component to which all interfaces are connected. Each interface has an ingress port for incoming traffic and an egress port for outgoing traffic. The ingress port is directly connected to the routing component, while the egress port is more complex: Inside the interface component, there is a queuing component implementing a queueing algorithm that buffers packets and decides on the next packet that should be forwarded to the egress port. Now, when a packet arrives at one of the router’s ingress ports, it is forwarded to the routing algorithm. The routing algorithm decides which interface the packet should be sent to and forwards the packet accordingly. The queueing component of the outgoing interface then processes the packet. What happens inside the queueing component is specific to the implementation. However, in general, the packet gets buffered in a queue and is transmitted through the egress port as soon as there are no other packets enqueued that must be transmitted first. The queueing component is also allowed to discard packets instead of forwarding them. 28 4.1 System Model Routing Algorithm eth 1 egress ingress Queueing eth 2 egress ingress Queueing eth n egress ingress Queueing eth 0 egress ingress Queueing Router ... Server Direction Client Direction Figure 4.2: The internal structure of the routers considered in this work. The queueing component can be used to implement various DDoS defense mechanisms by prioritizing or dropping packets based on a set of rules and algorithms. For normal routers, we always use first-in, first-out queuing (FIFO) while smart routers implement a more sophisticated queueing algorithm (c.f. Chapter 5). As packet routing is outside of the scope of this work, we assume that the routing algorithm always chooses the optimal route to the destination of a packet. This is trivial for the considered tree-shaped network structure (c.f. Section 4.1.1) since there always exists exactly one path from an arbitrary router to an arbitrary host. 4.1.3 Considered Types of DDoS Attacks There are many types of DDoS attacks, and not all are covered by the approach presented in this work. In this paper, we assume that only the following three attack types can be performed by malicious clients: 29 4 System Model and Problem Statement • UDP Flooding • TCP SYN Flooding • HTTP Flooding A detailed description of these attack types can be found in Section 2.1. 4.2 Problem Statement This section presents the problem statement that this work will tackle. Many existing DDoS mitigation approaches run on the server endpoint and do not make use of the routers in the network to fight DDoS attacks closer to their origin. While network-level DDoS defense approaches exist, most of them use relatively simple methods like Rate Limiting [ACD14; KREC18; OLL14]. This work aims to design a new DDoS defense mechanism that is based on dynamic Quality of Service models. This defense mechanism should be able to protect a server from common DDoS attacks on the network and transport layer. Especially, an effective protection from UDP flooding, TCP SYN flooding, and HTTP flooding should be provided. This mechanism should not operate on the server’s network endpoint but instead run on the routers inside the network, such that malicious traffic is blocked as close to a malicious sender as possible. The approach should be designed so that full coverage of all routers in the network is not necessary to achieve effective DDoS protection, as this eases adoption in global networks. It should not be possible to abuse the defense mechanism itself for DDoS attacks, e.g., by sending spoofed IP packets in the name of other legitimate hosts to lock them out of the network. The mechanism should be implemented in a suitable network simulation environment under consideration of the network and router structure described in Section 4.1. The effectiveness of the defense mechanism should be compared to existing approaches using appropriate metrics. For the evaluation the simulation environment should be used. 30 5 Design This chapter explains the design of the DPTB DDoS Defense mechanism, short DDD, that forms the main contribution of this work. In the following, we will first introduce the general approach of DDD, then discuss two variants for handling downstream traffic, and discuss an additional TCP SYN flood protection. Afterward, we discuss three features to protect DDD against IP spoofing, and finally, we propose a method to choose parameters for DDD. 5.1 General Approach DDD is a realization of the queueing module of a network interface in the router, as introduced in Section 4.1.2. This means that DDD receives all packets that should be sent through the interface, buffers them, and sends them in a specific order or discards them. The details of this process will be explained in this section. DDD internally uses a slightly modified version of the DPTB algorithm, as introduced in Section 2.2.2. There is a separate DPTB bucket for every client IP address that regulates the traffic of this single client. There is no connection between the DPTBs of different clients, which eases parallel computation inside the router. We consider a DPTB with three severity levels 𝑆0, 𝑆1 and 𝑆2 corresponding to three priority classes 𝐶0, 𝐶1 and 𝐶2. The severity levels have the following meaning in the context of DDD: • 𝑆0: no DDoS attacker • 𝑆1: potential DDoS attacker / low-volume DDoS attacker • 𝑆2: definitive DDoS attacker Thus, the DPTB is used to classify the packets into the categories no DDoS attacker, potential DDoS attacker and definitive DDoS attacker. The priority classes handle the packets as follows: • 𝐶0 = 𝐶𝑙𝑎𝑠𝑠(𝑆0): Enqueue packet into highest-priority queue 𝑄0. • 𝐶1 = 𝐶𝑙𝑎𝑠𝑠(𝑆1): Enqueue packet into second-highest-priority queue 𝑄1. • 𝐶2 = 𝐶𝑙𝑎𝑠𝑠(𝑆2): Drop packet. Strict priority queueing is then used to schedule the packets from the queues 𝑄0 and 𝑄1: Whenever there are packets in 𝑄0 (highest priority), they are sent immediately in FIFO order. Packets from 𝑄1 are only sent when there is no packet in 𝑄0. See Figure 5.1 for an illustration of this process. 31 5 Design DPTB Priority Queue Priority Queue Priority : Drop Packet Strict Priority Scheduling: Incoming Packet Queueing Component of DDD Smart Router Egress Port Figure 5.1: Packet processing in the queuing component of a network interface in a DDD smart router This construct ensures that traffic classified as non-DDoS always gets scheduled at the highest priority, while DDoS-classified traffic gets blocked. We introduce the intermediate priority class 𝐶1 since the boundaries between DDoS traffic and legitimate traffic can be fluid, i.e., there are low-volume DDoS attacks and legitimate power users. A difference to the original DPTB design as described in Section 2.2.2 is that the highest severity level 𝑆2 does not map to a “best effort” traffic class but instead indicates a packet drop. This decision was made to block DDoS-classified traffic completely, even when excess bandwidth is available at the router’s egress port. This is especially important for DDoS attack types that cause only moderate upstream network loads but significantly increase computational effort and/or resource usage on the server, e.g., HTTP flooding. For HTTP flooding, the malicious clients send HTTP requests at a high frequency to force the server to generate a lot of HTTP responses. As HTTP requests are usually quite small [Goo09], they do not put a significant load on the upstream link of the network and, thus, do not cause an overload at the routers. If 𝑆2 would map to a “best effort” traffic class, DDoS-classified HTTP requests would still reach the server because “best effort” means that the packets are always sent when there is more bandwidth available at the router than required by the other priority classes. However, to defend against this attack, it must be ensured that the HTTP request messages do not reach the server, even when the network routers are not overloaded. This is achieved by dropping all packets of a client as soon as it reaches the severity level 𝑆2. We decided that for 𝐶1, the cost of sending one bit should be lower than for 𝐶0 so that legitimate power users have the option to send at a higher data rate than 𝑟 at the expense of a reduction in priority to 𝐶1. It is important that 𝐶𝑜𝑠𝑡 (𝐶2) is greater than zero to ensure that truly malicious clients stay in the worst priority class. If it were 𝐶𝑜𝑠𝑡 (𝐶2) = 0, malicious clients would oscillate between 𝑆1 and 𝑆2, preventing their traffic from being blocked completely. Details about the choice of the cost and threshold parameters can be found in Section 5.5.1. 32 5.2 Bidirectional DDD and Downstream Reporting 5.2 Bidirectional DDD and Downstream Reporting In real-world systems, there is usually not only upstream traffic from a client to the server but also downstream traffic in the reverse direction. In many cases, the downstream traffic significantly impacts the network and server load, making it relevant for DDoS detection. For instance, in an HTTP flooding attack, a malicious client sends a large number of HTTP requests to a web server, forcing the server to send a large number of HTTP responses. While HTTP requests are relatively small (typically 700-800 bytes [Goo09]), the corresponding HTTP responses are much larger: In 2022, the median web page size was 2.02 MByte, and the median number of requests per page load was 76, yielding an estimate of 26.5 kByte per HTTP response [HTT22]. To account for this downstream traffic in DDD, we present two different strategies, namely Bidirectional DDD and Downstream Reporting. Both methods will be introduced in the following. 5.2.1 Bidirectional DDD (DDD-B) With Bidirectional DDD, all network interfaces of the router implement DDD as their queueing mechanism. However, the interfaces do not have separate DPTB buckets; instead, they share one bucket per source IP address. This means that when one interface of the router deducts tokens from the bucket to send a packet, this also influences all other interfaces of the same router. Most importantly, this ensures that downstream traffic from the server to a client influences the regulation of the client’s upstream traffic: If a client receives much traffic (HTTP responses) from the server, this reduces the fill level of the shared bucket and thus, leads to a decrease in priority to 𝐶2. As this bucket is shared with the egress interface towards the server, upstream traffic from the same client also gets assigned priority 𝐶2, leading to the upstream packets (HTTP requests) being dropped. 5.2.2 Downstream Reporting (DDD-DR) Downstream Reporting is an improved version of Bidirectional DDD with regard to HTTP flooding. One problem with Bidirectional DDD is that it interferes with TCP’s congestion control algorithm [Edd22]: When a participant of a TCP connection detects that some of its packets are getting lost in the network (i.e., ACK confirmation messages are missing), it assumes that the network is overloaded. To reduce the load on the network, the participant’s TCP engine then reduces its transmission data rate. Now assume that a malicious client performs an HTTP flooding attack on a server in a network that uses DDD-B. The attack forces the server to send many HTTP responses back to this client. Due to the high data rate, the shared bucket in the router gets depleted until severity level 𝑆2 is reached. This causes the downstream packets to be dropped. As a result, the congestion control mechanism in the server’s TCP engine reduces its data rate. As the data rate is lower now, the shared bucket in the router fills up again, such that severity levels 𝑆1 or even 𝑆0 are reached. In their corresponding priority classes 𝐶1 and 𝐶0, no packet dropping occurs. This motivates the TCP congestion control to increase the data rate again. From here, the described process repeats. A visualization of this cycle can be seen in Figure 5.2. This cycle prevents HTTP flooding attackers from being blocked permanently, making the DDoS defense less effective. 33 5 Design High Downstream Traffic Priority reduced to packet drop Server reduces TCP data rate Priority increased to or no packet drop Server increases TCP data rate Figure 5.2: Bidirectional DDD interfering with TCP’s congestion control mechanism. The main cause of this issue is that DDD-B blocks not only upstream traffic but also downstream traffic coming from the server. Intuitively, this also doesn’t make much sense since we do not want to punish the server for sending HTTP responses but the client that requested these responses. Instead, we need a mechanism that takes downstream traffic into account but punishes the client, not the server, for it. An approach that implements this idea is Downstream Reporting for DDD. With this approach, only the server-facing network interface of a router (upstream) implements DDD, while all client-facing interfaces (downstream) implement simple FIFO queueing. However, whenever one of the client- facing interfaces processes a downstream packet, it reports this packet to the server-facing DDD interface. The DDD interface then deducts tokens from its internal DPTB bucket as if this packet were an upstream packet from the client. With this approach, downstream traffic is never dropped (except if the router is overloaded), which prevents the server’s TCP engine from reducing the downstream data rate. Thus, the cycle from DDD-B cannot occur here. Meanwhile, the client’s upstream is punished for the downstream traffic it indirectly caused. 5.3 TCP SYN Flooding Protection TCP SYN flooding attacks occur when a malicious client sends a large number of TCP SYN packets. This creates many half-open TCP connections at the server (see Section 2.1.3 for details). This attack type is different from UDP or HTTP flooding because it creates only very little load on the network but still significantly impacts the server’s performance. TCP SYN packets are small (60 to 100 bytes, as our own research has shown) and, thus, cannot deplete DDD’s normal bucket under a realistic DDD configuration. To resolve this issue, we introduce a separate DPTB bucket for TCP SYN packets. In total, DDD contains two DPTB buckets - one for TCP SYN packets and one for all other sorts of traffic. The TCP SYN bucket has the same parameters 𝑟, 𝑏 as the normal bucket; however, the TCP SYN packets are not accounted for by their actual packet size 𝑞 but instead with a size-independent weight 𝑤SYN: 𝑤SYN = 𝑓SYN · 𝑟 where 𝑓SYN ∈ R≥0 is a parameter that determines how many SYN packets a client can send per second without dropping into a higher severity level. For instance, 𝑓SYN = 0.5 means the client can sustainably send 1/0.5 = 2 SYN packets per second. A detailed visualization of the DDD queuing module with its two buckets is shown in Figure 5.3. 34 5.4 Preventing IP Spoofing Attacks DPTB SYN Priority Queue Priority Queue Priority : Drop Packet Strict Priority Scheduling: Incoming Packet Queueing Component of DDD Smart Router Egress PortDPTB normal no yes TCP SYN Packet? DPTB Figure 5.3: More detailed view of the DDD queueing component with the two DPTB buckets. 5.4 Preventing IP Spoofing Attacks This section deals with the issue of IP spoofing attacks and what countermeasures DDD implements against them. If no countermeasures were in place, a malicious actor could abuse the DDoS defense mechanism to “lock out” legitimate clients from the network. This can be achieved by either of the following options: 1. UDP Spoofing: The malicious client sends a lot of UDP traffic to the server with a spoofed source IP address. This causes the DPTB buckets associated with the spoofed address to be depleted quickly, decreasing the priority to 𝐶2. This means that all packets the legitimate client sends are dropped, effectively locking out the client out of the network until the attacker has stopped sending spoofed packets and the fill levels of the buckets have recovered. 2. TCP SYN Spoofing: Similar to UDP Spoofing, but the attacker sends a large number of TCP SYN Packets with a spoofed source IP address to the server. This causes the DPTB bucket of the TCP SYN flooding protection to be depleted, which again results in a decrease in priority to 𝐶2, causing all TCP SYN packets from the legitimate sender to be dropped. Note that spoofing HTTP requests is impossible since HTTP typically builds on top of TCP [NFB96], and establishing a TCP connection involves a three-way handshake [Edd22]. Such a handshake is only possible when the attacker knows the sequence number the server chose for this connection. However, since the sequence number is sent to the legitimate client due to the source address being spoofed, the attacker never gets hands on the sequence number and can, therefore, not send a valid ACK message to establish the connection. As a protection against IP spoofing attacks, DDD implements the following countermeasures: 1. IP Subnet Checking: Every router keeps a list of all IP subnets of the clients this router serves together with the interface number at which this subnet is attached (directly or indirectly). Then, for every incoming packet, the router checks whether the source address is part of a subnet that the router serves through the interface the packet arrived through. If this is not the case, the router considers the source IP as spoofed and drops the packet. This prevents attackers from spoofing IP addresses from another subnet as long as the attacker’s and victim’s subnet are served through different ports at at least one router on the path from sender to receiver. 35 5 Design Maintaining a list of all subnets and their corresponding interface ports might seem like a considerable overhead. However, routers usually already have this information because they need it for packet routing. For instance, routers between autonomous systems (AS) in the Internet use the BGP protocol to exchange available routes to other ASes [RHL06]. The list of subnets and corresponding ports can then be constructed from the routes by looking at the port to which the next hop of the route is attached. 2. Separate bucket for TCP SYN packets: As described in Section 5.3, there are two buckets per source IP address: A bucket for TCP SYN packets and a bucket for all other traffic. This is intentional: If there was only a shared bucket for all sorts of packets, an attacker could perform a TCP SYN spoofing attack to deplete this shared bucket. This would mean that the priority of all packets from the victim’s IP address would be blocked, including the packets of already established TCP connections. However, with two separate buckets, a TCP SYN spoofing attack only depletes the bucket for SYN packets, leaving the bucket for all other packets filled. This means that already-established TCP connections and UDP traffic are not affected at all by this type of attack. The victim is only blocked from creating new TCP connections. This is a significant improvement for applications using long-lasting connections, such as videoconferencing, large downloads, or audio streaming. 3. Cryptographic Signatures (Optional): The two other approaches do not offer complete spoofing protection since, e.g., UDP spoofing from an attacker in the same subnet as the victim client is still possible. To achieve complete protection, cryptographically signed IP packets can be used. We require every IP packet to be signed by the genuine owner of the packet’s source IP address. Every router then verifies the signature of each incoming packet and drops all packets with a missing or invalid signature. This can be implemented with TrueIP [SSF09], a cryptographic IP spoofing prevention system developed at the University of Marburg. TrueIP uses the IP address itself as a public key and generates a corresponding private key that only the owner of this IP address possesses. For every packet, the UTC timestamp at which the packet is sent gets hashed and signed by the private key. The certificate is then included in the IP packet together with the timestamp. Routers can then verify the signature of the timestamp. The packets get dropped if the signature is invalid or the timestamp is older than a specific validity period. As such a protocol is challenging to implement in established large networks like the Internet, we declare this countermeasure optional. 5.5 Choosing Parameters for DDD DDD requires the following parameters: Refill rate 𝑟, bucket capacity 𝑏, and TCP SYN weight factor 𝑓SYN, as well as costs and thresholds for the priority classes of DPTB. This section discusses how values for these parameters should be chosen. First, the costs and thresholds are covered, and then the factors 𝑓𝑟 and 𝑓𝑏 determining 𝑟 and 𝑏 are defined. 36 5.5 Choosing Parameters for DDD 5.5.1 Costs and Thresholds For DDD, we define fixed costs and thresholds of DPTB based on the positive bucket capacity 𝑏: 𝑇ℎ(𝑆0) = 0, 𝑇ℎ(𝑆1) = −𝑏, 𝑇ℎ(𝑆2) = −∞ 𝐶𝑜𝑠𝑡 (𝐶0) = 1, 𝐶𝑜𝑠𝑡 (𝐶1) = 0.5, 𝐶𝑜𝑠𝑡 (𝐶2) = 0.5 𝑇ℎ(𝑆0) = 0 and 𝑇ℎ(𝑆2) = −∞ are given by the definition of DPTB [LDR+23]. We select 𝑇ℎ(𝑆1) = −𝑏 such that the severity levels 𝑆0 and 𝑆1 have the same burst size. We set 𝐶𝑜𝑠𝑡 (𝐶1) to half the cost of 𝐶0 to give legitimate power users the option to send at twice the data rate 𝑟 at the expense of a reduction in priority. 𝐶𝑜𝑠𝑡 (𝐶2) is also set to 0.5 to ensure that the cost per bit does not decrease for clients classified as a “definitive DDoS attacker”. This way, clients are guaranteed to stay in severity level 𝑆2 until they reduce their bandwidth usage. 5.5.2 Parameters 𝑓𝑟 and 𝑓𝑏 The token bucket inside DPTB requires a refill rate 𝑟 and a bucket capacity 𝑏. As can be seen in the previous section, 𝑏 is also used to define the thresholds of DPTB. Thus, selecting good values for 𝑟 and 𝑏 is important. In this section, we define a standardized way to select the token bucket parameters 𝑟 and 𝑏 based on two factors 𝑓𝑟 , 𝑓𝑏 ∈ R>0 and the per-client bandwidth of the router. The per-client bandwidth is defined as the upstream bandwidth of the router divided by the number of clients directly or indirectly attached to the router (considering a tree network structure as shown in Figure 4.1). The refill rate 𝑟 and bucket size 𝑏 are calculated as follows: 𝑟 = 𝑓𝑟 · Upstream Bandwidth # Clients of Router 𝑏 = 𝑓𝑏 · 𝑟 Here, the factor 𝑓𝑟 determines what part of the per-client bandwidth should be granted to the sender. Note that for DDD, a value 𝑓𝑟 ∈ [0.5, 1.0) does not necessarily mean that bandwidth is wasted since the cost in the middle priority class 𝐶1 is 0.5, meaning that the sender can send at rate 2𝑟 without the fill level of the bucket getting reduced any further. Values 𝑓𝑟 ≥ 1 are optimistic since this allows clients to continuously use more bandwidth than the per-client bandwidth in the highest priority 𝐶0. This can only work if not all clients send at rate 𝑟 simultaneously, as otherwise, congestion would occur at the router’s egress port. The factor 𝑓𝑏 determines how long the sender can send at rate 2𝑟 in the highest priority until the bucket level falls below zero. For instance, if 𝑓𝑏 = 3, the sender can send at rate 2𝑟 for 3 seconds until bucket level zero is reached, leading to a decrease in priority. As can be seen, these formulas automatically incorporate the per-client bandwidth into 𝑟 and 𝑏. The advantage of this definition is that all parameters that need to be chosen manually ( 𝑓𝑟 , 𝑓𝑏) are independent of the router. Thus, the specific network structure does not have to be considered when choosing 𝑓𝑟 and 𝑓𝑏. 37 6 Implementation In this chapter, we take an in-depth look into the implementation that forms a major contribution of this thesis. The implementation serves the purpose of simulating networks incorporating different DDoS defense mechanisms. The goal is to analyze the behavior of DDD and compare its performance to that of existing DDoS defense methods, particularly Rate Limiting. The implementation is built on top of the OMNeT++ simulation framework and makes heavy use of the INET network component suite. In the following, we first give an introduction to statistics collection in OMNeT++. Then, we explain how custom packet queueing algorithms can be implemented in INET routers. Next, we talk about the implementation of the Rate Limiting DDoS defense mechanism as well as the implementation of DDD. Afterward, we focus on the implementation of the HTTP server and browser and explain how we implemented a TCP SYN flooding attacker. Finally, we describe how we combined all the previously mentioned components to simulate networks. 6.1 Collecting Statistics OMNeT++ offers a signal-based framework to collect statistics of events. Signals are publish- subscribe style hooks to individual events like the transmission of a packet. Signals can be published (emitted) in the code when a certain event occurs. A so-called “statistic” can subscribe to a signal such that it always gets called when the signal is published. The statistic can then extract and record certain information from the signal. To make use of the framework, one can declare a signal inside the NED file of a module as follows: @signal[mySignal](type=inet::Packet); In this case, a signal of type inet::Packet is declared. This means that the signal expects a packet as an argument when emitted. Statistics can later use the arguments of a signal to extract information. This signal can then be registered in the C++ code of the module to obtain a handle to it: simsignal_t mySignal = registerSignal("mySignal"); Now, this simsignal_t object can be used to emit the signal whenever a specific event occurs. To do this, we can call cSimpleModule::emit(mySignal, packet); at any position in the code. With this call, we trigger the signal and provide the packet to be tracked as an argument. 39 6 Implementation To record specific information from a signal, we need to declare a statistic in the NED file. For example @statistic[myStatistic](source=packetLength(mySignal); record=sum; unit=b); declares a statistic that records the sum of bits of all packets emitted by mySignal. As we can see, this statistic has multiple parameters: • source: Where and how to extract the information from. In the example, the method packetLength(inet::Packet *packet) is applied to the argument of the mySignal signal. This means that whenever mySignal is emitted, the packet is taken from the arguments of this signal and gets fed into packetLength(...) to extract the length of the packet. This value is then collected by the statistic. Also, more complex calculations involving mathematical formulas and combinations of multiple methods are allowed here. • record: Specifies in what form the value provided by source should be recorded. In the example we use sum to record only the sum of all values over the entire simulation. There are also many other so-called recorders, for example count, min, max, mean, or last. All these recorders have in common that they only record a single number per simulation, a so-called “scalar”. There is also a vector recorder that records every single value and stores them as a list with their timestamps. • unit: The unit of measurement of the value produced by the source. In the example it is b for bits. Other common units are B for bytes or pk for packets. For every simulation run, OMNeT++ generates a *.sca file storing all recorded scalar values and a *.vec file for all vector values. 6.2 Implementing Custom Queueing Algorithms With INET As formulated in the system model (Section 4.1.2), each router contains multiple network interfaces, and each interface includes a queueing component that manages the queueing of the outgoing packets. Custom implementations of these queueing components can be used to implement network-based DDoS defense mechanisms, as packets can be prioritized or dropped in the queueing component. The default Router module from INET follows this structure. It is a compound module (c.f. Section 2.3.1) with multiple EthernetInterface submodules. Each EthernetInterface module contains a submodule that extends the IPacketQueue interface. To compare it with our system model: An OMNeT++ module extending IPacketQueue is an implementation of a queueing component. By default, INET’s EthernetInterface uses a queue of type EthernetQueue. However, it is possible to replace the type of the queue module by changing it in the network’s INI file. For instance, this is how we change the queue or the server-facing interface (eth0) to a DptbQueue module: router0_0.eth[0].queue.typename = "DptbQueue" This means we can implement DDoS defense algorithms by creating custom OMNeT++ modules implementing the IPacketQueue interface. This interface contains several method declarations, most importantly: 40 6.2 Implementing Custom Queueing Algorithms With INET • int getMaxNumPackets(): Returns the queue capacity in number of packets • b getMaxTotalLength(): Returns the queue capacity in number of bits • int getNumPackets(): Returns the number of packets currently stored in the queue • b getTotalLength(): Returns the cumulative packet size of all packets in the queue in bits • bool canPushPacket(Packet *packet, cGate *gate): True if there is enough space in the queue to insert the given packet; otherwise, false. • Packet *canPullPacket(cGate *gate): Returns the next packet if there is at least one packet in the queue that is ready for dequeueing; otherwise, it returns a null pointer. • void pushPacket(Packet *packet, cGate *gate): Inserts the packet into the queue. • Packet *pullPacket(cGate *gate): Extracts a packet from the queue. • bool isEmpty(): Returns true if and only if the queue does not contain any packets. These methods need to be overridden in order to implement a queue. However, a better starting point for custom queue implementations is the PacketQueueBase module that itself is an abstract implementation of the IPacketQueue interface. This class already implements some boilerplate code. To simplify the creation of multiple queueing implementations for different DDoS defense mech- anisms, we create an abstract intermediate class AdvancedPacketQueueBase that inherits from PacketQueueBase. The main purpose of this intermediate class is to streamline the collection of various statistics. AdvancedPacketQueueBase declares the following statistics (c.f. Section 6.1): • Number of good and bad packets going into the queueing module from the routing com- ponent (goodPacketsIncoming, badPacketsIncoming) as well as their cumulative lengths (goodPacketsIncomingLength, badPacketsIncomingLength) • Number of good and bad packets leaving the queueing module (i.e., did not get dropped) towards the egress port: goodPacketsOutgoing, badPacketsOutgoing as well as their cumulative lengths (goodPacketsOutgoingLength, badPacketsOutgoingLength) • Number of good and bad packets that got dropped inside the queueing mod- ule, either because of an overflowing queue or because the packet was classified as malicious (goodPacketsDropped, badPacketsDropped) and their cumulative lengths (goodPacketsDroppedLength, badPacketsDroppedLength) For each of the mentioned statistics, a corresponding signal is defined and emitted at the appropriate position in the code. To implement different DDoS defense mechanisms, we create subclasses of the described AdvancedPacketQueueBase that implement its methods accordingly. A UML class diagram showing all relevant queueing modules can be found in Figure 6.1. 41 6 Implementation <> PacketQueueBase <> AdvancedPacketQueueBase DptbQueue FifoQueue PacketReportingFifoQueue SimpleTokenBucketQueue TokenBucketDynamicPriorityTokenBucket <> DownstreamAccounter Part of INET 1 0..1 ** 0..1 <> IPacketQueue Figure 6.1: UML class diagram of the queueing implementations One of these subclasses is the FifoQueue that implements a basic FIFO queue. This queue serves as a baseline since it does not feature any DDoS protection mechanisms. While INET’s standard EthernetQueue is also a FIFO queue, we use our own implementation instead to have access to all the aforementioned statistics. The other two subclasses of AdvancedPacketQueueBase, namely DptbQueue and SimpleTokenBucketQueue are described below. 6.3 Rate Limiting In this section, we explain the implementation of Rate Limiting. First, we talk about a few conceptual considerations about the implementation, and afterward, we discuss the concrete implementation in OMNeT++. 42 6.3 Rate Limiting 6.3.1 Conceptual Implementation As could be seen in Chapter 3, Rate Limiting is a QoS-based common approach to DDoS defense. Since there are many variants of this approach [KREC18; OLL14; ZP06], we focus on the concept of Rate Limiting in general and introduce our own implementation of it in this section. The Token Bucket algorithm (c.f. Section 2.2.1) can be used to limit the average data rate of a sender. It allows the sender to continuously send at rates ≤ 𝑟 while the bucket of size 𝑏 allows for temporary bursts of at most 𝑇max = 𝑏 𝑅 − 𝑟 seconds, given the maximum egress bandwidth 𝑅 [Rot21]. Thus, we use the Token Bucket algorithm to implement Rate Limiting. For each client, each smart router maintains a token bucket with parameters 𝑟, 𝑏. Whenever a packet is sent to or from this client, the size of the packet (in bits) is deducted from the token bucket. If the token bucket does not contain at least as many tokens as the packet has bits, the packet gets dropped. To be more specific, we implement two variants of Rate Limiting with regard to the downstream traffic from server to client: • Unidirectional Rate Limiting (RL-U): This variant completely ignores downstream traffic. This means that only the upstream queueing component in the server-facing interface of each smart router contains a token bucket for each client IP address. The downstream queueing components of the client-facing interfaces are just simple FIFO queues. • Bidirectional Rate Limiting (RL-B): This variant has a shared token bucket for the upstream and downstream of a client. This means that tokens are not only removed from the bucket when the client sends a packet but also when the client receives a packet from the server. This is intended to make Rate Limiting more effective against downstream-heavy attacks like HTTP flooding, where the upstream traffic has no significant contribution to the overall bandwidth usage. To select parameters 𝑟, 𝑏 for the token buckets, we use the same strategy as for DDD: We pick router-independent parameters 𝑓𝑟 , 𝑓𝑏 and calculate the router-dependent parameters 𝑟, 𝑏 from them. The details for these calculations can be found in Section 5.5.2. 6.3.2 Concrete Implementation The implementation of Rate Limiting is realized in a SimpleTokenBucketQueue module that inherits from the AdvancedPacketQueueBase module described in Section 6.2. Internally, this module consists of the following components: • A single FIFO queue to store the enqueued packets • A hash map mapping client IP addresses to TokenBucket objects. This way, a separate token bucket is maintained for each client. 43 6 Implementation The implementation of the token buckets is realized in a separate TokenBucket class. This class maintains the state of a token bucket that is configured by parameters 𝑟, 𝑏. Most importantly, this class contains a method internalClassify(inet::Packet *packet) that receives a to-be-sent packet. This method calculates the size of the packet and checks whether the current fill level of the bucket contains enough tokens to send the packet. If this is not the case, the method returns false. Otherwise, the bucket is updated accordingly, and true is returned. The variants RL-U and RL-B mostly differ in the configuration of the routers: • For Unidirectional Rate Limiting (RL-U) only the server-facing interface eth0 is assigned a SimpleTokenBucketQueue and all other interfaces use normal FifoQueue interfaces. • For Bidirectional Rate Limiting (RL-B), every interface of a router uses a SimpleTokenBucketQueue. However, only the server-facing interface’s queue is config- ured as a so-called “master queue”. Being a master queue means that this queue manages the token buckets for all queues of the router across different interfaces. This allows all interfaces to share a token bucket per client. At initialization, all non-master queues obtain a reference to the master queue object. For each processed packet, this reference is then used to access the master queue’s token buckets through its publicly exposed classifyAndUpdateExternally(inet::Packet *packet) method. Now, when a SimpleTokenBucketQueue receives a packet from the routing component of a router, it processes it as follows: First, it is checked whether there is still enough space in the FIFO queue to insert the packet. If not, the packet gets dropped immediately. Otherwise, the packet is classified: If the queue is a master queue, the local address-to-token-bucket map is used for the classification. Otherwise, the master queue is accessed. In both cases, it is first checked whether the client IP address (source IP if packet from client to server, otherwise destination IP address) is already present in the token bucket map. If not, a new entry with a new TokenBucket object is created. Otherwise, a reference to the existing token bucket is retrieved from the map. The token bucket is then updated as described above, returning a boolean that indicates whether the packet may be sent. If yes, the packet is enqueued in the FIFO queue. Otherwise, the packet is dropped. 6.4 DDD In this section, we describe the implementation of the DDD mechanism in OMNeT++. The heart of the DDD implementation is a module DptbQueue that inherits from AdvancedPacketQueueBase. This module mainly consists of two components: • An std::vector containing two equally-sized FIFO queues for the priority classes 𝐶0 and 𝐶1 • A hash map mapping client IP addresses to tuples (standardBucket, tcpSynBucket). As the names imply, we store two DPTB buckets for each client: One for TCP SYN packets and one for all other packets. All buckets are instances of the class DynamicPriorityTokenBucket. This class implements a DDD-adapted variant of the DPTB algorithm, as described in Chapter 5. Most importantly, its method internalCalculatePriority(inet::Packet *packet, bool isTcpSynPacket) updates the bucket level and calculates the priority class for a given packet. The internals of this method can be found in Listing 6.1. 44 6.4 DDD Listing 6.1 Code in the DynamicPriorityTokenBucket class to update the bucket level and calculate the priority class of a packet. (slightly simplified) std::tuple DynamicPriorityTokenBucket::internalCalculatePriority( inet::Packet *packet, bool isTcpSynPacket) const{ double currentLevelLocal = currentLevel; // Fill bucket with refill rate r: simtime_t now = omnetpp::simTime(); double timePassed = (now - lastRefillTime).dbl(); currentLevelLocal += timePassed * r; if (currentLevelLocal > b){ currentLevelLocal = b; } int size = isTcpSynPacket ? tcpSynPacketCost : packet->getTotalLength().get(); // Calculate severity level int severityLevel = thresholds.size(); for(int i = 0; i < numPriorities; i++){ if(currentLevelLocal - costs.at(severityLevelToClass(i)) * size >= thresholds.at(i)){ severityLevel = i; break; } } // Deduct tokens from bucket: double costOfPacket = costs.at(severityLevelToClass(severityLevel)) * size; currentLevelLocal -= costOfPacket; int priority = severityLevelToClass(severityLevel); return std::make_tuple(priority, currentLevelLocal, now); } Both variants of DDD, Bidirectional DDD, and DDD with Downstream Reporting, are built around the DptbQueue. However, there are differences in the configuration of the routers: • For DDD-B, the configuration is analogous to that of Bidirectional Rate Limiting (RL-B, see Section 6.3.2): All interfaces of a smart router use their own DptbQueue instance. The server-facing interface has a queue called the “master queue”. This master queue manages the buckets for all other queues. Each client and router pair has only one pair of buckets, which is shared across all interfaces of the router. The queues of all other interfaces are “slave queues” that do not have their own buckets but instead access their master queue’s buckets to classify packets. Again, there is a public classifyAndUpdateExternally(inet::Packet *packet) method exposed by master queues that can be used by the slaves to access the DPTB buckets indirectly. • The implementation and configuration of DDD with Downstream Reporting is more com- plicated: The queueing module of a router’s server-facing interface is again an instance of DptbQueue that acts as a master queue. However, the client-facing interfaces are instances of a 45 6 Implementation new module PacketReportingFifoQueue. This module is an extension of the FifoQueue that supports Downstream Reporting. In itself, this type of queue behaves like a normal FIFO queue. However, every time it enqueues a packet, it also notifies the master DptbQueue about this event by calling its classifyAndUpdateExternally(inet::Packet *packet) method. This method is declared through an additional DownstreamAccounter interface that is implemented by DptbQueue. This interface makes it possible that the PacketReportingFifoQueue cannot only be used together with the DptbQueue but with any queuing module implementing this interface. This allows for the extensibility of the code to implement other DDoS defense mechanisms. When the master queue gets notified about a downstream packet being enqueued, it deducts the tokens necessary to send the packet from the receiving client’s DPTB bucket according to the DDD specification. In general, when a DptbQueue module receives a packet (i.e., its pushPacket(...) method is called), it is processed as follows: First, the packet is classified by DPTB in a “dry run”, i.e., without actually updating the bucket level. This is necessary as we need to know in which of the priority queues the packet would be inserted. Only when this is known, it can be checked whether there is enough space in the determined queue to insert the packet. If this is not the case, the packet gets dropped. If the packet can be inserted, the DPTB classification algorithm is run again, but this time with side effects, i.e., the bucket level gets updated. The packet then gets enqueued into the queue, which is determined by its classified priority, or dropped in the case of priority 𝐶2. In both the dry run and the run with side effects, the classification algorithm first checks whether the client’s IP address is already contained as a key in the bucket map. If this is not the case, two new DynamicPriorityTokenBucket instances are created: One for TCP SYN packets and one for all others. The pair of both buckets then gets inserted into the map together with the client’s IP address. If the client is already present in the map, its buckets are retrieved from it. Next, it is checked whether the packet is a TCP SYN packet (i.e., the IP packet contains a TCP segment, and the SYN flag is set but not the ACK flag). If it is, the bucket for SYN packets is selected, otherwise the bucket for normal packets is used. The selected DynamicPriorityTokenBucket is then used to clas- sify the packet: In the case of a dry run, the method calculatePriorityConst(inet::Packet *packet, ...) is called on the bucket’s object. In a run with side effects, the method calculatePriorityAndUpdate(inet::Packet *packet, ...) is called instead. Internally, both methods call the side-effect free internalCalculatePriority(...) method (shown in List- ing 6.1). This method returns, among other values, the updated fill level of the bucket. calculatePriorityAndUpdate(...) assigns the returned value to the object-level currentLevel variable, while calculatePriorityConst(inet::Packet *packet, ...) discards the returned value. When the pullPacket(...) method of a DptbQueue module is called, strict priority queueing is applied: The queues of priorities 𝐶0 and 𝐶1 are checked in this order. The first queue containing at least one packet is selected, and a packet is extracted from this queue in FIFO order. This packet is then forwarded to the egress port of the network interface. 46 6.5 HTTP Server and Browser 6.5 HTTP Server and Browser For the evaluation, we need to simulate an HTTP web server and HTTP browsers accessing the server. INET offers HttpBrowser and HttpServer components [Var23] for this purpose. These OMNeT++ modules can be run as applications on INET’s StandardHost components. Both components offer a “random mode” and a “scripted mode”. In the random mode, the behavior of the browser and server is specified by probability distributions. For instance, the request size and interval between two requests from the browser can be modeled using distributions. Modelable parameters for the server include the resource size for HTML pages, text resources and images and the number of resources per page. Supported distributions are uniform, normal, and exponential distributions, among others. At runtime, values are sampled from the probability distributions to determine the behavior of the browser and server. The scripted mode allows to hard-code the behavior of the browser and server. For the browser a list of URLs can be specified together with timestamps. The browser will then request these pages together with all their resources at the server at the specified times. For the server, the available web pages, together with their resources and respective sizes and file types, can be specified. The scripted mode can be used to replicate websites from the real world in the simulation environment. In this work we always use the random mode as it is convenient to model realistic client and server behavior by specifying probability distributions. As the modules given by INET did not fulfill our requirements out of the box, we had to modify them. In the following we first discuss how we modified the HTTP server and chose appropriate probability distributions for it. Then we look at the modifications we did to the HTTP browser. 6.5.1 HTTP Server Modifications We noticed that there is an issue with INET’s HttpServer component: When the server receives an HTTP request, it keeps the associated TCP connection open until it has sent the response to the request. Even under high load, there is no mechanism to reject requests or close TCP connections before sending a response. This becomes a problem when the server receives more requests than it can answer in a given period of time with regard to the egress bandwidth. In such a scenario, open TCP sockets accumulate in the HTTP server. In our experiments, this has led to hundreds of thousands of open TCP connections piling up on the server. This is a major problem for the performance of the simulations as the TCP sockets use up large amounts of memory on the simulation server and slow down the simulation significantly. To tackle this issue, we created the HttpServerAdvanced module, a subtype of HttpServer. This module keeps track of the current number of open TCP sockets. If the number of open sockets exceeds a threshold (we picked 500 sockets), all new requests are rejected until a socket has been closed. This way, we limit the number of open TCP sockets. After we replaced the HttpServer with our own module, all performance and memory bloat issues disappeared. 47 6 Implementation 6.5.2 Choosing Probability Distributions for the Server We use the random mode of the HttpServerAdvanced component to configure the behavior of the server. In this mode, the behavior of the web server can be defined using probability distributions. For instance, the sizes of HTML pages, text and image resources, and the number of resources per page can be controlled via distributions. This poses the question of how we should define these distributions. To make things as realistic as possible, we construct the distributions from statistical data of real-world websites. The authors of the “Web Almanac 2022” [HTT22] evaluated 8.36 million websites to create statistics for all sorts of metrics. Relevant to this work is the “Page Weight” chapter of the almanac. This chapter provides median values for the number of requests per page and the sizes of website resources by resource type. We use this data to define exponential distributions with the following mean values: • Mean HTML page size: 31 kByte • Mean text resource (CSS, JS, ...) size: 20.03 kByte • Mean image resource size: 41.04 kByte • Mean number of resources: 54 (only considering text and image resources, but not video, etc.) Unfortunately the almanac only provides median values while an exponential distribution cannot be defined over a median. Therefore we treat the median values as mean values. While this is not clean from a mathematical perspective, it should still represent real-world websites sufficiently accurate for our use case. Since the network links in our evaluations have only about 60 % of the bandwidth of network links on the internet due to performance reasons, we multiply all the size values by a factor of 0.6. 6.5.3 HTTP Browser Modifications INET’s HttpBrowser module tracks a couple of metrics, including the number of sent and received requests broken down by file type (HTML, text resource, image) and the number of broken sockets. However, by default, the browser does not track the response time for HTTP requests. As the response time has a significant impact on the user experience [Lin06], we want to measure it. To achieve this, we developed the HttpBrowserAdvanced module as an extension of the HttpBrowser. Whenever this browser module sends an HTTP request to the server, it stores the current time together with the socket handle for the request’s TCP connection. When the browser receives a response to this request from the server, it uses the stored timestamp to calculate the response time. This response time is then reported to OMNeT++’s statistics framework by the emission of a signal called httpResponseTimeSignal. The NED file of the HttpBrowserAdvanced module declares a statistic that records the mean, minimum, and maximum response time based on the signal. 48 6.6 TCP SYN Flooding Attacker Application 6.6 TCP SYN Flooding Attacker Application To make a client perform a TCP SYN flooding attack, we need an application that sends TCP SYN packets without actually opening TCP sockets. The latter part is important because opening a real TCP socket would use up memory on the client, which is problematic when we want to do this hundreds of times per minute. As a base for this application, we use INET’s IpApp. This is an application that can send IP packets at a specified rate. The content of these IP packets is determined by a submodule implementing the IActivePacketSource interface. The ActivePacketSource module is used as the default implementation of this interface. This module only produces meaningless bytes as filler content for the packets. We change this behavior by creating a subtype of ActivePacketSource: The TcpSynPacketSource. This module overrides the createPacketContent() method such that it returns a TCP header with the SYN flag set. For each p