diff --git a/Makefile b/Makefile index dc9ef8b..ae377e8 100644 --- a/Makefile +++ b/Makefile @@ -111,6 +111,8 @@ xdp: # LibXDP chain. We need to install objects here since our program relies on installed object files and such. libxdp: $(MAKE) -C $(XDP_TOOLS_DIR) libxdp + +libxdp_install: sudo $(MAKE) -C $(LIBBPF_SRC) install sudo $(MAKE) -C $(LIBXDP_DIR) install @@ -118,11 +120,6 @@ libxdp_clean: $(MAKE) -C $(XDP_TOOLS_DIR) clean $(MAKE) -C $(LIBBPF_SRC) clean -clean: - find $(BUILD_DIR) -type f ! -name ".*" -exec rm -f {} + - find $(BUILD_LOADER_DIR) -type f ! -name ".*" -exec rm -f {} + - find $(BUILD_XDP_DIR) -type f ! -name ".*" -exec rm -f {} + - install: mkdir -p $(ETC_DIR) cp -n xdpfw.conf.example $(ETC_DIR)/xdpfw.conf @@ -132,5 +129,10 @@ install: cp -f $(BUILD_LOADER_DIR)/$(LOADER_OUT) /usr/bin cp -f $(BUILD_XDP_DIR)/$(XDP_OBJ) $(ETC_DIR) +clean: + find $(BUILD_DIR) -type f ! -name ".*" -exec rm -f {} + + find $(BUILD_LOADER_DIR) -type f ! -name ".*" -exec rm -f {} + + find $(BUILD_XDP_DIR) -type f ! -name ".*" -exec rm -f {} + + .PHONY: all libxdp .DEFAULT: all \ No newline at end of file diff --git a/README.md b/README.md index 7c9e8b5..c4ac61e 100644 --- a/README.md +++ b/README.md @@ -14,15 +14,83 @@ I hope this project helps existing network engineers/programmers interested in u ![Demo](./images/demo.gif) -## Command Line Usage -The following command line arguments are supported: +## Building & Installing +Before building, ensure the following packages are installed. These packages can be installed with `apt` on Debian-based systems (e.g. Ubuntu, etc.), but there should be similar package names in other package managers. -* `--config -c` => Location to config file. Default => **/etc/xdpfw/xdpfw.conf**. -* `--offload -o` => Tries to load the XDP program in hardware/offload mode (please read **Offload Information** below). -* `--skb -s` => Forces the program to load in SKB mode instead of DRV. -* `--time -t` => How long to run the program for in seconds before exiting. 0 or not set = infinite. -* `--list -l` => List all filtering rules scanned from config file. -* `--help -h` => Print help menu for command line options. +```bash +# Install dependencies. +sudo apt install -y libconfig-dev llvm clang libelf-dev build-essential + +# Install dependencies for building LibXDP and LibBPF. +sudo apt install -y libpcap-dev m4 gcc-multilib + +# You need tools for your kernel since we require BPFTool. If this doesn't work, I'd suggest building BPFTool from source (https://github.com/libbpf/bpftool). +sudo apt install -y linux-tools-$(uname -r) +``` + +You can use `git` to clone this project. Make sure to include the `--recursive` flag so it downloads the XDP Tools submodule! + +```bash +# Clone repository via Git. Use recursive flag to download XDP Tools submodule. +git clone --recursive https://github.com/gamemann/XDP-Firewall.git + +# Change directory to repository. +cd XDP-Firewall +``` + +From here, you have two options to build and install this tool which are explained below. + +### With Bash Script +The easiest way to build and install this tool is to use the provided [`install.sh`](./install.sh) Bash script. This script relies on `sudo` being installed on your system. If you do not have sudo, please refer to the below steps on building and installing this tool without the Bash script. + +If you don't have LibXDP installed on your system yet, I'd recommend using the following command. + +```bash +./install.sh --libxdp +``` + +Otherwise, you can exclude the `--libxdp` flag if you'd like. + +Additionally, here is a list of flags you may pass to this script. + +| Name | Description | +| ---- | ----------- | +| --libxdp | Build and install LibXDP before building the tool. | +| --no-install | Build the tool and/or LibXDP without installing them. | +| --clean | Remove build files for the tool and LibXDP. | +| --static | Statically link LibXDP and LibBPF object files when building the tool. | +| --help | Displays help message. | + +### Without Bash Script +If you do not want to use the Bash script above, you may use `make` to build and install this tool instead. + +``` +# Build XDP-Tools (LibXDP and LibBPF). +make libxdp + +# Install LibXDP & LibBPF onto your system. +# Warning: This command must be executed as root! `sudo` should do this for you if you have it installed and have privileges. +sudo libxdp_install + +# Build the firewall tool. +make + +# Install the tool onto your system. +# Warning: This command must be executed as root! `sudo` should do this for you if you have it installed and have privileges. +sudo make install +``` + +## Command Line Usage +The following command line arguments are supported. + +| Name | Default | Description | +| ---- | ------- | ----------- | +| -c, --config | `/etc/xdpfw/xdpfw.conf` | The path to the config file. | +| -o, --offload | N/A | If set, attempts to load the XDP program in hardware/offload mode. | +| -s, --skb | N/A | If set, forces the XDP program to be loaded using SKB mode instead of DRV mode. | +| -t, --time | N/A | If set, will run the tool for this long in seconds. E.g. `--time 30` runs the tool for 30 seconds before exiting. | +| -l, --list | N/A | If set, will print the current config values and exit. | +| -h, --help | N/A | Prints a help message. | ### Offload Information Offloading your XDP/BPF program to your system's NIC allows for the fastest packet processing you can achieve due to the NIC dropping the packets with its hardware. However, for one, there are **not** many NIC manufacturers that do support this feature **and** you're limited to the NIC's memory/processing (e.g. your BPF map sizes will be extremely limited). Additionally, there are usually stricter BPF verifier limitations for offloaded BPF programs, but you may try reaching out to the NIC's manufacturer to see if they will give you a special version of their NIC driver raising these limitations (this is what I did with one manufacturer I used). @@ -148,38 +216,6 @@ filters = ( ); ``` -## Building & Installation -Before building, ensure the following packages are installed. These packages are installed via `apt` (Ubuntu, Debian, etc.), but there should be similar package names in other package managers. - -```bash -# Install dependencies. -sudo apt install -y libconfig-dev llvm clang libelf-dev build-essential - -# Install dependencies for building LibXDP and LibBPF. -sudo apt install -y libpcap-dev m4 gcc-multilib - -# You need tools for your kernel since we need BPFTool. If this doesn't work, I'd suggest building BPFTool from source (https://github.com/libbpf/bpftool). -sudo apt install -y linux-tools-$(uname -r) -``` - -You can use `git` and `make` to build this project. The following should work: - -```bash -# Clone repository via Git. Use recursive flag to download LibBPF sub-module. -git clone --recursive https://github.com/gamemann/XDP-Firewall.git - -# Change directory to repository. -cd XDP-Firewall - -# Build XDP-Tools and install LibXDP & LibBPF to /usr/include. -# Warning - This command uses Sudo for root access! -# Feel free to remove sudo from the Makefile and execute as root otherwise. -make libxdp - -# Build main project and install as root via Sudo. -make && sudo make install -``` - ## Notes ### Moved To LibXDP On **June 6th, 2023**, we've moved to [LibXDP](https://github.com/xdp-project/xdp-tools/tree/master/lib/libxdp) from [XDP Tools](https://github.com/xdp-project/xdp-tools) to load the XDP/(e)BPF program. This requires additional packages and tools to install and use with this XDP firewall as noted above. @@ -253,7 +289,7 @@ If you receive an error similar to the one below when running the program, make ./xdpfw: error while loading shared libraries: libxdp.so.1: cannot open shared object file: No such file or directory ``` -If you don't want to have LibXDP installed on your system after building the program, you can set the `LIBBPF_LIBXDP_STATIC` environmental variable to `1` while building the project with `make`. This will link all of the LibBPF and LibXDP object files while building the loader so you shouldn't need LibXDP installed globally. +If you don't want to have LibXDP installed on your system after building the program, you can set the `LIBBPF_LIBXDP_STATIC` environmental variable to `1` while building the project with `make` or pass the `--static` flag to the [`install.sh`](./install.sh) Bash script. This will link all of the LibBPF and LibXDP object files while building the loader so you shouldn't need LibXDP installed globally. For example: @@ -263,6 +299,9 @@ LIBBPF_LIBXDP_STATIC=1 make # Install onto system. sudo make install + +# Build using Bash script with static. +./install.sh --static ``` ## My Other XDP Projects diff --git a/install.sh b/install.sh new file mode 100755 index 0000000..64aeb01 --- /dev/null +++ b/install.sh @@ -0,0 +1,90 @@ +#!/bin/bash +WITH_LIBXDP=0 +INSTALL=1 +CLEAN=0 +STATIC=0 + +while [[ $# -gt 0 ]]; do + key="$1" + + case $key in + --libxdp) + WITH_LIBXDP=1 + + shift + ;; + + --no-install) + INSTALL=0 + + shift + ;; + + --clean) + CLEAN=1 + + shift + ;; + + --static) + STATIC=1 + + shift + ;; + + --help) + echo "Usage: install.sh [OPTIONS]" + echo + echo "Options:" + echo " --libxdp Build and install LibXDP before building the tool." + echo " --no-install Build the tool and/or LibXDP without installing them." + echo " --clean Remove build files for the tool and LibXDP." + echo " --static Statically link LibXDP and LibBPF object files when building the tool." + echo " --help Display this help message." + + exit 0 + + shift + ;; + *) + + shift + ;; + esac +done + +if [ "$CLEAN" -gt 0 ]; then + if [ "$WITH_LIBXDP" -gt 0 ]; then + echo "Cleaning LibXDP..." + + ./scripts/libxdp_clean.sh + fi + + echo "Cleaning up tool..." + + ./scripts/clean.sh + + exit 0 +fi + +if [ "$WITH_LIBXDP" -gt 0 ]; then + echo "Building LibXDP..." + + ./scripts/libxdp_build.sh + + if [ "$INSTALL" -gt 0 ]; then + echo "Installing LibXDP..." + + sudo ./scripts/libxdp_install.sh + fi +fi + +echo "Building tool..." + +./scripts/build.sh $STATIC + +if [ "$INSTALL" -gt 0 ]; then + echo "Installing tool..." + + sudo ./scripts/install.sh +fi \ No newline at end of file diff --git a/scripts/build.sh b/scripts/build.sh new file mode 100755 index 0000000..ff6fd1b --- /dev/null +++ b/scripts/build.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +STATIC="$1" + +if [ -z "$STATIC" ]; then + STATIC=0 +fi + +if [ -z "$ROOT" ]; then + LIBBPF_LIBXDP_STATIC=$STATIC make +else + cd $ROOT && LIBBPF_LIBXDP_STATIC=$STATIC make +fi \ No newline at end of file diff --git a/scripts/clean.sh b/scripts/clean.sh new file mode 100755 index 0000000..43c55eb --- /dev/null +++ b/scripts/clean.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +if [ -z "$ROOT" ]; then + make clean +else + cd $ROOT && make clean +fi \ No newline at end of file diff --git a/scripts/install.sh b/scripts/install.sh new file mode 100755 index 0000000..3f167e5 --- /dev/null +++ b/scripts/install.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +if [ -z "$ROOT" ]; then + make install +else + cd $ROOT && make install +fi \ No newline at end of file diff --git a/scripts/libxdp_build.sh b/scripts/libxdp_build.sh new file mode 100755 index 0000000..1e05d46 --- /dev/null +++ b/scripts/libxdp_build.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +if [ -z "$ROOT" ]; then + make libxdp +else + cd $ROOT && make libxdp +fi \ No newline at end of file diff --git a/scripts/libxdp_clean.sh b/scripts/libxdp_clean.sh new file mode 100755 index 0000000..7c0a517 --- /dev/null +++ b/scripts/libxdp_clean.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +if [ -z "$ROOT" ]; then + make libxdp_clean +else + cd $ROOT && make libxdp_clean +fi \ No newline at end of file diff --git a/scripts/libxdp_install.sh b/scripts/libxdp_install.sh new file mode 100755 index 0000000..56a930f --- /dev/null +++ b/scripts/libxdp_install.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +if [ -z "$ROOT" ]; then + make libxdp_install +else + cd $ROOT && make libxdp_install +fi \ No newline at end of file