Selectively shady
Hi! As far as I understand this module, it marks all packets from a host. My services are mostly benignn but some of them (e.g. my private smtpd) are set up to become hostile depending on what the peer sends (e.g. requesting login methods that I don't like). Could you adapt your module so I can flag specific connections just before starting to send evil data? Would be nice if I could use the combination of process ID + file descriptor number to select them. I currently don't have a use case to revoke this decision (i.e. stop marking that connection's data as evil), but if it's few effort, that feature would probably be nice to have as well.
PS: Would be even better if we can figure out a way to allow non-superuser processes to configure the evil bit for sockets they have write access to.
Oh, I somehow missed this issue, and for so long!
This module uses the netfilter framework to modify all outgoing IPv4 packets. I'm not sure what info we have on packets at this level, other than the raw IP itself. The sk_buff struct has some interesting information that might help in identifying who generated the packet. Setting up and maintaining that data in the module would be an interesting adventure though! I might actually get to use kobjects and such. Having the process modifies it's own socket that the module could detect later would be nice. Maybe there's some field I can hijack to do some testing...
People have also commented on having an iptables extension. I need to dig in there and see if there are features already implemented there that provide the level of flexibility we're all looking for. I've only dabbled a little bit with iptables to do blocking based on geolocation. I'm not sure how dynamic iptables gets.
Haha, oh boy. I'm revisiting this after a long time b/c I realized that the network namespaces could help here. You could create a network namespace and then when your service needs to become evil they just use that namespace instead. How that actually works in terms in terms of userspace I'm not entirely sure... I think it would be similar to setting up a VPN and then figuring out how to get your program to use it. Creating a network and then passing it into the module as an argument might be an easy way to get there. It might be possible to lookup a network by name, get its namespace, and then add this filter to it.
https://github.com/alwilson/evil/blob/096ba9bf408fc714dc09a2e41be9ec03fc50ee4a/evil.c#L30
Would one virtual network interface be enough or would I need one per connection? The latter would be a bit adventurous, keeping a pool of spare idle VNIs and setting up round robin logíc to distribute incoming connection attempts. (And the usual pool management of course.)
One of my use cases is handling dubious behavior on SMTP, and unfortunately my SMTP is really popular with some people.