Automating Security with GNU cfengine

A sysadmin tool for automating changes across many machines, recording update information and making them all safer.
Disabling Network Services

You also can use cfengine to disable certain network services you do not want running on your systems. As an example, let's disable the rshd and rlogind services on all systems, as well as any files related to these services:

   { /etc/inetd.conf
      HashCommentLinesContaining "rshd"
      HashCommentLinesContaining "rlogind"
      DefineClasses "modified_inetd"

      "inetd" signal=hup


The code above accomplishes this task on a standard Linux system when added to the master cfagent.conf, and the actionsequence list is expanded. First of all, any lines containing the strings rshd or rlogind in /etc/inetd.conf are commented out. If such a thing occurs, the class modified_inetd is defined. Then, when the processes section is executed and the class is defined, the HUP signal is sent to the inetd process to cause it to reload its configuration.

We finally tell cfengine to disable the files /root/.rhosts and /etc/hosts.equiv if they exist. They are made unreadable for anybody but root and renamed with a .cfdisabled extension. You also could disable this file in your users' home directories, but that takes a few more setup tasks that are beyond the scope of this article.

Filesystem Permissions

You can use cfengine to check and repair the permissions of important system files:

   /etc/passwd mode=644 owner=root group=root
   /etc/shadow mode=600 owner=root group=root
   /etc/group  mode=644 owner=root group=root

   /etc mode=0755 owner=root group=root inform=true
   /tmp mode=1777 owner=root group=root inform=true

In this case, we are concerned with certain system account and password files. We specify the desired ownership and permissions and direct cfengine to repair any problems (action=fixall) it may find. We also list a couple of important directories that should be created if they don't exist and whose permissions should be set appropriately.

Monitoring File Checksums

You may be familiar with the Tripwire program, a wonderful security tool that monitors the files on your systems for unwanted changes. You can do similar file monitoring with cfengine. Although not as secure as the method used by Tripwire, this method is easy and convenient if you already are using cfengine for other tasks.

At the very least, I like to monitor important system files, especially setuid root files, for the proper permissions and md5 checksum:

   /bin/mount mode=4755 owner=root group=root
      action=fixall checksum=md5
   /bin/mount mode=4755 owner=root group=root
      action=fixall checksum=md5

I have listed only two files in the example, but you obviously could list many more. As in the previous example, the files' permissions are checked and fixed, if necessary. But, in addition, each file's md5 checksum is compared with its previously stored value and any anomalies are reported. Cfengine updates only the stored checksums when the ChecksumUpdates = ( on ) line is present in the control section.

Watching for setuid Root Files

You also can have cfengine find and eliminate the setuid bit on files that should not be setuid. In Listing 3, we have an entry in the files section looks through the entire filesystem and turns off the setuid bit on any file owned by root and not explicitly itemized as a file to be ignored. You obviously should expand the list of files to be ignored before executing this code, as there probably are many other setuid root files on your systems. You can determine what files currently are setuid root on your system by running the command find / -perm +4000 -user root.

Listing 3: Eliminating Unwanted setuid Root Files

   { root_owned_files
      Owner:     "root"
      Result:    "Owner"

      mode=u-s     # no SUID bit may be set
      # And the full paths of files that *should* be SUID

Using Classes

One powerful feature of cfengine we have not used much in these examples is its support of classes. Each system automatically is a part of numerous classes, and custom classes can be defined in many ways--when a certain action is taken or based on certain files found on the system. You then can perform sets of commands only on systems of specific classes. Some examples of classes automatically defined for one of my systems are: redhat, linux, redhat_7_2 and www_kaybee_org. There also are classes defined based on the current system time. Listing 4 shows a few examples of how these classes can be used; I'm sure you can find many more uses for this feature.

Listing 4. Class Examples

   # Assume systems with this file are web servers
   web_server = ( 
      '/usr/bin/test -f /etc/httpd/conf/httpd.conf' 

      # Fix permissions on web server config files
      /etc/httpd/conf owner=root group=root
         mode=0644 action=fixall recurse=inf

      # On all Solaris systems
      /etc/inet/inetd.conf owner=root group=root
         mode=0644 action=fixall

      # On all Linux systems not running Red Hat
      # versions 7.X, 8.X, or 9.X.
      /etc/inetd.conf owner=root group=root
         mode=0644 action=fixall

      # On Red Hat Linux 7.X, 8.X, or 9.X
      /etc/xinetd.conf owner=root group=root
         mode=0644 action=fixall

      # This file exists on all systems
      /etc/passwd mode=644 owner=root group=root

      # Clean out files more than 14 days old
      # in /tmp on Sunday only
      /tmp recurse=inf age=14 rmdirs=sub



Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Excellent article

Mark Wolf's picture

This is by far the best basic setup article I have found. I have tried to follow several other articles and was not successful in getting things to work. I have got a cfengine configuration setup and running on three servers using keys and classes etc...Woohoo...

Very nice indeed

Thank you



Stefan2's picture

I say "Woohho....", too.
thank you for this great article...
it would help me to understand cfengines functionality...

sorry for my english but I wanted to say this now ;-)


Automating Security with GNU cfengine

sts's picture

just wanted to leave a link to our cfengine wiki. maybe that might be helpful to anyone.

regards. stefan.

Re: Automating Security with GNU cfengine

Anonymous's picture

This is an excellent, in depth, clear, concise article on a great application ( cfengine ). I have recently been asked to set-up and configure cfengine at work.

I found that although cfengine is well documented, the docs are missing some very key points in actual implementation, (like a. do this. b. now do this. c. now do this. d. your done. i.e. for installation it said ./configure, make , make install - ok great, now what, then you had to read all the 'advanced' command line switches and possible params without a clear sequence of events. 30+ pages, additionally it would not make on my box, Red Hat 9.0 Shrike, or Slackware 9.2 kept getting "must have Berkeley3.2 or later", i was running Berkeley4.2,..." errors, i filled a bug report with the author, I had to install a rpm)

It was very diffucult to find google results on actual working implementations of this tool. I did find a few and with all the docs and example files after 2 days had a pretty decent idea about my set-up, except for a few key details. ( like how to get a new cfengine.conf on each host, before running cfengine, kind of like chicken/egg,... )
Then i discovered this excellent article, which i think should be included on the cfengine site, or have links to it, like a "step-by-step" example implementation.

Thanks for this great article.

Re: Automating Security with GNU cfengine

Anonymous's picture

Actually the only thing i would append to my comment, is that the Mr. Bauer did not include which version this article is based on. It sounds as if it's based on a pre 2.0 version but it's hard to tell. (I don't know exactely vor what version the cfengine change took place but it moved everything from /usr/local/cfengine to /var/cfengine, which can lead to some confusion when reading articles describe configuration). :)

Re: Automating Security with GNU cfengine

Anonymous's picture

sorry, to append my post again, actually with this comment
"this creates the files and localhost.priv in the /var/cfengine/ppkey" - it has to be >= 2.0. sorry about that. (It would still be cool if in the header of the article it stated "based on a 2.1.1 cfengine or whatever,..."
thanks again