Implementing port knocking with eBPF
Contents
Background
I recently learnt about a security mechanism called port knocking. It’s a method to secure a network by requiring a sequence of UDP packets be sent to specific ports before the intended port or network is accessible, like a certain knock which no Toon can resist.
At the same time I’ve been wanted to try a bit of eBPF development. I find eBPF a fascinating technology. It enables you to load compiled code into the kernel. The kernel then verifies the code is ‘correct’ and runs it! It can be used to implement all sorts of functionality, from tracing to security.
Implementing port knocking with eBPF seemed like a fun challenge!
Components
The project is split into three main components:
- eBPF program - C, compiled to BPF bytecode
- eBPF loader - C++, allowing for easy loading of the eBPF skeleton (auto-generated by
bpftool
and embedded into a header file). I also selfishly wanted to flex my C++ muscle for a future project… - End-to-end tests - Python-based tests to ensure everything works as expected.
Interesting learnings so far
- Loading eBPF programs within Docker and the Linux capabilities, security tweaks required to do so
- Linux virtual Ethernet devices, namespaces and how to use them to test eBPF programs
- Exploring the difference between
std::atomic<bool>
,volatile bool
andvolatile sig_atomic_t
- The delights provided by the C++23 standard…
To be continued…
I hope to update this post with more details as I continue to work on the project!