Monitoring Drupal with OSSEC
Drupal offers a number of defensive configurations that can enable a site to more proactively detect attacks and alert administrators. One such module is the Login Security module. This module detects brute force attacks and locks out attackers after a certain number of failed authentication attempts. This module works quite well, but if you are using a host based intrusion detection system (HIDS) like OSSEC it would be much more efficient to utilize your existing HIDS infrastructure to alert you to these sorts of attacks. Fortunately Drupal 6 includes the Syslog module by default, which allows Drupal to write log files to the system log. OSSEC is extensible in that you can write custom decoders for specific applications. These features combined allow you to utilize OSSEC to monitor your Drupal site.
The first step in implementing an OSSEC monitor of your Drupal site is to enable the Syslog module. This can be done via your Drupal 6 site from the URL ?q=admin/build/modules. Once the syslog module is enabled you need to install the OSSEC client, or OSSEC in standalone mode, on your Drupal host. After Drupal is configured to write to the syslog and OSSEC is configured to monitor the syslog you have to utilize a custom decoder to actually parse the Drupal messages. This decoder is a little tricky because OSSEC's regular expression engine isn't very full featured and the Drupal syslog entries are delimited by a pipe, which is a special character in regular expressions. Using the following decoder should work for OSSEC version 2.2 and 2.3:
<!-- Drupal decoder. By Justin C. Klein Keane Drupal 6 must be configured with Syslog module enabled Sample: Jun 16 11:45:29 webdev drupal: 172.16.46.129 http://172.16.46.129/drupal-6.16|1276703129|user|172.16.46.1|http://172.16.46.129/drupal-6.16/node?destination=node||0||Login attempt failed for admin. --> <decoder name="drupal"> <program_name>^drupal</program_name> <prematch>\d+.\d+.\d+.\d \S+|\d+|\w+|</prematch> <regex offset="after_prematch">(\d+.\d+.\d+.\d+)\|(\.+)\|\.*\|\d+\|\.*\|(\.+)</regex> <order>srcip,url,data</order> </decoder>
Once the decoder is in place (it should be added to the decoder file located at /var/ossec/etc/decoder.xml) it's possible to write any number of rules to utilize the entries from Drupal. What follows are a few sample rules that will detect common attacks (such as brute force login attempts). These rules can be added to /var/ossec/rules/local_rules.xml:
<!-- DRUPAL RULES (use custom drupal decoder) --> <rule id="104110" level="3"> <decoded_as>drupal</decoded_as> <match>Drupal</match> <description>Drupal syslog message</description> </rule> <rule id="104120" level="6"> <if_sid>104110,1002</if_sid> <match>Login attempt failed</match> <description>Drupal failed login!</description> </rule> <rule id="104225" level="11"> <if_sid>104120</if_sid> <!-- Note "admin" should be changed to whatever your uid 1 account is --> <match>Login attempt failed for admin.</match> <description>Drupal failed attempt to log in as admin!</description> </rule> <rule id="104130" level="10" frequency="4" timeframe="360"> <if_matched_sid>104120</if_matched_sid> <description>Possible Drupal brute force attack </description> <description>(high number of logins).</description> </rule> <rule id="104140" level="10"> <if_sid>104110</if_sid> <match>Illegal choice</match> <description>Drupal possible input injection (XSS/XSRF) attack!</description> </rule> <rule id="104150" level="7"> <if_sid>104110,1002</if_sid> <match>Access denied</match> <description>Drupal access denied error (permissions rejected).</description> </rule> <rule id="104160" level="10"> <if_sid>104150</if_sid> <match>admin/</match> <description>Drupal access denied to admin screen.</description> </rule>
You may want to tune the alert levels listed above to suit your particular installation as well. By default OSSEC will send e-mail to admins on alerts with level 7 or greater. You can check this setting in your /var/ossec/etc/ossec.conf file.