Last night, I spent a long while trying to get mod_security working on this web server. Installation was simple, thanks to the FreeBSD ports system. Configuration was another matter entirely.
Not having much experience of web application firewalls, I opted for the ModSecurity Core Rules to give me a head start. These are essentially some pre-provided Apache configs that you can include into your existing config files. It seems like a good idea, although some of the rules are questionable—I don’t really think that “googlebot visited” is a security event.
After configuring minor details like the audit log file, I deployed it. Hmmm, front page still comes up, so let’s commit the configs to subversion. Booom.
It turns out that the Core Rules don’t interact well with subversion in a number of minor, but irritating ways. For example, they expect every request to come with an Accept header. And only certain Content-Types can be submitted to the web server. It’s all minor stuff, and relatively easy to work out how to fix. This gave me a good feel for what’s involved in properly customizing mod_security.
This afternoon, I came back and inspected the logs. There are nearly 400 events from mod_security. Quite a lot of these were people trying to spam my trac instance (which I’ve now finally gotten under control) and blog. Importantly however, I noticed that it had blocked a legitimate user of an RSS feed.
At this point, I realised the problem. mod_security needs a lot of work to set up and maintain. You customize it towards a specific purpose—your application. But I’m running lots of applications. So it becomes harder and harder to customize correctly (particularly as I’m not running everything on it’s own virtualhost), because a rule that’s correct for subversion might well not be correct for trac. Or more to the point, it’s going to take me a very long time to get it configured correctly. So I’ve switched off mod_security for now.
Don’t take this as a slur on mod_security. It’s a useful tool, and I will be using it again. But it’s far easier to configure when you’re covering a single application running inside that Apache. And you’ll still need to invest a good chunk of time to get it set up correctly (a very iterative process).