So I’ve been playing around a lot with OSSEC. Active responses are one of my favorite features. They remind me of the old firewall days when countermeasures existed whereby the firewall would detect an ongoing attack and fight back flooding the source IP with syn attacks or malformed packets. Yeah…sneaky goodness….but in the world of botnets and script kiddies those kinds of things are no longer effective. However, one use of active responses is to let you “tune” your firewall to situations at hand. It seems a little easier to work in local mode as the active responses are already set up, but it is possible to get them to work in the agent-server configuration as well.
Here is how they work…
The ossec.conf file lists both commands and active-responses. I’m going to describe how the firewall-drop active-response detects and drops attempts to login too many times to your server. The command configuration is shown here:
<command>
<name>firewall-drop</name>
<executable>firewall-drop.sh</executable>
<expect>srcip</expect>
<timeout_allowed>yes</timeout_allowed>
</command>
Now this is stock code included with OSSEC so you can get this working in minutes. Notice that the file structure is XML. That not only makes it easy to find and understand the code but it makes it simple to extend with any text editor as well.
Here we see the declaration of a command firewall-drop. It’s tied to a shell script called firewall-drop.sh (which lives at /var/ossec/active-response/bin on my server). This script and pretty much all scripts return (expect) a number of variables for you to use. The first is the action (add or delete) which is used to tell the script to add a firewall rule or delete a firewall rule. The second variable is the username (user) which isn’t actually used in this specific script. The third variable is the source ip address (srcip) which in our case is the ip of the guy trying to login unsuccessfully. The timeout_allowed goes hand in hand with the action variable. A timeout lets you put a rule in for say…600 seconds and then remove it again. This will thwart attackers automated attacks while not completely locking out the forgetful or fat-fingered admin.
The active response configuration in the ossec.conf file looks like this:
<active-response>
<!-- Firewall Drop response. Block the IP for
- 600 seconds on the firewall (iptables,
- ipfilter, etc).
-->
<command>firewall-drop</command>
<location>local</location>
<level>6</level>
<timeout>600</timeout>
</active-response>
The first part in between the <!—and –!> is just a descriptive comment. The command matches up with the command defined above. The location tells the script where to run the rule. In this case, this is a local installation of OSSEC so it’s set to local. The level is the trigger which kicks off this event. There are a set of predefined rules (in /var/ossec/rules) which categorize different detected events. One of these triggers is the detection of a brute force ssh password attack. There are numerous levels so I can’t go into all them here but you can easily drop in a look at the rules files on a standard installation for more info. Additionally, you can trigger on multiple types of things not just levels. There is a predefined rules group name called “sshd” so I could have used something like that as well. Unfortunately, the sshd rules group fires for successful and unsuccessful attempts so I couldn’t use that in this example.
Once things are configured a simple restart of the ossec system (/var/ossec/bin/ossec-control restart) will put it all into action.
So here is how it works. Someone tries to brute force attack the server on ssh and logs are generated in the secure log. OSSEC watches those logs, uses the rules file to detect the attack and sets the rule level. The the rule level fires off the active response script firewall-drop.sh which adds a rule to the iptables config effectively blocking the source ip address. After 600 seconds, the script is called again with the “delete” action and the rule is removed and all is well.
OSSEC is very powerful and this example just scrapes the surface. This has rapidly become one of my favorite open source tools of all time.