gemini-capsule

My gemini capsule
git clone git://jb55.com/gemini-capsule
Log | Files | Refs

2021-09-15-wireguard-ebpf.gmi (2301B)


      1 
      2 # Monitor incoming WireGuard packets with eBPF
      3 
      4 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:
      5 
      6 
      7 ```
      8 #include <linux/skbuff.h>
      9 #include <linux/ip.h>
     10 
     11 struct peer_arg {
     12   struct wg_peer *peer;
     13 };
     14 
     15 kprobe:wg_index_hashtable_lookup {
     16   @peerarg = (struct peer_arg *)arg3;
     17 }
     18 
     19 kretprobe:wg_index_hashtable_lookup {
     20   @peer = @peerarg->peer;
     21 }
     22 
     23 kprobe:wg_packet_receive {
     24   @skb = (struct sk_buff*)arg1;
     25   @ipheader = ((struct iphdr *) (@skb->head + @skb->network_header));
     26   @version = (@ipheader->version) >> 4;
     27 }
     28 
     29 kretprobe:wg_packet_receive {
     30   printf("wg_packet_receive peer(%x) [%d] %d\t%s > %s (%d)\n", 
     31     @peer, 
     32     @version, 
     33     @ipheader->protocol, 
     34     ntop(@ipheader->saddr), 
     35     ntop(@ipheader->daddr),
     36     @skb->len);
     37 }
     38 ```
     39 
     40 Running `sudo bpftrace wireguard.bt` we can see if our machine is receiving any encrypted wireguard packets:
     41 
     42 ```
     43 Attaching 4 probes...
     44 wg_packet_receive peer(c690000) [0] 17	192.168.86.24 > 192.168.86.201 (96)
     45 wg_packet_receive peer(c690000) [0] 17	192.168.86.24 > 192.168.86.201 (96)
     46 wg_packet_receive peer(c690000) [0] 17	192.168.86.24 > 192.168.86.201 (96)
     47 ```
     48 
     49 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.
     50 
     51 There are a few hook types:
     52 
     53 * kprobe - hook into the start of a function call
     54 * kretprobe - hook into a function return
     55 * uprobe - hook process userspace functions
     56 * uretprobe - same as kretprobe but for userspace functions
     57 * usdt - custom user-space tracepoints, add a hook to anywhere in your code!
     58 
     59 bpftrace allows us to quickly write scripts that take advantage of this magic linux kernel machinery
     60 
     61 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:
     62 
     63 => https://blog.coinbase.com/userspace-statically-defined-tracing-support-for-bitcoin-core-e4076cd3e07
     64 
     65 There are lots of fun things you can do with eBPF, what will you use them for?