Git Product home page Git Product logo

research-project's Introduction

Automated Rule Generation for DDoS Mitigation using eBPF

This repository I use(d) for my Research Project into Automated Rule Generation for DDoS mitigation using eBPF. Basically, this means doing three things:

  1. Generate an eBPF program based on a set of filtering rules
  2. Generate these filtering rules out of a DDoS attack fingerprint from DDoSDB.org.
  3. Evaluate the performance of these automatically generated rules.

Prerequisites

This repository uses the BPF Compiler Collection to compile the code into eBPF. You can find the installation instructions here.

1. Generate an eBPF program from a set of rules

The concept is simple: We want to define rules and then convert those rules into a runnable eBPF program that filters packets based on this same rules.

1.1 Basic rules

A rule consists of one ore more conditions. A basic condition consists of:

  • a property (Protocol['property'], e.g: IPv4['src'])
  • a numerical comparator (==, !=, <. <=, >=, >)
  • a value to compare to (e.g: 1.2.3.4)

A basic rule with a basic condition is created as shown below:

from Rules import Rule
from Protocols import IPv4

# Creating a condition is pretty easy
condition = IPv4['src'] == '1.2.3.4'

# Creating a rule with the same condition can be done in various ways:
rule = Rule(condition)                      # Condition in variable
rule = Rule(IPv4['src'] == '1.2.3.4')       # Condition directly in constructor
rule = Rule(IPv4['src'], '==' ,'1.2.3.4')   # Separate parts of condition directly in Rule

1.2 Properties

Each of the properties that can be used in a condition/rule belongs to a protocol, like IPv4 or TCP. Currently, the following properties are supported:

Protocol Property Description Expected value type* Example value
Ethernet len Total packet length int in [0, 2^16) 41020
Ethernet src Source MAC address FF:FF:FF:FF:FF:FF b1:30:a2:bf:0f:c7
Ethernet src Destination MAC address FF:FF:FF:FF:FF:FF b1:30:a2:bf:0f:c7
Ethernet next Next protocol int in [0, 2^16) 41020
IPv4 src Source IP address 255.255.255.255 1.2.3.4
IPv4 dst Destination IP address 255.255.255.255 1.2.3.4
IPv4 len IP packet length int in [0, 2^16) 41020
TCP src TCP source port int in [0, 2^16) 41020
TCP dst TCP destination port int in [0, 2^16) 41020
TCP fin TCP FIN flag 0 or 1 1
TCP syn TCP SYN flag 0 or 1 1
TCP rst TCP RST flag 0 or 1 1
TCP psh TCP PSH flag 0 or 1 1
TCP ack TCP ACK flag 0 or 1 1
TCP urg TCP URG flag 0 or 1 1
TCP ece TCP ECE flag 0 or 1 1
TCP cwr TCP CWR flag 0 or 1 1
UDP src UDP source port int in [0, 2^16) 41020
UDP dst UDP destination port int in [0, 2^16) 41020
UDP len UDP packet length int in [0, 2^16) 41020

*A numerical value can also always be entered as a string

Every property can be used with every numerical comparator (==, !=, <. <=, >=, >), as long as the value matches the property. Please note that the IP and MAC addresses always should be supplied in a string.

Some examples of the usage of properties:

from Protocols import IPv4, TCP, UDP, Ethernet

# Some valid conditions
a = Ethernet['src'] != 'b1:30:a2:bf:0f:c7'
b = IPv4['src'] < '100.0.0.0'
c = TCP['fin'] == 1
d = UDP['len'] >= 100

1.3 Combined rules

Rules and conditions can be combined indefinitely using OR or AND operations as follows:

from Rules import Rule
from Protocols import IPv4, Ethernet
from Conditions import Condition

# Some valid conditions
a = Ethernet['src'] != 'b1:30:a2:bf:0f:c7'
b = IPv4['src'] < '100.0.0.0'

# Combine conditions by AND
cond = a & b
cond = Condition(a, '&&', b)
rule = Rule.all(a, b)
rule = Rule(Rule(a), '&&', Rule(b))

# Combine conditions by OR
cond = a | b
cond = Condition(a, '||', b)
rule = Rule.one(a, b)
rule = Rule(Rule(a), '||', Rule(b))

# THIS WON'T WORK: Conditions cannot be combined with rules with & and |
error = Rule(a) | b
# But can be combined with Rule.all() and Rule.one()
working = Rule.all(Rule(a), b)

To avoid illegal combination of rules and conditions, using Rule.all() and Rule.one() is recommended:

from Rules import Rule
from Protocols import IPv4, TCP, UDP, Ethernet

# Recommended way to create more complex rules
rule = Rule.all(
    Rule.one(
        Ethernet['src'] != 'b1:30:a2:bf:0f:c7',
        IPv4['src'] < '100.0.0.0',
        IPv4['len'] >= 100
    ), Rule.one(
        TCP['fin'] == 1,
        UDP['len'] >= 100
    )
)

1.4 Generating and running program from rules

Once the rules are defined, generating a program from a set of rules is simple:

from Program import Program

# Write program code to variable
code = Program.generate(rule1, rule2, ruleX, .. ,ruleN)

# Write program code to file
Program.generate(*rules, file='test.c')

# Optionally specify whitelisting
Program.generate(*rules, blacklist=False)

The string or file will contain all C code of the eBPF program. The directory src/code contains bpf-loader.py which can load BPF C files into the kernel. To execute your freshly generated file:

sudo python bpf-loader.py <filename>

# For the program generated above
sudo python bpf-loader.py test.c

At the moment it is not possible to feed strings directly to BPF.

1.5 Total example

from Program import Program
from Rules import Rule
from Protocols import IPv4, TCP, UDP, Ethernet

# Filter packets from 132.68.0.0/16 larger than 250 bytes
rule1 = Rule.all(
    Ethernet['len'] > 250,
    IPv4['src'] >= '132.68.0.0',
    IPv4['src'] <= '132.68.255.255'
)

# Filter packets from port 53 (DNS) larger than 1000
rule2 = Rule.all(
    Ethernet['len'] > 1000,
    Rule.one(
        UDP['src'] == 53,
        TCP['src'] == 53
    )
)

# Generate program
Program.generate(rule1, rule2, file='test.c')
$ sudo python bpf-loader.py test.c
Loading bpf program
Following traceprint, hit CTRL+C to stop and remove

research-project's People

Contributors

dirkkoelewijn avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.