# Gatekeeper puts a central policy behind DPDK packet processing

> Gatekeeper is a GPL-3.0 DDoS mitigation system written in C on top of DPDK, built for network operators who can hand it NICs through vfio-pci and configure it with Lua. It is explicitly not aimed at individual internet users.

**AltraMayor/gatekeeper** — The first open-source DDoS protection system

- Repository: https://github.com/AltraMayor/gatekeeper
- Website: https://github.com/AltraMayor/gatekeeper/wiki
- Stars: 1,653 · Forks: 256
- Language: C
- License: GPL-3.0
- Published: 2026-10-16 · Updated: 2026-10-16 · Language: en
- Canonical page: https://hysenlabs.com/projects/altramayor-gatekeeper

## Written for operators who can hand over their own NICs

The audience is narrow and the README does not pretend otherwise. Gatekeeper targets network operators at institutions, service and content providers, and enterprise networks, and it says outright that it is not intended for individual internet users. That framing matters, because the deployment path runs through DPDK: Gatekeeper does not sit on a normal host network stack as an ordinary daemon, it takes physical interfaces away from the kernel and processes packets itself.

The claim on the front page is that this is the first open source DDoS protection system, and the interesting design claim is architectural rather than a throughput number. Traffic is geographically distributed across sites, yet the network policy describing every decision made on incoming traffic is centralized. Centralizing the policy is what allows the project to use algorithms that would fail under the latency of a distributed store, and to handle several multi-vector attacks at the same time.

The default branch is master, the primary language is C, and the licence is GPL-3.0, which for a network appliance means any derivative you distribute carries the same licence and source obligation. Treat it as infrastructure software, not a component you drop into a proprietary product.

## Functional blocks named in the Makefile, not a monolith

The build file gives a clearer picture of the architecture than the README does. Sources are grouped into functional blocks that are compiled into one binary: config/static.c and config/dynamic.c handle static and dynamic configuration, cps/main.c with cps/kni.c and cps/rd.c deals with the control plane and kernel communication, ggu/ and gt/ cover the packet handling and traffic policing side, gk/main.c, gk/rt.c and gk/bpf.c carry the BPF programs, lls/main.c with cache, arp and nd is a link layer stack with its own ARP and neighbour discovery, and sol/main.c plus main/main.c provide the solution loop and entry point.

Underneath sits a set of C libraries in lib/, including ratelimit.c, acl.c, fib.c, rib.c, varip.c, memblock.c, coro.c and hash.c. The presence of coro.c and the -DCORO_ASM flag in the build flags says the packet path uses its own coroutine machinery instead of one thread per core. bpf/ at the top level carries eBPF sources for the fast path, and lua/ exists because configuration is Lua.

The controller lives in gkctl/, and there is a generated interface map via generate_if_map.c, which is how port assignments reach the data path. Build flags include -DALLOW_EXPERIMENTAL_API, so the DPDK it compiles against is using APIs DPDK itself still marks experimental. That is a fair signal about how closely you are tracking the DPDK version underneath.

## Hugepages and vfio-pci come before any Gatekeeper command

Most of the README setup section is spent on the host, not on Gatekeeper, and that ordering tells you what the project expects. DPDK requires hugepages, and on many systems one command is enough:

```sh
echo 2 | sudo tee /sys/kernel/mm/hugepages/hugepages-1048576kB/nr_hugepages
```

Then the NIC has to be handed over. That means VT-d in the BIOS, IOMMU in the kernel with a version greater than 3.6, and the vfio-pci module. The README gives you a way to check each layer rather than assuming:

```sh
grep CONFIG_INTEL_IOMMU_DEFAULT_ON /boot/config-`uname -r`
cat /proc/cmdline | grep intel_iommu=on
```

If the config line says the option is not set, you add intel_iommu=on through GRUB and reboot. The final check is the one to remember:

```sh
ls /sys/kernel/iommu_groups
```

An empty listing means stop, because nothing can be bound. Otherwise /sys/class/iommu will show devices such as dmar0 on Intel or ivhd0 on AMD. This is the step where most of the work goes, and none of it involves Gatekeeper itself.

## Installing the Ubuntu 24.04 packages and pointing them at your ports

Debian packages are published on the Releases page for Ubuntu 24.04 LTS, and that is the supported route. Installation is a tarball and dpkg:

```sh
tar -zxvf gatekeeper-ubuntu-24.04-packages.tar.gz
cd gatekeeper-ubuntu-24.04-packages
sudo dpkg -i gatekeeper-bird_*_amd64.deb gatekeeper_*_amd64.deb
```

Configuration then lives in /etc/gatekeeper. The one file you must edit is net.lua, and the README names four variables in it: front_ports, front_ips, back_ports and back_ips. Those describe the attacked side and the protected side, so getting them wrong means either nothing is inspected or legitimate traffic is dropped.

The second file is /etc/gatekeeper/envvars, which needs GATEKEEPER_INTERFACES set to the PCI addresses of the adapters you are binding to DPDK. The lshw output gives them to you:

```sh
sudo lshw -c network -businfo
```

A line such as pci@0000:08:00.0 becomes 08:00.0 in the variable, so a two-port I350 becomes:

```sh
GATEKEEPER_INTERFACES="08:00.0 08:00.1"
```

The same file also takes DPDK_ARGS for Environment Abstraction Layer options and GATEKEEPER_ARGS for Gatekeeper specific options. Start and enable it:

```sh
sudo systemctl start gatekeeper
sudo systemctl enable gatekeeper
```

The README truncates before the build-from-source instructions finish, so the dependency list is cut off mid-command. Building from source is documented, but the visible text is incomplete, and the wiki carries the rest.

## Lua decides policy, and the wiki owns the details

Gatekeeper is configured primarily through Lua files in /etc/gatekeeper rather than a command line or a YAML file. The README is candid about the limits of its own coverage here: after pointing you at net.lua it sends you to the project wiki for what the other Lua files do, including whether they need changing in your setup.

That division of labour has a consequence for adoption. The four net.lua variables are documented well enough to start from, but block-level tuning lives outside the repository documentation, so budget time for reading the wiki Configuration page before you can reason about what a block is doing. The Gatekeeper specific options reachable through GATEKEEPER_ARGS are documented on that wiki page rather than in the README.

Lua as the policy language is the right call for a device that has to change behaviour without rebuilds, and it is also the wrong call if you want policy as code reviewed in a repository and shipped through CI. Nothing in the README suggests Gatekeeper supports loading policy from a versioned artifact you push at deploy time.

## What this does not cover, and where the blind spots are

The clearest limitation is the hardware floor. No IOMMU groups, no vfio-pci binding, no Gatekeeper. Virtual machines are not addressed anywhere in the README, and a cloud instance with a paravirtualised NIC does not give you the PCI passthrough that GATEKEEPER_INTERFACES expects. If your mitigation point is a VPS, this is not deployable as written.

The second gap is scope. Gatekeeper is a network filter, not an HTTP-aware reverse proxy, so application layer protections that depend on inspecting requests are outside what the README describes. Nothing here mentions TLS termination, caching, or serving content.

The third gap is documentation depth on failure behaviour. The README does not document what the service logs on a misconfigured net.lua, how to read the runtime state of the mitigation blocks, or how to roll a policy change back. The maintenance tab you may expect from a web product does not exist here; the observable surface is systemd plus the link layer stack logging to the kernel.

On maintenance, the last push was on 2026-09-23 and the repository is not archived. The tagged releases trail that: v1.2.0 shipped on 2024-12-31, after v1.2.0-rc2 on 2024-09-05 and v1.2.0-rc1 on 2024-06-05. A compilation workflow badge sits at the top of the README. What that gap between last push and latest tag means for your upgrade path is not stated.

## Where Gatekeeper sits against commercial mitigation

The meaningful comparison is not with other open source filters but with what a provider buys. Commercial mitigation usually arrives as a scrubbing service in front of your prefixes, or as an appliance with a vendor dashboard and support contract. Gatekeeper is the appliance shape, self-hosted, where you own the hardware, the policy, and the patching schedule.

The difference in approach is visible in the source layout. The lls/ block implements its own ARP and neighbour discovery, and cps/kni.c provides a kernel communication path, which means the system owns forwarding and neighbour state rather than borrowing the host's. That is what allows it to work on bound interfaces at line rate, and it is also why it cannot be dropped onto a box where another service needs the same NIC.

For a large network, the centralized-policy design is the argument to make. Distributed decision making across sites sounds appealing until the policy has to be consistent to the packet, and the project is explicit that it centralizes policy for that reason.

## Conclusion

Gatekeeper is a fit for a service provider or enterprise network that already owns DPDK-capable hardware, has VT-d enabled in the BIOS, and can dedicate NICs and CPU cores to mitigation; it is the wrong choice for a single site, a VM, or anyone who needs HTTP proxy style filtering, because the enforcement path is Lua policy over bound packet interfaces. Before anything else, run ls /sys/kernel/iommu_groups and confirm it is non-empty, since an empty result means no NIC can be handed to DPDK. Then check that net.lua names your real front_ports, front_ips, back_ports and back_ips, because the packages ship placeholders that will not match your topology.

## FAQ

### Can Gatekeeper run on a virtual machine?

The setup documentation assumes bare metal with PCI passthrough. Gatekeeper needs vfio-pci to bind NICs to DPDK, which requires VT-d in the BIOS and IOMMU in the kernel, and the README does not address virtual machines.

### How do I check whether Gatekeeper prerequisites are satisfied on my host?

Run ls /sys/kernel/iommu_groups and ls /sys/class/iommu. If both outputs are not empty, IOMMU is detected and NICs can be bound; dmesg | grep -e DMAR is the BIOS level check for VT-d.

### Which Gatekeeper file must be edited after installing the Debian packages?

At minimum net.lua in /etc/gatekeeper, where you set front_ports, front_ips, back_ports and back_ips. You also need to set GATEKEEPER_INTERFACES in /etc/gatekeeper/envvars to the PCI addresses found with sudo lshw -c network -businfo.

## Sources

- [AltraMayor/gatekeeper on GitHub](https://github.com/AltraMayor/gatekeeper)
- [License: GPL-3.0](https://github.com/AltraMayor/gatekeeper/blob/master/LICENSE)
- [Project website](https://github.com/AltraMayor/gatekeeper/wiki)
- [README](https://github.com/AltraMayor/gatekeeper/blob/master/README.md)
- [Releases](https://github.com/AltraMayor/gatekeeper/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/altramayor-gatekeeper
