pwru
pwru copied to clipboard
Packet, where are you? -- eBPF-based Linux kernel networking debugger
pwru (packet, where are you?)

pwru is an eBPF-based tool for tracing network packets in
the Linux kernel with advanced filtering capabilities. It allows fine-grained
introspection of kernel state to facilitate debugging network connectivity issues.
The following example shows where the packets of a curl request are dropped
after installing an IP tables rule:

Quick start with Vagrant
If you have Vagrant installed, you can run the above example with the following commands.
-
In a terminal (terminal 1), bring up the Vagrant box:
$ vagrant upThis will take a few minutes to download and provision the box.
-
Connect to the Vagrant box:
$ vagrant ssh -
Build
pwru:$ cd /pwru $ make -
Run
pwru:$ sudo ./pwru --filter-dst-ip=1.1.1.1 --filter-dst-port=80 --filter-proto=tcp --output-tuple -
In a new terminal (terminal 2), connect to the Vagrant box:
$ vagrant ssh -
In terminal 2, run
curlto generate some traffic to 1.1.1.1:$ curl 1.1.1.1Observe the output of
pwruin terminal 1. -
In terminal 2, add an
iptablesrule to block traffic to 1.1.1.1:$ sudo iptables -t filter -I OUTPUT 1 -m tcp --proto tcp --dst 1.1.1.1/32 -j DROP -
In terminal 2, run
curlto generate some traffic to 1.1.1.1:$ curl 1.1.1.1Observe the output of
pwruin terminal 1. -
To clean up, press
Ctrl+Cto terminatepwruin terminal 1, exit both shells, and run:$ vagrant destroy
Running
Requirements
pwru requires >= 5.3 kernel to run. For --output-skb >= 5.9 kernel is required.
The following kernel configuration is required.
| Option | Note |
|---|---|
| CONFIG_DEBUG_INFO_BTF=y | Available since >= 5.3 |
| CONFIG_KPROBES=y | |
| CONFIG_PERF_EVENTS=y | |
| CONFIG_BPF=y | |
| CONFIG_BPF_SYSCALL=y |
You can use zgrep $OPTION /proc/config.gz to validate whether option is enabled.
Downloading
You can download the statically linked executable for x86_64 arch which includes the eBPF bytecode from the release page.
Usage
> ./pwru --help
Usage of ./pwru:
--filter-dst-ip string filter destination IP addr
--filter-dst-port uint16 filter destination port
--filter-func string filter kernel functions to be probed by name (exact match, supports RE2 regular expression)
--filter-mark uint32 filter skb mark
--filter-netns uint32 filter netns inode
--filter-proto string filter L4 protocol (tcp, udp, icmp, icmp6)
--filter-src-ip string filter source IP addr
--filter-src-port uint16 filter source port
--kernel-btf string specify kernel BTF file
--kmods strings list of kernel modules names to attach to
--output-limit-lines uint exit the program after the number of events has been received/printed
--output-meta print skb metadata
--output-relative-timestamp print relative timestamp per skb
--output-skb print skb
--output-stack print stack
--output-tuple print L4 tuple
--per-cpu-buffer int per CPU buffer in bytes (default 4096)
--version show pwru version and exit
If multiple filters are specified, all of them have to match in order for a packet to be traced.
The --filter-func switch does an exact match on function names i.e.
--filter-func=foo only matches foo(); for a wildcarded match, try
--filter-func=".*foo.*" instead.
Developing
Dependencies
- Go >= 1.16
- LLVM/clang >= 1.12
Building
make
Alternatively, you can build and run in the Docker container:
docker build -t pwru .
docker run --privileged -it pwru [filter1] [filtern]
Contributing
pwru is an open source project licensed under GPLv2. Everybody is
welcome to contribute. Contributors are required to follow the
Contributor Covenant Code of Conduct
and must adhere to the Developer Certificate of Origin
by adding a Signed-off-by line to their commit messages.
Logo Credits
The detective gopher is based on the Go gopher designed by Renee French.