Steve.org.uk

Steve Kemp's Homepage

 

Slaughter

 

Primitives

Slaughter : Primitives

slaughter allows you to write your policies in a combiantion of pure-perl, and a set of primitive functions it provides.

This page documents the primitives that are supported/provided along with the parameters that are used - if you wish to add new primitives this is documented elsewhere.

Alert

The alert primitive is used to send an email. Sample usage is:

 Alert( Message => "Server on fire: $hostname",
             To => 'steve[at]steve.org.uk',
        Subject => "Alert: $fqdn" );

The following parameters are available:

From [default: "root"]

The sender address of the email.

Message [mandatory]

The content of the message to send

Sendmail [default: "/usr/lib/sendmail -t"]

The path to the sendmail binary.

Subject [mandatory]

The subject to send.

To [mandatory]

The recipient of the message.

AppendIfMissing

This primitive will open a local file, and append a line to it if it is not already present.

  AppendIfMissing( File => "/etc/hosts.allow",
                   Line => "All: 1.2.3.4" );

The following parameters are available:

File [mandatory]

The filename which should be examined and potentially updated.

Line [mandatory]

The line which should be searched for and potentially appended.

CommentLinesMatching

This primitive will open a local file, and comment out any line which matches the specified regular expression.

  if ( CommentLinesMatching( Pattern => "telnet|ftp",
                             File    => "/etc/inetd.conf" ) )
  {
        RunCommand( Cmd => "/etc/init.d/inetd restart" );
  }

The following parameters are available:

Comment [default: "#"]

The value to comment out the line with.

File [mandatory]

The filename which should be examined and potentially updated.

Pattern [mandatory]

The regular expression to match with.

The return value of this function is the number of lines updated, or -1 if the file could not be opened.

DeleteFilesMatching

This primitive will delete files with names matching a particular pattern, recursively.

  #
  #  Delete *.dpkg-old - recursively
  #
  DeleteFilesMatching( Root    => "/etc",
                       Pattern => "\\.dpkg-old\$" );

The following parameters are available:

Root [mandatory]

The root directory from which the search begins.

Pattern [mandatory]

The regular expression applied to filenames.

The return value of this function is the number of files deleted.

DeleteOldFiles

This primitive will delete files older than the given number of days from the specified directory.

Note unlike "DeleteFilesMatching" this function is not recursive.

  #
  #  Delete files older than ten days from /tmp.
  #
  DeleteFilesMatching( Root  => "/tmp",
                       Age   => 10 );

The following parameters are available:

Age [mandatory]

The age of files which should be deleted.

Root [mandatory]

The root directory from which the search begins.

The return value of this function is the number of files deleted.

IdenticalContents

The IdenticalContents primitive is used to compare whether two filenames have identical contents.

The following is an example of usage:

    #
    #  If the current contents don't match then move into place.
    #
    if (
         1 != IdenticalContents( File1 => $tmp,
                                 File2 => $dest ) )
    {
        system( "cp", $tmp, $dest );
    }
    else
    {
        unlink( $tmp );
    }

The following parameters are available:

File1 [mandatory]

The first file to complare.

File2 [mandatory]

The second file to compare.

The return value will depend on the matching:

-1

Returned on error; either missing parameters, or non-existing files.

0

The files are different.

1

The files are identical.

FetchFile

The FetchFile primitive is used to copy a file from the remote server to the local system. The file will have be moved into place if the local file is missing OR if it exists but contains different contents to the remote version.

The following is an example of usage:

    if ( FetchFile( Source => "/etc/motd",
                    Dest   => "/etc/motd",
                    Owner  => "root",
                    Group  => "root",
                    Mode   => "644" ) )
    {
        # File was created/updated.
    }
    else
    {
        # File already existed locally with the same contents.
    }

The following parameters are available:

Backup

If the fetch results in replacing an existing file the old file will be kept with a .bak suffix, unless "Backup" is set to "false".

Dest [mandatory]

The destination file to write to, on the local system.

Expand [default: false]

This is used to enable template-expansion, documented later.

Group

The unix group which should own the file.

Mode

The Unix mode to set for the file. NOTE If this doesn't start with "0" it will be passed through the perl "oct" function.

Owner

The Unix owner who should own the file.

Source [defaults to Dest if unset.]

The path to the remote file. This is relative to the /files/ prefix beneath the transport root.

When a file fetch is attempted several variations are attempted, not just the literal filename. The first file which exists and matches is returned, and the fetch is aborted:

/etc/motd.$fqdn
/etc/motd.$hostname
/etc/motd.$os
/etc/motd.$arch
/etc/motd

Template template expansion involves the use of the Text::Template module, of "Expand => true". This will convert the following text:

   # This is the config file for SSHD on {$fqdn}

To the following, assuming the local host is called "precious.my.flat":

   # This is the config file for SSHD on precious.my.flat

The return value will depend on the result of the fetch:

-1

Returned on error: either missing parameters, or failure to fetch the file.

0

The fetch resulted in no change to the local system..

1

The local file was replaced with the remote one.

FileMatches

This allows you to test whether the contents of a given file match either a literal line of text, or a regular expression.

  if ( FileMatches( File    => "/etc/sudoers",
                    Pattern => "steve" ) )
  {
     # OK "steve" is in sudoers.  Somewhere.
  }

The following parameters are available:

File [mandatory]

The name of the file to test.

Line [or Pattern mandatory]

A line to look for within the file literally.

Pattern [or Line mandatory]

A regular expression to match against the file contents.

The return value of this function will be the number of matches found - regardless of whether a regular expression or literal match is in use.

FindBinary

This method allows you to search for an executable upon your system $PATH, or a supplied alternative string.

  if ( FindBinary( Binary => "ls" ) )
  {
      # we have ls!
  }

The following parameters are available:

Binary [mandatory]

The name of the binary file to find.

Path [default: $ENV{'PATH'}]

This is assumed to be a semi-colon deliminated list of directories to search for the binary within.

If the binary is found the full path will be returned, otherwise undef.

InstallPackage

The InstallPackage primitive will allow you to install a system package. The precise mechanism used will depend upon your operating system:

  • GNU/Linux
    • Currently apt-get and yum are supported.
  • NetBSD
    • We use pkg_add, pkg_info, etc.
  • OpenBSD
    • We use pkg_add, pkg_info, etc.
  foreach my $package ( qw! bash tcsh ! )
  {
      if ( PackageInstalled( Package => $package ) )
      {
          print "$package installed\n";
      }
      else
      {
          InstallPackage( Package => $package );
      }
  }

The following parameters are available:

Package [mandatory]

The name of the package to install.

LogMessage

This primitive is used to store a log-worthy message. When slaughter finishes executing it will output a summary of all log-messages which were encountered, sorted by priority.

 LogMessage( Message => "Server on fire: $hostname",
             Level   => "normal" );

The following parameters are available:

Level [default: "normal"]

The log-level of the message. You may choose whichever level you prefer.

Message [mandatory]

The content of the message to record.

Mounts

Return a list of all the mounted filesystems upon the current system.

  my @mounts = Mounts();

No parameters are required or supported in this method, and the return value is an array of all mounted filesystems upon this host.

PackageInstalled

Test whether a given system package is installed.

  if ( PackageInstalled( Package => "exim4-config" ) )
  {
      print "$package installed\n";
  }

The following parameters are supported:

Package

The name of the package to test.

The return value will be a 0 if not installed, or 1 if it is.

The precise mechanism used will depend upon your operating system:

  • GNU/Linux
    • Currently apt-get and yum are supported.
  • NetBSD
    • We use pkg_add, pkg_info, etc.
  • OpenBSD
    • We use pkg_add, pkg_info, etc.

PercentageUsed

Return the percentage of space used in in the given mounted-device.

  foreach my $point ( Mounts() )
  {
     if ( PercentageUsed( Path => $point ) > 80 )
     {
        Alert( To      => "root",
               From    => "root",
               Subject => "$server is running out of space on $point",
               Message => "This is a friendly warning." );
     }
  }

The following parameters are supported:

Path

The mount-point to the filesystem in question.

The return value will be a percentage in the range 0-100.

ReplaceRegexp

This primitive will open a local file, and replace any lines matching a given regular expression.

  ReplaceRegexp( File    => "/etc/ssh/sshd_config",
                 Pattern => "^PermitRootLogin.*yes.*",
                 Replace => "PermitRootLogin no" );

The following parameters are available:

File [mandatory]

The filename which should be examined and potentially updated.

Pattern [mandatory]

The pattern to test and potentially replace.

Replace [mandatory]

The replacement text to use.

The return value of this function is the number of lines updated, 0 if none, or -1 if the file could not be opened.

RemovePackage

Remove the specified system package from the system.

  if ( PackageInstalled( Package => 'telnetd' ) )
  {
      RemovePackage( Package => 'telnetd' );
  }

The following parameters are supported:

Package

The name of the package to remove.

The precise mechanism used will depend upon your operating system:

  • GNU/Linux
    • Currently apt-get and yum are supported.
  • NetBSD
    • We use pkg_add, pkg_info, etc.
  • OpenBSD
    • We use pkg_add, pkg_info, etc.

RunCommand

This primitive will execute a system command.

   RunCommand( Cmd => "/usr/bin/id" );

The following parameters are available:

Cmd [mandatory]

The command to execute. If no redirection is present in the command to execute then STDERR will be redirected to STDOUT automatically.

The return value of this function is the result of the perl system function.

SetPermissions

This method allows the file owner,group, and mode-bits of a local file to be changed.

  SetPermissions( File => "/etc/motd" ,
                  Owner => "root",
                  Group => "root",
                  Mode => "644" );

The following parameters are supported:

File [mandatory]

The filename to work with.

Group

The group to set as the owner for the file.

User

The username to set as the files owner.

Mode

The permissions bits to set for the file. NOTE if this doesn't start with a leading "0" then it will be passed through the "oct" function - this allows you to use the obvious construct :

  Mode => "755"

UserExists

This primitive will test to see whether the given local user exists.

   if ( UserExists( User => "skx" ) )
   {
      # skx exists
   }

The following parameters are available:

User [mandatory]

The unix username to test for.

The return value of this function is 1 if the user exists, and 0 otherwise.

UserDetails

This primitive will return a hash of data about the local Unix user specified, if it exists.

   if ( UserExists( User => "skx" ) )
   {
      my %data = UserDetails( User => "skx" );
   }

The following parameters are available:

User [mandatory]

The unix username to retrieve details of.

The return value of this function is a hash of data conprising of the following Keys/Values

Home

The user's home directory

UID

The user's UID

GID

The user's GID

Quota

The user's quota.

Comment

The user's comment

Shell

The user's login shell.

Login

The user's username.

Undef will be returned on failure.

 

Sitemap | Contact Me © 2014 Steve Kemp