O'Reilly Hacks
oreilly.comO'Reilly NetworkSafari BookshelfConferences Sign In/My Account | View Cart   
Book List Learning Lab PDFs O'Reilly Gear Newsletters Press Room Jobs  



Taming periodic emails
How to get FreeBSD's periodic to send you email only when you need to be alerted.

Contributed by:
Pretzel
[01/26/06 | Discuss (0) | Link to this hack]

FreeBSD's periodic(8) keeps an eye on your server for you, and runs a number of security and system checks. When these checks run, they'll generate an email detailing what checks were run.
The problem is that most of the time, the emails simply tell you that the checks were run, and found everything to be okay. This makes detecting alerts from periodic far more difficult.

In order to solve this problem, we can use swatch (The Simple WATCHer and filter) to divide the emails into sections, and then ignore any sections that are not reporting problems.

The steps:
  1. Install swatch from ports
    $ su - root
    root# cd /usr/ports/security/swatch/
    root# make install
    root# make clean
      
  2. Send periodic emails to a separate file by creating an alias and changing the address the mail is sent to
    1. create the new mailbox:
      root# touch /var/log/periodic
      root# chown mailnull:mailnull /var/log/periodic
      root# chmod 600 /var/log/periodic
          
    2. insert the following into /etc/mail/aliases:
      periodic:       /var/log/periodic
          
      If you wish to save a copy of all the periodic email unmolested, then you can create the following entry instead:
      periodic:       /var/log/periodic, /var/log/periodic.archive
          
      (don't forget to touch, chown and chmod the periodic.archive if you do this)
    3. Rebuild the aliases database
      root# newaliases
          
    4. Add the following entries to periodic.conf:
      daily_output="periodic"
      weekly_output="periodic"
      monthly_output="periodic"
      daily_status_security_output="periodic"
          
  3. Setup a config file for swatch. Let's call it /usr/local/etc/parse-periodic.conf
    # Swatch config for periodic(8) on FreeBSD 5.4
    
    # I use a default echo, and then ignore all the stuff I don't want. This way
    # I'm only rejecting known messages.
    
    # CMD: swatch --input-record-separator="\n\n" -f $TMPFILE -c /usr/local/etc/parse-periodic.conf
    # With --input-record-separator="\n\n" set, Perl will be put into "Paragraph Mode"
    
    # See swatch(1) for more information about the sentax of this file
    
    # Get rid of the email headers
    ignore /^From \S*\@\S*.\S\S+/
    
    # The \z matches the end of the string (So items with someting listed
    # will *not* match)
    ignore /Removing stale files from \/var\/(preserve|rwho):\z/
    ignore /Cleaning out old system announcements:\z/
    ignore /Backup passwd and group files:\z/
    ignore /Verifying group file syntax:\n\/etc\/group is fine\z/
    ignore /Backing up mail aliases:\z/
    ignore /Rotating accounting logs and gathering statistics:\z/
    ignore /Verifying group file syntax:\z/
    
    # The number and location of all the \n's are important.
    # That way, we'll only match filesystems that we don't expect to be
    # at 100%
    #                  Header |-------- / -------|   |---- /dev ---| |-------- /tmp ---------| |-------- /usr ---------| |-------- /var ---------|  |---- /proc --| |----------- Linux proc -----------|
    ignore /Disk status:\n.*\n.*\s[0-8]?[0-9]%\s+\/\n.*100%\s+\/dev\n.*\s[0-8]?[0-9]%\s+\/tmp\n.*\s[0-8]?[0-9]%\s+\/usr\n.*\s[0-8]?[0-9]%\s+\/var\n.*100%\s+\/proc\n.*100%\s+\/usr\/compat\/linux\/proc\z/
    ignore /Disk status:\n.*\n.*\s[0-8]?[0-9]%\s+\/\n.*100%\s+\/dev\n.*\s[0-8]?[0-9]%\s+\/tmp\n.*\s[0-8]?[0-9]%\s+\/usr\n.*\s[0-8]?[0-9]%\s+\/var\n.*100%\s+\/proc\z/
    # Without /proc (it's not always mounted)
    ignore /Disk status:\n.*\n.*\s[0-9][0-9]?%\s+\/\n.*100%\s+\/dev\n.*\s[0-9][0-9]?%\s+\/tmp\n.*\s[0-9][0-9]?%\s+\/usr\n.*\s[0-9][0-9]?%\s+\/var\z/
    ignore /Last dump\(s\) done \(Dump \'>\' file systems\):\z/
    # We only care about the errors on the interfaces
    #                                Header Name MTU    Net   Addr Ipkts Ierrs Opkts Oerrs  Coll
    ignore /Network interface status:\n.*\n\S+\s+\S+\s+\S+\s+\S+\s+\S+\s+(0|-)\s+\S+\s+(0|-)\s+(0|-)/
    # Only show the load average only if the 15 minute average is more then 1
    ignore /Local system status:\n.*load averages: [0-9].[0-9][0-9], [0-9].[0-9][0-9], 0.[0-9][0-9]/
    ignore /\/var\/spool\/(clientmqueue|mqueue) is empty/
    ignore /\(output mailed separately\)/
    ignore /Checking for rejected mail hosts:\z/
    ignore /Checking for denied zone transfers \(AXFR and IXFR\):\z/
    ignore /-- End of (daily|weekly|security|monthly) output --/
    ignore /Checking for uids of 0:\nroot 0\ntoor 0\z/
    ignore /Checking for passwordless accounts:\z/
    ignore /<YOUR-HOSTNAME> login failures:\z/
    ignore /<YOUR-HOSTNAME> refused connections:\z/
    ignore /Checking setuid files and devices:\z/
    ignore /Cleaning up kernel database files:\z/
    ignore /Rebuilding (locate|whatis) database:\z/
    ignore /Doing login accounting:/
    
    # Print everything else
    watchfor /.*/
      mail addresses=root,subject="Periodic Mail"
        

    You'll likely need to adjust some of the entries in the file (notably the filesystem section) and you'll want to replace <YOUR-HOSTNAME> with your actual hostname.
    Don't worry if you don't know what to put in right now. The config will err on the side of sending you too much email. It will be easy to adjust the regular expressions once you see what it is not filtering.
  4. Next, create a small script to parse /var/log/periodic. In this example the script is called "~root/bin/parse-periodic".
    #!/bin/sh
    
    # What is the file we want to look at?
    INFILE="/var/log/periodic"
    TMPFILE=/tmp/`basename $0`.$$
    
    mv $INFILE $TMPFILE
    
    touch $INFILE
    chown mailnull:mailnull $INFILE
    chmod 600 $INFILE
    
    /usr/local/bin/swatch --input-record-separator="\n\n" -f $TMPFILE -c /usr/local/etc/parse-periodic.conf && \
    rm $TMPFILE
        
    Don't forget to make the script executable:
    chmod 500 ~root/bin/mailparser
        
  5. Last, add a cronjob to process /var/log/periodic daily
            45      6       *       *       *       root    ~/bin/mailparser > /dev/null
        
    You may want to change the time in the crontab - depending on when periodic runs on your machine
<hr> That's it!

Tomorrow morning when you wake up, you shouldn't see any email from periodic - unless of course there is something for you to look at.
To give it a test, change your password. The periodic security checks will detect that the password file has changed, and you should get an email stating that.

If the config file is letting through too much email, then you can adjust is as necessary. Be careful however that you don't accidently match too much, or you might not be alerted when there's something that you should be aware of.

See also:


O'Reilly Home | Privacy Policy

© 2007 O'Reilly Media, Inc.
Website: | Customer Service: | Book issues:

All trademarks and registered trademarks appearing on oreilly.com are the property of their respective owners.