OSSEC-HIDS Module

by blkwolf

This is a work in progress…

Install ossec-hids-agent on monitored servers and workstations.

This module downloads the defined version of ossec from a defined website extracts the files, configures the preloaded-vars.conf file for unattended install, runs the installation script and then copies and manages the master ossec.conf and rules files.

Usage Example

# OSSEC master server internal network
node 'ossecsrv.mydomain.net' { include baseserver, ossec::server }

# Generic server / OSSEC agent
node 'mailsrv.mydomain.net' { include baseserver, ossec::agent }

Code

modules/ossec/manifests/init.pp

# call this module via:  node 'name' {include ossec::server}
# replace server with  local or agent  depending on the type of ossec install you
# want to perform.

class ossec {

    # I will move this define to a common definition module later        
    define download_file(
            $site="",
            $cwd="",
            $creates="",
            $require="",
            $user="") {                                                                                         

        exec { $name:                                                                                                                     
            command => "/usr/bin/wget ${site}/${name}",                                                         
            cwd => $cwd,
            creates => "${cwd}/${name}",                                                              
            require => $require,
            user => $user,                                                                                                          
        }
    }        


    class install{

        $ossecversion = "ossec-hids-2.4.1" 
        $ossecfile = "$ossecversion.tar.gz"
        $workdir = "/opt/working"


        file { "/opt/working":    
            ensure  => directory,
            owner => root,
            group => root,
            mode => 760, 
        }

        download_file {"${ossecfile}":                                                                                                                              
           # site => "http://www.ossec.net/files",   # best to use a local copy if working with lots of machines
           site => "http://webserver.mydomain.local/pub",
           cwd => "${workdir}",                                                                            
           creates => "${workdir}/$name",                                                                  
           require => File["/opt/working"],                                                                  
           user => root,                                                                                                              
       }

        exec {"extract-ossec":
           cwd => "${workdir}",
           command => "/bin/tar xzf ${ossecfile}",
           creates => "${workdir}/${ossecversion}",
           require => Download_file["${ossecfile}"],
           user => root,
        }

    }


    class server inherits ossec::install {

        $ossectype = "server"

        file {"ossecvars":
            path => "${workdir}/${ossecversion}/etc/preloaded-vars.conf",
            ensure => present,
            content => template("ossec/preloaded-vars.conf-${ossectype}"), 
            require => Exec["extract-ossec"],

        }

        exec {"install-ossec":
            cwd => "${workdir}/${ossecversion}",
            command => "${workdir}/${ossecversion}/install.sh",
            creates => "/var/ossec/etc",
            user => root,
            require => File["ossecvars"],
        }


        service { "ossec":
            enable => true,
            ensure => running,
        }

        # manage ossec.conf file
        file { "ossec.conf":
            path => "/var/ossec/etc/ossec.conf",
            ensure  => present, owner => root, group => ossec, mode => 550, 
            content => template("ossec/ossec-conf-${ossectype}.erb"),    
        } 

        # manage the /var/ossec/rules 
        file { "ossec-rules":
            path => "/var/ossec/rules",
            checksum => "mtime",
            ensure  => directory, owner => root, group => ossec, mode => 550, 
            source  => "puppet://$server/ossec/ossec-rules",
            recurse => true,
            ignore  => [ ".svn" ],
        }

        exec {ossec-restart:
            command => "/var/ossec/bin/ossec-control restart",
            subscribe => File[ "ossec.conf" , "ossec-rules" ],
            refreshonly => true,  # Only run command if monitored files change       
        }

    }



    class local inherits ossec::install {

        $ossectype = "local"

        file {"ossecvars":
            path => "${workdir}/${ossecversion}/etc/preloaded-vars.conf",
            ensure => present,
            content => template("ossec/preloaded-vars.conf-${ossectype}"), 
            require => Exec["extract-ossec"],

        }

        exec {"install-ossec":
            cwd => "${workdir}/${ossecversion}",
            command => "${workdir}/${ossecversion}/install.sh",
            creates => "/var/ossec/etc",
            user => root,
            require => File["ossecvars"],
        }


        service { "ossec":
            enable => true,
            ensure => running,
        }

        # manage ossec.conf file
        file { "ossec.conf":
            path => "/var/ossec/etc/ossec.conf",
            ensure  => present, owner => root, group => ossec, mode => 550, 
            content => template("ossec/ossec-conf-${ossectype}.erb"),    
        } 

        # manage the /var/ossec/rules 
        file { "ossec-rules":
            path => "/var/ossec/rules",
            checksum => "mtime",
            ensure  => directory, owner => root, group => ossec, mode => 550, 
            source  => "puppet://$server/ossec/ossec-rules",
            recurse => true,
            ignore  => [ ".svn" ],
        }

        exec {ossec-restart:
            command => "/var/ossec/bin/ossec-control restart",
            subscribe => File[ "ossec.conf" , "ossec-rules" ],
            refreshonly => true,  # Only run command if monitored files change       
        }

    }


    class agent inherits ossec::install {    
        $ossectype = "agent"

        file {"ossecvars":
            path => "${workdir}/${ossecversion}/etc/preloaded-vars.conf",
            ensure => present,
            content => template("ossec/preloaded-vars.conf-${ossectype}"), 
            require => Exec["extract-ossec"],

        }

        exec {"install-ossec":
            cwd => "${workdir}/${ossecversion}",
            command => "${workdir}/${ossecversion}/install.sh",
            creates => "/var/ossec/etc",
            user => root,
            require => File["ossecvars"],
        }


        service { "ossec":
            enable => true,
            ensure => running,
        }

        # manage ossec.conf file
        file { "ossec.conf":
            path => "/var/ossec/etc/ossec.conf",
            ensure  => present, owner => root, group => ossec, mode => 550, 
            content => template("ossec/ossec-conf-${ossectype}.erb"),    
        } 

        exec {ossec-restart:
            command => "/var/ossec/bin/ossec-control restart",
            subscribe => File["ossec.conf"],
            refreshonly => true,  # Only run command if monitored files change       
        }
    }
}

modules/ossec/templates/ossec-conf-server.erb

### Create templates for ossec-conf-local and agent
<ossec_config>
  <global>
    <email_notification>yes</email_notification>
    <email_to>myemail@mydomain.local</email_to>
    <smtp_server>mail-server.mydomain.local</smtp_server>
    <email_from>ossecm@<%= fqdn %></email_from>
  </global>

  <rules>
    <include>rules_config.xml</include>
    <include>pam_rules.xml</include>
    <include>sshd_rules.xml</include>
    <include>telnetd_rules.xml</include>
    <include>syslog_rules.xml</include>
    <include>arpwatch_rules.xml</include>
    <include>symantec-av_rules.xml</include>
    <include>symantec-ws_rules.xml</include>
    <include>pix_rules.xml</include>
      ==== Depreciated for Readability =====
  </rules>  

  <syscheck>
    <!-- Frequency that syscheck is executed - default to every 22 hours -->
    <frequency>79200</frequency>

    <!-- Directories to check  (perform all possible verifications) -->
    <directories check_all="yes">/etc,/usr/bin,/usr/sbin</directories>
    <directories check_all="yes">/bin,/sbin</directories>

    <!-- Files/directories to ignore -->
    <ignore>/etc/mtab</ignore>
    <ignore>/etc/mnttab</ignore>
    <ignore>/etc/hosts.deny</ignore>


    <!-- Windows files to ignore -->
    <ignore>C:\WINDOWS/System32/LogFiles</ignore>
    <ignore>C:\WINDOWS/Debug</ignore>

  </syscheck>

  <rootcheck>
    <rootkit_files>/var/ossec/etc/shared/rootkit_files.txt</rootkit_files>
    <rootkit_trojans>/var/ossec/etc/shared/rootkit_trojans.txt</rootkit_trojans>
    <system_audit>/var/ossec/etc/shared/system_audit_rcl.txt</system_audit>
    <system_audit>/var/ossec/etc/shared/cis_debian_linux_rcl.txt</system_audit>
    <system_audit>/var/ossec/etc/shared/cis_rhel_linux_rcl.txt</system_audit>
    <system_audit>/var/ossec/etc/shared/cis_rhel5_linux_rcl.txt</system_audit>
  </rootcheck>

  <global>
    <white_list>127.0.0.1</white_list>
    <white_list>^localhost.localdomain$</white_list>
    <white_list>192.168.77.22</white_list>
  </global>

  <remote>
    <connection>secure</connection>
  </remote>

  <alerts>
    <log_alert_level>1</log_alert_level>
    <email_alert_level>7</email_alert_level>
  </alerts>

  <command>
    <name>host-deny</name>
    <executable>host-deny.sh</executable>
    <expect>srcip</expect>
    <timeout_allowed>yes</timeout_allowed>
  </command>  

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

  <command>
    <name>disable-account</name>
    <executable>disable-account.sh</executable>
    <expect>user</expect>
    <timeout_allowed>yes</timeout_allowed>
  </command>  

  <command>
    <name>restart-ossec</name>
    <executable>restart-ossec.sh</executable>
    <expect></expect>
  </command>


  <command>
    <name>route-null</name>
    <executable>route-null.sh</executable>
    <expect>srcip</expect>
    <timeout_allowed>yes</timeout_allowed>
  </command>


  <!-- Active Response Config -->
  <active-response>
    <!-- This response is going to execute the host-deny
       - command for every event that fires a rule with
       - level (severity) >= 6.
       - The IP is going to be blocked for  600 seconds.
      -->
    <command>host-deny</command>
    <location>local</location>
    <level>6</level>
    <timeout>600</timeout>
  </active-response>

  <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>  

  <!-- Files to monitor (localfiles) -->

  <localfile>
    <log_format>syslog</log_format>
    <location>/var/log/messages</location>
  </localfile>

  <localfile>
    <log_format>syslog</log_format>
    <location>/var/log/secure</location>
  </localfile>

  <localfile>
    <log_format>syslog</log_format>
    <location>/var/log/maillog</location>
  </localfile>
</ossec_config>

modules/ossec/templates/preloaded-vars-conf-local

### Create templates for preloaded-vars-conf-agent and server
USER_LANGUAGE="en" 
USER_NO_STOP="y"
USER_INSTALL_TYPE="local"
USER_DIR="/var/ossec"
USER_DELETE_DIR="y"
USER_ENABLE_ACTIVE_RESPONSE="y"
USER_ENABLE_SYSCHECK="y"
USER_ENABLE_ROOTCHECK="y"
USER_UPDATE_RULES="y"
USER_ENABLE_EMAIL="y"
USER_EMAIL_ADDRESS="myemailaddress@mydomain.local"
USER_ENABLE_FIREWALL_RESPONSE="y"
USER_WHITE_LIST="192.168.77.22"