I hope people are cautious when using p0f. When accessing it on my iPhone 6 from my cell network (not Wi-Fi) in Chrome, it reports the following:
Detected OS = Linux 3.x [generic]
HTTP client = unknown
Network link = Ethernet or modem
Distance = 11
Language = English
Uptime = 36 days 18 hrs 26 min (modulo 198 days)
WARNING: Inconsistent fingerprints, probably indicative of
IP sharing or proxyingNote: looks like you're hitting this
page through a proxy (your Via header is set). This
affects the apparent identity of your system on TCP/IP
level.
Perhaps my cell network is acting via proxy (wouldn't surprise me), but your average user won't know this. If you're going to filter or identify traffic based on p0f, be careful to not negatively impact honest users who might be misidentified (either because p0f got the fingerprint wrong or because there's some proxy in the middle).
My first thought reading this was "lcamtuf works at cloudflare now?" Nope, cloudflare just took an awesome tool of his and made the kernel able to filter packets based on its signatures using bpf. Pretty cool.
It'd be nice to know what if any false indications this triggers. "we want to ratelimit" -- so is there any pathological behavior wrt the legit traffic (especially with ever-more-cleverly-reducing-round-trip protocols like QUIC)?
The pessimistic case is when the attack signature matches exactly the signature of real operating system. For example, if the attack resembles Linux, with the p0f-to-BPF you can generate a BPF that matches Linux SYN packets. This allows you to block these packets, and this of course can affect traffic from Linux machines.
pass in proto tcp from any to any port www synproxy state
I'm being a little tongue-in-cheek, though. It seems your solution is either a superset of the above, or perhaps just an alternative. And compiling p0f to BPF is definitely an interesting topic and quite noteworthy.
Though, I would dispute the notion that compiling to BPF is either simpler or more secure. The BPF JIT has been responsible for several kernel exploits recently. The original BPF was much simpler but irrelevant at this point. While I believe the design of the contemporary incarnation in Linux is still provably correct, the implementation manifestly still has bugs. And from a user perspective it's really difficult to beat the syntax of PF's pf.conf. pf.conf can't be emulated by using a front-end configuration generator for iptables + company as the semantics of many tasks require implementation logic in the kernel, whether as extensions to BPF or to the networking subsystem.
This is old and very good tool for passive identification. I wrote my engineer thesis based on p0f 10 years ago. It mostly uses differences in implementation of TCP/IP stacks between OS and couple of other things to recognize the OS. You can add new fingerprints yourself.