I saw a reference to ModSecurity while reading the following article on Slashdot: Writing Hardened Web Applications?. It is an Apache web server firewall module that is designed to look for and reject malicious access attempts. What follows are the trials and tribulations of installing it on debian.
Note: The web server is restarted after each configuration change below.
- Find the package and install it in debian: libapache-mod-security
- Have the web server not restart because of the following error: "(EAI 2)Name or service not known: mod_unique_id: unable to find IPv4 address"
- Figure out that an entry needed to be added to /etc/hosts for the servers IPv4 address and hostname.
- Configure ModSecurity using the example config files in /usr/share/doc/mod-security-common/examples/rules/.
- Get the following error: "Unable to retrieve collection (name "global", key "global"). Use SecDataDir to define data directory first."
- Set SecDataDir in modsecurity_crs_10_config.conf using the example from the reference manual. Repeat previous error do to directory permissions.
- Set SecDataDir to /tmp. Finally start up without complaining.
- While looking through one of the security rules, find a bug and retrieve the latest rule set from owasp.org.
- Configure the new rule set in modsecurity_crs_10_config.conf by following the instructions in INSTALL and setting SecRuleEngine DetectionOnly to prevent rejections during testing.
- Get the following error in modsecurity_crs_20_protocol_violations.conf: "Unknown variable REQBODY_ERROR"
- Comment out the 2 lines in modsecurity_crs_20_protocol_violations.conf that reference REQBODY_ERROR.
- Test using the following URL: "http://yourwebsite.com/test.vbs" and get a detection message in the web server error log.
- See the following error message from regular website traffic: "Rule execution error - PCRE limits exceeded (-8)"
- Determine that the following 2 lines needed to be added to modsecurity_crs_10_config.conf: "SecPcreMatchLimit 150000" "SecPcreMatchLimitRecursion 150000"
- See the following error message from regular website traffic: "SQL injection attempts ..."
- Determine that it was rejecting legitimate requests that happened to have "div" in the URL or "2or" in the session cookie.
- Disable the SQL injection rule by removing the links in activated_rules/ with "rm *sql_injection*"
After running in test mode for a couple of days, set SecRuleEngine On
Test with the following url and make sure the request is rejected: "http://yourwebsite.com/?a=ftp://127.1.1.1"
Update: 8 Jan 2012
I wrote my own custom rule to catch hack attempts via certain php page names such as phpmyadmin.
Then I implemented log-guardian to monitor the web server error log files for hack attempts and write a message to authfail so that it will smoke the ip address (drop it in iptables) after 4 hack attempts.