Mike Chirico (mchirico@gmail.com)
Copyright (c) 2005 (GNU Free Documentation License)
Last Updated: Sat May 13 09:48:11 EDT 2006
[http://souptonuts.sourceforge.net/cfengine_tutorial.html]

Cfengine

Cfengine is a powerful package for maintaining, upgrading and securing systems that can both pull software packages down to computers or push them with the "cfrun" command. In addition, there is a tripwire feature for monitoring files by keeping the MD5sum in a BerkeleyDB database. Cfengine goes beyond monitoring to correcting systems. Thus, as you will see in this tutorial, cfengine is an expert system.


Installing Cfengine

The following steps will walk you through the installation.

My current setup contains the following 4 computers.

IP Address Name Function
192.168.1.81 squeezel.squeezel.com Cfengine Master Host
192.168.1.171 livingroom.squeezel.com Cfengine Host
192.168.1.71 closet.squeezel.com Cfengine Host
192.168.1.155 tape.squeezel.com Cfengine Host

Downloading Cfengine

Download cfengine and check the md5sum of the package. The following steps use ncftp. If you don't have it ftp or wget will do.

     $ ncftpget ftp://ftp.iu.hio.no/pub/cfengine/cfengine-2.1.19p1.tar.gz
     $ sha1sum cfengine-2.1.19p1.tar.gz
     797392b67c6624ed7483f72f127b7873af9249da  cfengine-2.1.19p1.tar.gz

     $ tar -xzf cfengine-2.1.19p1.tar.gz

Checking BerkeleyDB Version and Installing

You need to have a current version of BerkeleyDB (http://downloads.sleepycat.com/db-4.3.29.tar.gz). Note that BerkeleyDB has a funny install. You cd to the "build_unix" directory, then, run configure as shown below. By default, BerkeleyDB installs in "/usr/local/BerkeleyDB.4.3". This is fine, but when compiling cfengine you will need to put this directory location in the configure. To install BerkeleyDB under "/usr" use the "--prefix=/usr" option.

 

  Installing BerkeleyDB if needed:
    $ wget http://downloads.sleepycat.com/db-4.3.29.tar.gz
    $ wget http://downloads.sleepycat.com/db-4.3.29.tar.gz.md5
    $ md5sum db-4.3.29.tar.gz
    200b9f5d74175875fcb3ee54adbf0007  db-4.3.29.tar.gz

    $ cat db-4.3.29.tar.gz.md5
    MD5 (/backup/ftp/releases/db-4.3.29.tar.gz) = 200b9f5d74175875fcb3ee54adbf0007

    $ tar -xzf db-4.3.29.tar.gz
    $ cd db-4.3.28/build_unix/
    $ ../dist/configure 
    $ make 
    $ make install

Checking OpenSSL Version and Installing

You also need a current version of OpenSSL. To find your version of OpenSSL execute the following command.

    $ openssl version
    OpenSSL 0.9.7g 11 Apr 2005

For instructions on how to install OpenSSL see the following article (http://souptonuts.sourceforge.net/postfix_tutorial.html ).

Next, compile cfengine. Below it is assumed that BerkeleyDB.4.3 has been installed in it's default location, which means you have to tell cfengine where it can be found using the "--with-berkeleydb" option as shown below.

Compiling Cfengine

     $ cd cfengine-2.1.19p1
     $ ./configure --with-berkeleydb=/usr/local/BerkeleyDB.4.3/lib
     $ make
     $ make install

Next create the following directories:

     $ mkdir -p /var/cfengine/bin
     $ mkdir -p /var/cfengine/inputs
     $ mkdir -p /var/cfengine/outputs

Setup

Copy needed files (cfagent, cfdoc, cfenvd, cfenvgraph, cfexecd, cfkey, cfrun, cfservd, cfshow) into "/var/cfengine/inputs" as follows:

     $ cp /usr/local/sbin/cf* /var/cfengine/bin

You'll also need to generate keys. As root, execute the following:

Naming and Copying Public Keys

     $ cfkey

The command above will write the public and private keys in "/var/cfengine/ppkeys". You should copy the public "localhost.pub" to the IP address of the server. My server has the IP address 192.168.1.171.

     $ cd /var/cfengine/ppkeys
     $ cp localhost.pub root-192.168.1.171.pub

The cfengine server for my setup is on IP address 192.168.1.81, so the key for this server is copied over to this client computer. And this key is copied over to the server. Many problems can occur with the keys. You want to make sure the client and server have copies of the respective keys.

     $ scp root@192.168.1.81:/var/cfengine/ppkeys/root-192.168.1.81.pub .
     $ scp root-192.168.1.171.pub root@192.168.1.81:/var/cfengine/ppkeys/.
     $ chown root.root *.pub
     $ chmod 600 *.pub

Daemon Configuration

You probably want (cfexecd,cfservd, and cfenvd) running on all servers. There are two way to do this. If you're running Fedora Core, you can copy the following files into the "/etc/init.d" directory as follows:

     $ cd /etc/init.d/
     $ wget http://ftp1.sourceforge.net/souptonuts/cfexecd
     $ wget http://ftp1.sourceforge.net/souptonuts/cfservd
     $ wget http://ftp1.sourceforge.net/souptonuts/cfenvd
     $ chmod 755 cfexecd cfservd cfenvd

     $ chkconfig --add cfexecd
     $ chkconfig --level 35 cfexecd on

     $ chkconfig --add  cfservd
     $ chkconfig --level 35 cfservd on

     $ chkconfig --add  cfenvd
     $ chkconfig --level 35 cfenvd on

Now you need to start each process.

     $ ./cfexecd start
     $ ./cfservd start
     $ ./cfenvd start

Checking Status

Alternatively, you could have add the files to "rc.local". Make sure the services are running. They will run on port 5308. You can check the following ports as follows:

     $ netstat -n -l|grep '5308'
     tcp        0      0 :::5308                     :::*                        LISTEN

At this point, you need to open your local firewall to permit upd/tcp connections. My computers are all on the 192.168.1.0/24 subnet, so I have the following firewall rules.

Opening the Firewall and Testing the Connection

    $ iptables -I INPUT -p udp -s 192.168.1.0/24  --dport 5308 -j ACCEPT
    $ iptables -I INPUT -p tcp -s 192.168.1.0/24  --dport 5308 -j ACCEPT

At this point, you should check that you can get access to port 5308 on all the computers running cfengine. You can easily do this with the telnet command, just to see if you can get connected.

    $ telnet 192.168.1.81 5308
    Trying 192.168.1.81...
    Connected to squeezel.squeezel.com (192.168.1.81).

Running Cfengine

Once cfengine is installed on a host, the only file needed to get things rolling is "update.conf", which will then pull other files containing custom configurations.

On the cfengine server "squeezel.squeezel.com" (192.168.1.81), there is a master set of directories "/master/cfengine". The directory tree is shown below with files. The input files "/master/cfengine/inputs" will be installed on all host computers ( closet.squeezel.com, tape.squeezel.com, and livingroom.squeezel.com) in each host's "/var/cfengine/inputs" file. Again, these files get copied to each hosts. Also, all hosts get the files under "/master/cfengine/src/pkg"; but, files in "/master/cfengine/src/pkg_closet" only go to closet. And files under "/master/cfengine/src/pkg_tape" only go to tape.squeezel.com.

     master                                             
     `-- cfengine                                       
         |-- initial_inputs    <---- This directory contains very simple files                         
         |   |-- cfrun.hosts                            
         |   `-- update.conf                            
         |-- inputs        <---- The files here are standard for all computers         
         |   |-- NOTES                                  
         |   |-- cfagent.conf                           
         |   |-- cfrun.hosts                            
         |   |-- cfservd.conf                           
         |   `-- update.conf                            
         |-- ppkeys                                     
         |   |-- localhost.priv                         
         |   |-- localhost.pub                          
         |   |-- root-192.168.1.155.pub                 
         |   |-- root-192.168.1.171.pub                 
         |   |-- root-192.168.1.71.pub                  
         |   |-- root-192.168.1.81.pub                  
         |   |-- root-closet.squeezel.com.pub           
         |   |-- root-livingroom.squeezel.com.pub       
         |   |-- root-squeezel.squeezel.com.pub         
         |   `-- root-tape.squeezel.com.pub             
         `-- src                                        
             |-- pkg    <---- Standard packages for all clients                                
             |   |-- cfengine-2.1.19p1.tar.gz             
             |   |-- snort-2.3.3.tar.gz                 
             |   `-- sysstat-6.0.1.tar.gz               
             |-- pkg_closet     <---- This directory contains files only for computer closet
             |   `-- ClosetOnly                         
             |   
             |-- pkg_tape       <---- This directory contains files only for computer tape                       
             |   `-- TapeOnly                           
             |-- tmp_closet                             
             |   |-- Note                               
             |   `-- stuff                              
             `-- tmp_tape                               
                 |-- Note                               
                 `-- stuff                              

Initial Push - cfrun on Master Host (squeezel.squeezel.com)

The steps here will describe setting up livingroom.squeezel.com and squeezel.squeezel.com. The computer livingroom is a host, and squeezel will be used as a server. In this example, both the host "livingroom" and "squeezel" will be updated. The update will come from "squeezel".

Step 1

Construct a minimal "update.conf" and copy this file to livingroom.squeezel.com in the directory "/var/cfengine/inputs". This is the only time you will have to manually copy a file, since we're priming the system. It demonstates the only "update.conf" is needed on the host.

A few points about this file. The first part of this file is the "control" section, and in the first thing listed is the "actionsequence" only contains one action "copy". Other actions could be added, but for this priming file, it's best to keep it simple.

     control:                                                                           
     
        actionsequence  = ( copy  )   # Keep this simple, only one action copy. See below.
                                                                                        
        AllowUsers      = ( root )    # Root account is the only account that has access.                                                  
        domain          = ( squeezel.com )              # My domain
                                                                                        
        cfhost          = ( squeezel.squeezel.com )   # The cfengine server. 
        workdir         = ( /var/cfengine )           # The workdir                      
        inputs_src      = ( /master/cfengine/inputs ) # Location of inputs on master host

        src_pkg         = ( /master/cfengine/src/pkg )         # Location of src install
                                                                                        
        input_mode      = ( 700 )                    # mode for input files             
        bin_mode        = ( 755 )                    # mode for binaries                
        fowner          = ( root )                   # file owner                       
        ogroup          = ( root )                   # file group                        
                                                                                        
     ############################################################################       
                                                                                        
     copy:                                                                              
                                                                                        
       $(inputs_src)                dest=$(workdir)/inputs                              
                                    recurse=inf  # copy any subdirectories
                                    owner=$(fowner) group=$(ogroup)                     
                                    mode=600                                            
                                    exclude=*~    # ignore emacs backup files           
                                    exclude=#*    # ignore CVS conflict files           
                                    server=$(cfhost) trustkey=true                      
                                                                                        
                                                                                        
        $(src_pkg)                  dest=/home/src/cfengine_src                         
                                    recurse=inf                                         
                                    owner=$(fowner) group=$(ogroup)                     
                                    mode=600                                            
                                    exclude=*~    # ignore emacs backup files           
                                    exclude=#*    # ignore CVS conflict files           
                                    server=$(cfhost) trustkey=true                      
                                    inform=true                                         


Step 2

In order for the master host (squeezel.squeezel.com) to run "cfrun" that will cause the host (livingroom.squeezle.com) to download the necessary files, "cfrun.hosts" must list "livingroom.squeezel.com". This file often list the names of all hosts.

     #                                           
     # /var/cfengine/inputs/cfrun.hosts on squeezel.squeezel.com        
     #                                       
     domain=squeezel.com                     
     access=root,chirico                     
     outputdir=/var/cfengine/outputs/cfrun   # This directory must exist
     maxchild=6  6                           
     hostnamekeys=true                       
     tape.squeezel.com:5308   # Listing of all hosts on the squeezel domain               
     closet.squeezel.com:5308                
     livingroom.squeezel.com:5308            
     squeezel.squeezel.com:5308              

Anytime "cfrun" is executed on squeezel.squeezel.com it will alert each host to call cfagent.

Step 3

The following command is executed on squeezel.squeezel.com with the account root.

     [root@squeezel ~]# cfrun
     cfrun(0):         .......... [ Hailing tape.squeezel.com:5308 ] ..........
     cfrun(1):         .......... [ Hailing closet.squeezel.com:5308 ] ..........
     cfrun(2):         .......... [ Hailing livingroom.squeezel.com:5308 ] ..........
     cfrun(3):         .......... [ Hailing squeezel.squeezel.com:5308 ] ..........

Or, if you only want to hail "livingroom" specify this option on the command line as follows noting that the syntac must exactly match what is in cfrun.hosts, including the port number.

     [root@squeezel inputs]# cfrun livingroom.squeezel.com:5308
     cfrun(0):         .......... [ Hailing livingroom.squeezel.com:5308 ] ..........

Note, if you want debugging information, use the following command.

         cfrun  -T -- -d2

Summary - What Happened

When the "cfrun" command was executed on the master host "squeezel.squeezel.com" all servers were update. H

References

http://www.linuxjournal.com/article/6848 This is a linux journal article that give a pretty good over view.

















     control:                                                                                                               

        actionsequence  = ( copy  )                                                                                         
                                                                                                                            
        AllowUsers      = ( root )                                                                                          
        domain          = ( squeezel.com )              # our domain                                                        
                                                                                                                            
        cfhost          = ( squeezel.squeezel.com )     # host running cfd                                                  
        workdir         = ( /var/cfengine )          # the workdir                                                          
        inputs_src      = ( /master/cfengine/inputs ) # location of inputs on the                                           
                                                      # master host                                                         
        src_pkg         = ( /master/cfengine/src/pkg )         # location of src installs                                   
                                                                                                                            
        bin_src         = ( /usr/local/sbin )        # location of binaries on the                                          
                                                     # master host                                                          
                                                                                                                            
        input_mode      = ( 700 )                    # mode for input files                                                 
        bin_mode        = ( 755 )                    # mode for binaries                                                    
        fowner          = ( root )                   # file owner                                                           
        ogroup          = ( root )                  # file group                                                            
                                                                                                                            
     ############################################################################                                           
                                                                                                                            
     copy:                                                                                                                  
                                                                                                                            
       $(inputs_src)                dest=$(workdir)/inputs                                                                  
                                    recurse=inf                                                                             
                                    owner=$(fowner) group=$(ogroup)                                                         
                                    mode=600                                                                                
                                    exclude=*~    # ignore emacs backup files                                               
                                    exclude=#*    # ignore CVS conflict files                                               
                                    server=$(cfhost) trustkey=true                                                          
                                                                                                                            
        $(src_pkg)                  dest=/home/src/cfengine_src                                                             
                                    recurse=inf                                                                             
                                    owner=$(fowner) group=$(ogroup)                                                         
                                    mode=600                                                                                
                                    exclude=*~    # ignore emacs backup files                                               
                                    exclude=#*    # ignore CVS conflict files                                               
                                    server=$(cfhost) trustkey=true                                                          
                                    inform=true                                                                             
                                                                                                                            
REFERENCES:
  http://www.onlamp.com/pub/a/onlamp/2004/04/15/cfengine.html
  http://www.onlamp.com/pub/a/onlamp/2004/05/13/distributed_cfengine.html

  http://www.sun.com/bigadmin/features/articles/cfengine_part1.html
  http://www.sun.com/bigadmin/features/articles/cfengine_part2.html

  (This is good)
  http://www.linuxjournal.com/article/6848


 The central stop to store all the files:

    $ mkdir -p /var/cfengine/myinputs
    $ cd /var/cfengine/myinputs
    $ touch cfagent.conf cfservd.conf update.conf
   
 Next, you need to create keys on the server. My severs has IP address
 192.168.1.81.

    $ cfkey
    
 You will want to copy the keys from
  
    /var/cfengine/ppkeys/localhost.pub

  to the other client (closet.squeezel.com)  as

   /var/cfengine/ppkeys/root-192.168.1.81.pub

Slight Change here. I'm looking at the article on
[ http://www.linuxjournal.com/article/6848 ]. And,
in the file

   # cfservd.conf file
   # /var/cfengine/inputs/cfservd.conf
   control:
     domain = ( squeezel.com )
     AllowUsers = ( root )
     cfrunCommand = ( "/usr/local/sbin/cfagent" )
   admit:
      /var/cfengine/myinputs *.squeezel.com

Now, I created the "update.conf" file as follows on squeezel.squeezel.com.

   control:
      actionsequence = ( copy )
      domain         = ( squeezel.com )
      workdir        = ( /var/cfengine )
      policyhost     = ( squeezel.squeezel.com )
      master_cfinput =
                  ( /var/cfengine/myinputs )

   copy:
      $(master_cfinput)     dest=$(workdir)/inputs
                         r=inf
                         mode=644
                         type=binary
                         exclude=*.lst
                         exclude=*~
                         exclude=#*
                         server=$(policyhost)

Note you also have to create /var/cfengine/inputs, /var/cfengine/outputs, /var/cfengine/bin and copy cfagent to /var/cfengine/bin

Remote Access

I created the following file in "/var/cfengine"

To get debugging output run the following:

    $ cfagent -d2
  Or
    $ cfagent -v -n -q

What's interesting is I got the following error when I ran "cfagent -v" on closet.squeezel.com:

    (Concatenated 114 from stream)
cfengine:: Server returned error:  Host authentication failed. Did you forget the domain name or IP/DNS address registration (for ipv4 or ipv6)?
cfengine:: Can't stat /master/cfengine/inputs in copy

But, the entry "/master/cfengine/inputs" was not listed correctly on "squeezel.squeezel.com" config file "/var/cfengine/inputs/cfservd.conf" I had a mispelling. But this is only part of the problem. If you are using host name entries, then, "/etc/hosts" must not have the names defined to 127.0.0.1; but, instead to the actual IP address.

  # /var/cfengine/inputs/cfservd.conf                                                 
  # If directories are not listed correctly you will get an authentication failed   
  # in which case you should use  cfagent -d2 and look for the directory/file       
  # directly after the error.                                                       
  #                                                                                 
  # Note how the hostname is defined in /etc/hosts                                  
  #                                                                                 
  #     # good                                                                      
  #     192.168.1.155 tape.squeezel.com tape                                        
  #     # problamatic                                                               
  #     127.0.0.1 tape.squeezel.com tape localhost.localdomain localhost            
                                                                                    
  control:                                                                          
     domain = ( squeezel.com )                                                      
     AllowUsers = ( root )                                                          
     cfrunCommand = ( "/usr/local/sbin/cfagent" )                                   
                                                                                    
  admit:                                                                            
                                                                                    
     /master/cfengine/inputs *.squeezel.com                                         
     /var/cfengine/myinputs *.squeezel.com                                          
     /master/cfengine/src/pkg *.squeezel.com                                        
     /master/cfengine/src/pkg_closet *.squeezel.com                                 
     /master/cfengine/src/pkg_tape *.squeezel.com                                   
     /master/cfengine/src/tmp_closet *.squeezel.com                                 
     /master/cfengine/src/tmp_tape *.squeezel.com                                   

Below is a good example update.conf

    ###############################################################################                  
    #                                                                                                
    # update.conf - ensure that the inputs and binaries in /var/cfengine are                         
    # synced to those on the server.  This runs before the main configuration                        
    # file, so we always have a way to fix broken configurations or programs that                    
    # were mistakenly pushed out.                                                                    
    #                                                                                                
    # STEP 1.                                                                                        
    #    A few things are needed for this to run correctly. First create the following               
    #    on the server. Here it is done on squeezel.squeezel.com                                     
    #                                                                                                
    #         mkdir -p /master/cfengine/inputs                                                       
    #                                                                                                
    # STEP 2.                                                                                        
    #    On the server (squeezel.squeezel.com) make sure that "/var/cfengine/inputs"                 
    #    has an entry for the client. My client is closet.squeezel.com                               
    #                                                                                                
    #          # cfrun.hosts                                                                         
    #          /var/cfengine/inputs                                                                  
    #                                                                                                
    # STEP 3.                                                                                        
    #    Make sure squeezel.squeezel.com has granted the other server access                         
    #    in the "/var/cfengine/inputs/cfservd.conf" file as follows                                  
    #                                                                                                
    #                                                                                                
    #          # cfservd.conf                                                                        
    #          control:                                                                              
    #            domain = ( squeezel.com )                                                           
    #            cfrunCommand = ( "/usr/local/sbin/cfagent" )                                        
    #            MaxConnections = ( 15 )                                                             
    #            TrustKeysFrom = ( 192.168.1.0/24 )                                                  
    #                                                                                                
    #          grant:                                                                                
    #             /master/cfengine                                                                   
    #                *.squeezel.com                                                                  
    #                192.168.1.*                                                                     
    #                                                                                                
    # STEP 4.                                                                                        
    #    Check your host keys.                                                                       
    #                                                                                                
    # STEP 5.                                                                                        
    #    Run the following from closet.squeezel.com to show verbose                                  
    #    output and to kill any lock.                                                                
    #                                                                                                
    #          $ cfagent -vqK                                                                         
    #                                                                                                
    #                                                                                                
    ###############################################################################                  
                                                                                                     
    control:                                                                                         
                                                                                                     
       actionsequence  = ( copy processes tidy )    # sequence of actions to                         
                                                    # perform                                        
       domain          = ( squeezel.com )              # our domain                                  
       DefaultCopyType = ( checksum )               # Copy based on checksum, not                    
                                                    # mtime                                          
                                                                                                     
       # Which host/dir is the master for configuration and binary files                             
                                                                                                     
       cfhost          = ( squeezel.squeezel.com )     # host running cfd                            
       workdir         = ( /var/cfengine )          # the workdir                                    
       inputs_src      = ( /master/cfengine/inputs ) # location of inputs on the                     
                                                     # master host                                   
       src_pkg         = ( /master/cfengine/src/pkg )         # location of src installs             
                                                                                                     
                                                                                                     
       bin_src         = ( /usr/local/sbin )        # location of binaries on the                    
                                                    # master host                                    
                                                                                                     
       input_mode      = ( 700 )                    # mode for input files                           
       bin_mode        = ( 755 )                    # mode for binaries                              
       fowner          = ( root )                   # file owner                                     
       ogroup          = ( root )                  # file group                                      
                                                                                                     
       AddInstallable = ( new_cfenvd new_cfservd )  # classes which may become                       
                                                    # defined during a cfengine run                  
                                                                                                     
      any::                                         # the class to match                             
                                                                                                     
       SplayTime       = ( 10 )                     # max number of minutes over                     
                                                    # which cfengine will share                      
                                                    # its load on the server                         
                                                                                                     
    ############################################################################                     
                                                                                                     
    copy:                                                                                            
                                                                                                     
      $(inputs_src)                dest=$(workdir)/inputs                                            
                                   recurse=inf                                                       
                                   owner=$(fowner) group=$(ogroup)                                   
                                   mode=600                                                          
                                   exclude=*~    # ignore emacs backup files                         
                                   exclude=#*    # ignore CVS conflict files                         
                                   server=$(cfhost) trustkey=true                                    
                                                                                                     
                                                                                                     
       $(src_pkg)                  dest=/home/src/cfengine_src                                       
                                   recurse=inf                                                       
                                   owner=$(fowner) group=$(ogroup)                                   
                                   mode=600                                                          
                                   exclude=*~    # ignore emacs backup files                         
                                   exclude=#*    # ignore CVS conflict files                         
                                   server=$(cfhost) trustkey=true                                    
                                                                                                     
       /tmp/junk                   dest=/tmp                                                         
                                   server=$(cfhost) trustkey=true                                    
                                                                                                     
                                                                                                     
                                                                                                     
                                                                                                     
    #####################################################################                            
                                                                                                     
    processes:                                                                                       
                                                                                                     
    # restart cfservd and/or cfenvd if we received new copies                                        
                                                                                                     
      modified_cfservd::                                                                             
                                                                                                     
        "cfservd" signal=term restart /var/cfengine/bin/cfservd                                      
                                                                                                     
      modified_cfenvd::                                                                              
                                                                                                     
        "cfenvd" signal=kill restart "/var/cfengine/bin/cfenvd -H"                                   
                                                                                                     
                                                                                                     
    #####################################################################                            
                                                                                                     
    tidy:                                                                                            
                                                                                                     
    # delete output files older than 31 days so we don't accumulate too many                         
                                                                                                     
         $(workdir)/outputs pattern=* age=31                                                         
                                                                                                     




Firewall rules

# Cfengine
iptables -A INPUT -p udp -s 192.168.1.0/24  --dport 5308 -j ACCEPT
iptables -A INPUT -p tcp -s 192.168.1.0/24  --dport 5308 -j ACCEPT

This is to get all the options on cfagent

          $ cfagent -Q

This is what is strange. On closet, when I run "cfagent -F" I get errors if there is no "/var/cfengine/bin/cfagent". I have to copy "/usr/local/sbin/cfagent" to this location to avoid the errors. Interesting note, http://lists.gnu.org/archive/html/help-cfengine/2003-11/msg00107.html which mentions that /var/cfengine/bin is hardcoded in the source

   cfexecd -gdv

The above command seems to confirm this.

Want the checksums of all the files in your checksum database?

    $ cfshow -c
    /etc/xinetd.d/services = MD5=6f886150b7e16b4396b3a6f56ad80471
    /etc/xinetd.d/sgi_fam = MD5=4e68c72f653e72e0ca01096da36aef6a
    /etc/xinetd.d/time = MD5=e26ea7f94ca7a0f91ff117a46f0800a3
    /etc/xinetd.d/time-udp = MD5=5acabba45736d46b9b51190f89397b76
    /etc/xml/catalog = MD5=37fbcd8b7761ff11894d803ec5de4901
    /etc/xpdfrc = MD5=061b590d72e5ad0ca7e784b097c27115
    ...

These are a few other helpful commands from the documentation

The cfshow command was introduced in cfengine 2.1.11 in order to provide a simple way to show some of the data stored by cfagent for operational purposes. 

     everyhost# cfshow -a
     everyhost# cfshow -l
     everyhost# cfshow -c
     everyhost# cfshow -s

The command line options are 

`-a --active'
This prints a list of any currently active locks, i.e. tasks that cfengine believes it is currently enagaged in. 

`-l --locks'
This prints a list of the locks and the last times an active lock was secured for each cfengine acivity. This list is potentially very long. 

`-s --last-seen'
This lists the IP addresses of all known peers and the times they were last engaged in communication with the current host. The expected interval between communications is also printed. See FriendStatus. The output format is in a form that can easily be parsed by user scripts. e.g. 
          192.0.2.1 (answered us) at [Wed May 26 16:39:03 2004] i.e. not seen for !2860.08! hours; <delta_t> = {63325.64} hours
          192.0.2.3 (answered us) at [Wed May 26 16:39:03 2004] i.e. not seen for !2860.08! hours; <delta_t> = {90465.20} hours
     


`-c --checksum'
This lists all of the files and their current checksum values in the current checksum database. 

This is kind of cool. It will do everything but copy the files over. "k" option. And there is another one called "--no-tidy" or is the "-t" option.

    $ cfagent -vkK

Wow, this is good. The "-q" option takes out the splay. This is important for testing.

cfagent for testing

    $ cfagent -vqK

cfenvd

This is the really cool part. cfenvd can be used to monitor the system through std changes. This deamon should be run for a number of months. To view the results, run "cfenvgraph". It's also possible to use the following values in cfagent:

      $(value_users)                   $(average_users)             
      $(value_rootprocs)               $(average_rootprocs)         
      $(value_otherprocs)              $(average_otherprocs)        
      $(value_diskfree)                $(average_diskfree)          
      $(value_netbiosns_in)            $(average_netbiosns_in)      
      $(value_netbiosns_out)           $(average_netbiosns_out)     
      $(value_netbiosdgm_in)           $(average_netbiosdgm_in)     
      $(value_netbiosdgm_out)          $(average_netbiosdgm_out)    
      $(value_netbiosssn_in)           $(average_netbiosssn_in)     
      $(value_netbiosssn_out)          $(average_netbiosssn_out)    
      $(value_irc_in)                  $(average_irc_in)            
      $(value_irc_out)                 $(average_irc_out)           
      $(value_cfengine_in)             $(average_cfengine_in)       
      $(value_cfengine_out)            $(average_cfengine_out)      
      $(value_nfsd_in)                 $(average_nfsd_in)           
      $(value_nfsd_out)                $(average_nfsd_out)          
      $(value_smtp_in)                 $(average_smtp_in)           
      $(value_smtp_out)                $(average_smtp_out)          
      $(value_www_in)                  $(average_www_in)            
      $(value_www_out)                 $(average_www_out)           
      $(value_ftp_in)                  $(average_ftp_in)            
      $(value_ftp_out)                 $(average_ftp_out)           
      $(value_ssh_in)                  $(average_ssh_in)            
      $(value_ssh_out)                 $(average_ssh_out)           
      $(value_telnet_in)               $(average_telnet_in)         
      $(value_telnet_out)              $(average_telnet_out)        

cfenvgraph

    $ cfenvgraph -s
    $ cd cfenvgraphs-snapshot-Linux
    $ ls
bin_bash.cfenv	     icmp-out.cfenv	   nfsd-in.cfenv     tcpfin-out.cfenv
bin_run_parts.cfenv  irc-in.cfenv	   nfsd-out.cfenv    tcpsyn-in.cfenv
cfengine-in.cfenv    irc-out.cfenv	   otherprocs.cfenv  tcpsyn-out.cfenv
cfengine-out.cfenv   loadavg.cfenv	   rootprocs.cfenv   udp-in.cfenv
cfenv-average	     misc-in.cfenv	   sbin_getty.cfenv  udp-out.cfenv
cfenv-stddev	     misc-out.cfenv	   smtp-in.cfenv     users.cfenv
dns-in.cfenv	     netbiosdgm-in.cfenv   smtp-out.cfenv    usr_sbin_atd.cfenv
dns-out.cfenv	     netbiosdgm-out.cfenv  ssh-in.cfenv      usr_sbin_exim.cfenv
freedisk.cfenv	     netbiosns-in.cfenv    ssh-out.cfenv     www-in.cfenv
ftp-in.cfenv	     netbiosns-out.cfenv   tcpack-in.cfenv   www-out.cfenv
ftp-out.cfenv	     netbiosssn-in.cfenv   tcpack-out.cfenv  wwws-in.cfenv
icmp-in.cfenv	     netbiosssn-out.cfenv  tcpfin-in.cfenv   wwws-out.cfenv

      $ gnuplot
      $ plot 'ssh-in.cfenv' with errorbars

Email

Now I'm getting email. For some reason doing cfagent -vqF doesn't give me email. But, now I know everthing is working because I'm getting it with the cfagent.conf program. So something is still a little fishy.

cfrun

The "cfrun" command. Does it need access to 5308/tcp?

   Try
   $ cfrun -v  -- -p -q -K > mout5
  instead of 

   $ cfrun -v tape.squeezel.com -- -p  > mout


Note the following needs to be in "/var/cfengine/inputs/cfrun.hosts"

  #
  # cfrun on squeezel.squeezel.com
  #   /var/cfengine/inputs/cfrun.hosts
  domain=squeezel.com
  access=root,chirico
  outputdir=/var/cfengine/outputs/t1
  maxchild=5  5
  hostnamekeys=true
  tape.squeezel.com:5308
  closet.squeezel.com:5308

So that works, but if I didn't have 5308 above as in "tape.squeezel.com:5308", then, I will get the following error below.

  cfrun:squeezel.squeezel.com: Couldn't open a socket
  cfrun:squeezel.squeezel.com: socket: No route to host

Yes, note squeezel.squeezel.com cannot open a socket to tape.

Next I got the following error:


Jun 24 14:38:35 tape cfservd[2282]:  Host squeezel.squeezel.com denied access to /usr/local/sbin/cfagent
Jun 24 14:38:35 tape cfservd[2282]: Host authorization/authentication failed or access denied
Jun 24 14:38:35 tape cfservd[2282]: From (host=squeezel.squeezel.com,user=root,ip=::ffff:192.168.1.81)
Jun 24 14:38:35 tape cfservd[2282]:  ID from connecting host: (EXEC  -vqK )

So, how did I fix this? I edited the file "/var/cfengine/inputs/cfservd.conf" on tape.squeezel.com to contain the line "/master/cfengine/inputs *.squeezel.com". This file works two ways. When you run "cfrun" on squeezel, the cfservd.conf on tape must allow squeezel access to the necessary files, including "/var/cfengine/bin/cfagent".

     # Lives in /master/cfengine/inputs/cfservd.con  on squeezel.squeezel.com     
     # but should get distributed to each host, and works two ways on the         
     # hosts                                                                      
     #                                                                            
     ##############################################################               
     #                          HOSTS and SERVER                  #               
     #                          verson 0.4b                       #               
     ##############################################################               
     control:                                                                     
        domain = ( squeezel.com )                                                 
        AllowUsers = ( root )                                                     
        cfrunCommand = ( "/var/cfengine/bin/cfagent" )                            
     admit:                                                                       
                                                                                  
        # very important and must be on tape and closet                           
        /var/cfengine/bin/cfagent *.squeezel.com                                  
                                                                                  
        /var/cfengine/inputs  *.squeezel.com                                      
        /master/cfengine/src/pkg *.squeezel.com                                   
        /master/cfengine/src/pkg_tape *.squeezel.com                              
        /master/cfengine/src/pkg_closet *.squeezel.com                            
        /master/cfengine/inputs *.squeezel.com                                    
        /master/cfengine/src/tmp_tape *.squeezel.com                              

Also, make sure "cfenvd" is running on squeezel. This gave me a problem as well. Testing

   $ cfagent -v -n -q 


References

http://www.cfengine.org/txt/terseguide.txt


Other Tutorials

Breaking Firewalls with OpenSSH and PuTTY: If the system administrator deliberately filters out all traffic except port 22 (ssh), to a single server, it is very likely that you can still gain access other computers behind the firewall. This article shows how remote Linux and Windows users can gain access to firewalled samba, mail, and http servers. In essence, it shows how openSSH and Putty can be used as a VPN solution for your home or workplace.

Create a Live Linux CD - BusyBox and OpenSSH Included: These steps will show you how to create a functioning Linux system, with the latest 2.6 kernel compiled from source, and how to integrate the BusyBox utilities including the installation of DHCP. Plus, how to compile in the OpenSSH package on this CD based system. On system boot-up a filesystem will be created and the contents from the CD will be uncompressed and completely loaded into RAM -- the CD could be removed at this point for boot-up on a second computer. The remaining functioning system will have full ssh capabilities. You can take over any PC assuming, of course, you have configured the kernel with the appropriate drivers and the PC can boot from a CD. This tutorial steps you through the whole processes.

SQLite Tutorial : This article explores the power and simplicity of sqlite3, first by starting with common commands and triggers, then the attach statement with the union operation is introduced in a way that allows multiple tables, in separate databases, to be combined as one virtual table, without the overhead of copying or moving data. Next, the simple sign function and the amazingly powerful trick of using this function in SQL select statements to solve complex queries with a single pass through the data is demonstrated, after making a brief mathematical case for how the sign function defines the absolute value and IF conditions.

The Lemon Parser Tutorial: This article explains how to build grammars and programs using the lemon parser, which is faster than yacc. And, unlike yacc, it is thread safe.

How to Compile the 2.6 kernel for Red Hat 9 and 8.0 and get Fedora Updates: This is a step by step tutorial on how to compile the 2.6 kernel from source.

Linux System Admin Tips: There are over 160 linux tips and tricks in this article. This article is updated weekly.

Virtual Filesystem: Building A Linux Filesystem From An Ordinary File. You can take a disk file, format it as ext2, ext3, or reiser filesystem and then mount it, just like a physical drive. Yes, it then possible to read and write files to this newly mounted device. You can also copy the complete filesystem, sinc\ e it is just a file, to another computer. If security is an issue, read on. This article will show you how to encrypt the filesystem, and mount it with ACL (Access Control Lists), which give you rights beyond the traditional read (r) write (w) and execute (x) for the 3 user groups file, owner and other.

Working With Time: What? There are 61 seconds in a minute? We can go back in time? We still tell time by the sun?



Chirico img Mike Chirico, a father of triplets (all girls) lives outside of Philadelphia, PA, USA. He has worked with Linux since 1996, has a Masters in Computer Science and Mathematics from Villanova University, and has worked in computer-related jobs from Wall Street to the University of Pennsylvania. His hero is Paul Erdos, a brilliant number theorist who was known for his open collaboration with others.


Mike's notes page is souptonuts. For open source consulting needs, please send an email to mchirico@cwxstat.com. All consulting work must include a donation to SourceForge.net.

SourceForge.net Logo


SourceForge.net Logo