Replacing CSF / LFD with UFW and OSSEC

ufw

UFW and OSSEC active response. In my quest to see if I would like to replace Debian with all of its third party tooling with more up-to-date Ubuntu servers (also with third party tooling), I’ll dedicate the next couple of posts to cross off this list.

Starting at the top, today I’ll be replacing CSF / LFD with the uncomplicated firewall (UFW) and OSSEC active response for brute force detection and mitigation. The reason being that CSF / LFD community support is awful and that the software is not available via repositories.

Getting UFW up and running is very easy and we’ll be needing it for:

  1. Allowing management from certain IPs
  2. Opening up ports like 80 and 443
  3. Allowing specific ports from specific IPs
  4. Blocking everything else

Installing and enabling it and making sure you can keep managing your server via SSH:

# apt update
# apt install ufw
# ufw allow proto tcp from 134.17.116.8 to any port 22
# ufw enable

The above IP number should be your WAN IP number. From this point on the firewall is enabled and only from your WAN IP you can connect via SSH to your server.

Instant update: check if IPv6 is enabled and do so if you need it in /etc/default/ufw.

Open up ports 80 and 443 to the world, reload and check the firewall status:

# ufw allow 80/tcp
# ufw allow 443/tcp
# ufw status
# ufw reload

Denying ports is just as easy:

# ufw deny 80/tcp
# ufw deny 443/tcp
# ufw reload

You can also delete by rule number. Check it out and delete it with:

# ufw status numbered
# ufw delete 10
# ufw reload

Opening up ranges of ports is just as easy:

# ufw allow 10010:10070/tcp
# ufw allow 10010:10070/udp
# ufw reload

For our Icinga monitoring we’re adding port 5665 from a specific IPv4 and IPv6 address.

# ufw allow proto tcp from 37.18.170.10 to any port 5665
# ufw allow proto tcp from 2a01:7c8:ac8:33d:504:ff:feb6:3d7e to any port 5665
# ufw reload

All the rest will be blocked by default.

Next is OSSEC active response. The scope of this post is not describing a complete installation but I’m afraid I have to do a bit anyway. Let’s power through:

# echo 65536 > /proc/sys/fs/inotify/max_user_watches
# echo fs.inotify.max_user_watches = 65536 >> /etc/sysctl.d/60-local.conf
# wget -O - https://updates.atomicorp.com/installers/atomic | bash
# apt update
# apt install ossec-hids-server

In /etc/apt/sources.list.d/atomic.list change this:

deb https://updates.atomicorp.com/channels/atomic/ubuntu bionic main

Into this:

deb [arch=amd64] https://updates.atomicorp.com/channels/atomic/ubuntu bionic main

To avoid the (non critical) error you got at the above apt update.

Now you can (and should) change some important settings in /var/ossec/etc/ossec.conf like an alerting email address and which directories to actually monitor. Excerpt:

<ossec_config>
  <global>
    <email_notification>yes</email_notification>
    <email_to>support@yourdomain.com</email_to>
    <smtp_server>127.0.0.1</smtp_server>
    <email_from>root@server.yourdomain.com</email_from>
    <email_maxperhour>10</email_maxperhour>
  </global>

And stuff to scan and exclude:

  <syscheck>
    <!-- Frequency that syscheck is executed - default to every 22 hours -->
    <frequency>79200</frequency>
    <alert_new_files>yes</alert_new_files>
    <auto_ignore>no</auto_ignore>
    <scan_on_start>yes</scan_on_start>
    
    <!-- Directories to check  (perform all possible verifications) -->
    <directories report_changes="yes" realtime="yes" check_all="yes">/</directories>

    <!-- Files/directories to ignore -->
    <ignore>/data</ignore>
    <ignore>/dev</ignore>

You can also add or overwrite rules in the /var/ossec/rules/local_rules.xml like this:

<!-- Modify it at your will. -->

<group name="local,syslog,">

  <rule id="502" level="0" overwrite="yes">
    <if_sid>500</if_sid>
    <options>alert_by_email</options>
    <match>Ossec started</match>
    <description>Ossec server started.</description>
  </rule>

  <rule id="554" level="7" overwrite="yes">
    <category>ossec</category>
    <decoded_as>syscheck_new_entry</decoded_as>
    <description>File added to the system.</description>
    <group>syscheck,</group>
  </rule>

So that will be your basic config in a nutshell. Fire it up and you’re good to go:

# systemctl start ossec

Now to the whole purpose of the post: OSSEC active response, our replacement for LFD. Other tools in the same category are SSH Guard and Fail2Ban.

In /var/ossec/etc/ossec.conf check to see if the command is defined:

  <command>
      <name>firewall-drop</name>
      <executable>firewall-drop.sh</executable>
      <expect>srcip</expect>
      <timeout_allowed>yes</timeout_allowed>
  </command>

And when it is not, add it. In the same file add the appropriate active response (I recommend removing the existing ones):

  <active-response>
    <command>firewall-drop</command>
    <location>local</location>
    <rules_id>5712</rules_id>
    <timeout>3600</timeout>
    <repeated_offenders>360,720,1440</repeated_offenders>
  </active-response>

After restarting OSSEC, this will block IPs where brute force attempt originated for one hour (3600 seconds), and subsequent occurrences 360, 720 and 1440 minutes. You can easily test it while tailing /var/ossec/logs/active-responses.log and see the firewall-drop script in action.

Big chance you never want your management IP to be blocked. Whitelist it in the ossec.conf by adding it to the existing local host entries:

  <global>
    <white_list>127.0.0.1</white_list>
    <white_list>::1</white_list>
    <white_list>144.10.65.112</white_list>
  </global>

This will do it and is rock solid.

Update: check out Fail2Ban as well.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.