💾 Archived View for jb55.com › log › 2021-09-15-wireguard-ebpf.gmi captured on 2021-12-04 at 18:04:22. Gemini links have been rewritten to link to archived content

View Raw

More Information

⬅️ Previous capture (2021-11-30)

-=-=-=-=-=-=-

Monitor incoming WireGuard packets with eBPF

Recently I was trying to debug why one of my computers couldn't connect to another computer over wireguard. I wrote this quick bpftrace script to show incoming wireguard packets before they get decrypted:

#include <linux/skbuff.h>
#include <linux/ip.h>

struct peer_arg {
  struct wg_peer *peer;
};

kprobe:wg_index_hashtable_lookup {
  @peerarg = (struct peer_arg *)arg3;
}

kretprobe:wg_index_hashtable_lookup {
  @peer = @peerarg->peer;
}

kprobe:wg_packet_receive {
  @skb = (struct sk_buff*)arg1;
  @ipheader = ((struct iphdr *) (@skb->head + @skb->network_header));
  @version = (@ipheader->version) >> 4;
}

kretprobe:wg_packet_receive {
  printf("wg_packet_receive peer(%x) [%d] %d\t%s > %s (%d)\n", 
    @peer, 
    @version, 
    @ipheader->protocol, 
    ntop(@ipheader->saddr), 
    ntop(@ipheader->daddr),
    @skb->len);
}

Running `sudo bpftrace wireguard.bt` we can see if our machine is receiving any encrypted wireguard packets:

Attaching 4 probes...
wg_packet_receive peer(c690000) [0] 17	192.168.86.24 > 192.168.86.201 (96)
wg_packet_receive peer(c690000) [0] 17	192.168.86.24 > 192.168.86.201 (96)
wg_packet_receive peer(c690000) [0] 17	192.168.86.24 > 192.168.86.201 (96)

Nice! eBPF is useful because we can hook into any kernel or userspace function. I simply went into the linux source code, found the functions that receive the packet, and then added hooks for them! I hook into a few functions so that I can gather information about the peer, such as peer id and ip.

There are a few hook types:

bpftrace allows us to quickly write scripts that take advantage of this magic linux kernel machinery

As a side note, I recently added user-defined eBPF static tracepoints to bitcoin-core, you can read about what some people are doing with them here:

https://blog.coinbase.com/userspace-statically-defined-tracing-support-for-bitcoin-core-e4076cd3e07

There are lots of fun things you can do with eBPF, what will you use them for?