I am building a Wireguard tool for myself and I would like to receive events when a peer connects or disconnects. Does someone know if this is possible through some kernel API or EBPF?
Depending on how your connection is negotiated, it may partially not be possible due to the architecture of Wireguard. There is likely some way to hook into capturing handshakes between clients (initial handshake, key rotations). To determine disconnects and reconnects however is a challenge. There are no explicit states in the connection. The closest thing to disconnect monitoring is utilizing a keep alive timeout on the connections. There are some caveats to using a keep alive timer, however. Additionally, not every connection may use a keep alive timeout, making this a full solution infeasible.
Detailed information about Wireguard session handling can be found in section 6 of this PDF.
I know that Wireguard considers some sessions alive and I was hoping to somehow hook into that. For my use case it’s enough if it works with the implementation in the Linux kernel. I guess I’ll have to take a look to see if there’s anything I can hook into with EBPF.
Aren’t the keep-alive settings declared in the connection itself? Or are you saying some clients may not respect that?
If OP controls both endpoints, it may be easier, but still: I know of no Wireguard implementation that provides hooks for something like this.
Their best bet is probably their own SYN/ACK client-server solution - a dead-man’s switch, separate from Wireguard but connected only over that interface.
Persistent keep alive is configured per connection by all peers (server and client typically). As I understand it, Wireguard’s peer-based architecture will let both client and server peers define an optional persistent keep alive timer in order to send heartbeat packets on interval. Otherwise Wireguard on either peer may keep opening and closing connections for inactivity (or get its connections forcefully closed externally) if traffic isn’t being regularly sent. This can occur even though the network interfaces for Wireguard on both communicating peers remain up.
I do agree that running some kind of health-check handshake service over the Wireguard tunnel is an easy enough way to periodically check the state of the connection between peers.
Thinking of the top if my head. I haven’t tested this.
wg show lists connect peers, amongst other things. You can pipe that to grep to filter for just the peers.
With watch, you can periodically do the commands mentioned above, and execute another command on change.
With ntfy.sh you can easily get notifications on android or iphone.
The whole thing would look like.
watch --chgexit "wg show | grep peer" && curl -d "Someone (dis)connected!" ntfy.sh/mysecrettopic