CFEngine Remote Communication


Next: , Previous: (dir), Up: (dir)

CFEngine Remote Communication

COMPLETE TABLE OF CONTENTS

Summary of contents

In this module you will learn about

  • Pull and Push
  • How to pull
  • How to simulate push in cfengine
  • Authentication
  • Encryption
  • Security Implications of using cfengine
  • Centralization and Decentralization
  • Change Management


Next: , Previous: Top, Up: Top

1 Communication Overview

The idea of voluntary cooperation used by cfengine places restrictions on how files can be copied between hosts. CFEngine allows only `pull' (download) but not `push' (upload). This means you cannot force a cfagent to perform an operation against local policy but only request resources. There is no loss of flexibility in this choice, but a big increase in security.

CFEngine does not allow one to copy from one system to another system (push) since it amounts to forcing the system to perform an operation against it will. However, push is not totally eliminated from cfengine. CFEngine supports a kind of push which consistent with the idea of voluntary cooperation. If you want to copy from your local system to a remote machine you will need to place an order requesting the remote machine to copy the data for you. When the remote machine receives the order it will evaluate itself to see if it wants to handle the request. To allow remote copying between two systems each of the system must explicitly grant access before the operation can take place.

The following example illustrates how this could be done. We will consider three scenarios namely client server communication, peer to peer copying and simulation of push.


Next: , Previous: Communication Overview, Up: Communication Overview

1.1 Scenario 1


Next: , Previous: Scenario 1, Up: Scenario 1

1.1.1 Communication example 1

     
     #client server copy
     #server side cfservd.conf
     
     control:
     
      domain = ( mydomain.com )
      clients = ( 192.10.10 )   #peer subnet
      AllowConnectionsFrom = ( $(clients) ) #allow clients to pull data
      AllowMultipleConnectionsFrom = ( $(clients) )
      TrustKeysFrom = ( $(clients) )
     
     admit:
     
       /master/cfengine/inputs   $(clients)
     

Example 1 set up the permission to allow a cfengine client to pull data from a cfengine server. The domain specifies the existing domain. The line 3 defines clients subnet. This means any client in this subnet will be allowed to pull data from the server. The next step is to write the client policy files to copy data from the server.


Previous: Communication example 1, Up: Scenario 1

1.1.2 Communication example 2

Example 2 is the client policy file.

     Example 2
     
     #client side policy file, cfagent.conf
     control:
      domain = ( mydomain.com )
      serverip = ( 192.10.10.1 )   #server ip address
      master = (  /home/mark/inputs )
     actionsequence = ( copy )
     copy:
        /master/cfengine/inputs server=$(serverip)
               dest=(master)
               recurse=inf
               trustkey=on
     

Example 2 allows the client to copy or pull from the /master/cfengine/inputs to /home/mark/inputs on the local machine. This will succeed because the client is part of the subnet allow to pull from the server. To test the setup we need to run cfservd on the server side and cfagent on the client side.


Next: , Previous: Scenario 1, Up: Communication Overview

1.2 Scenario 2

We consider the second scenario. For the second scenario we want both machines to pull from each other. This means both machines should have cfservd.conf files and also a policy files that pull the data from each other. We will now label the systems peer1 and peer2. Suppose peer 1 has ip 192.10.10.1 and peer 2 has an ip 192.10.10.2, we can write the policy files as follows:


Next: , Previous: Scenario 2, Up: Scenario 2

1.2.1 Communication example 3

     
     #Peer 1
     #server side cfservd.conf
     
     control:
     
      domain = ( mydomain.com )
      clients = ( 192.10.10 )   #peer subnet
     
     AllowConnectionsFrom = ( $(clients) ) #allow clients to pull data
     AllowMultipleConnectionsFrom = ( $(clients) )
     TrustKeysFrom = ( $(clients) )
     
     admit:
     
       #allow clients to pull data from only the inputs directory
       /master/cfengine/inputs   $(clients)
     


Next: , Previous: Communication example 3, Up: Scenario 2

1.2.2 Communication example 4

     
     #client side policy file, cfagent.conf
     
     control:
     
      domain = ( mydomain.com )
      serverip = ( 192.10.10.2 )   #server ip address
      master = (  /home/eben/inputs )
      actionsequence = ( copy )
     
     copy:
     
        /master/cfengine/inputs server=$(serverip)
                   dest=(master)
                   recurse=inf
                   trustkey=on
     


Next: , Previous: Communication example 4, Up: Scenario 2

1.2.3 Communication example 5

     # Peer 2
     #server side cfservd.conf
     control:
      domain = ( mydomain.com )
     
      clients = ( 192.10.10 )   #peer subnet
      AllowConnectionsFrom = ( $(clients) ) #allow clients to pull data
      AllowMultipleConnectionsFrom = ( $(clients) )
      TrustKeysFrom = ( $(clients) )
     
     admit:
     
       /master/cfengine/inputs   $(clients)
     


Previous: Communication example 5, Up: Scenario 2

1.2.4 Communication example 6

     #This file should be kept in /var/cfengine/inputs
     #client side policy file, cfagent.conf
     
     control:
     
      domain = ( mydomain.com )
      serverip = ( 192.10.10.1 )   #server ip address
      master = (  /home/mark/inputs )
      actionsequence = ( copy )
     
     copy:
     
        /master/cfengine/inputs server=$(serverip)
                   dest=(master)
                   recurse=inf
                   trustkey=on
     

The only changes made were to have the two policy files on both machines and interchanging the IPs of the client configuration files so that they can pull from appropriate the server.


Previous: Scenario 2, Up: Communication Overview

1.3 Scenario 3

We now consider the third scenario. The third scenario will allow us to simulate push by using cfrun without breaking the rules of voluntary cooperation.


Next: , Previous: Scenario 3, Up: Scenario 3

1.3.1 Communication example 7

We start by modifying the cfservd.conf file. We need to modify the cfservd.conf to include the cfrun command. The cfrunCommand specifies which cfengine agent should be run when cfrun request is received. The cfservd.conf is modified as follows:

     
     #cfservd.conf for the puller
     
     control:
     
      domain = ( mydomain.com )
      clients = ( 192.10.10 )   #peer subnet
      cfrunCommand = ( /var/cfengine/bin/cfagent )
      AllowConnectionsFrom = ( $(clients) ) #allow clients to pull data
      AllowMultipleConnectionsFrom = ( $(clients) )
      TrustKeysFrom = ( $(clients) )
     
     classes:
      hostlist = (  IPRange(192.10.10.0/24) )
     
     admit:
       /master/cfengine/inputs   $(clients)
       /var/cfengine/bin/cfagent  hostlist
     

We include

     cfrunCommand = ( /var/cfengine/bin/cfagent )

Here we specify that cfagent should be called when cfrun request is received. On the same server machine we have to write the pull configuration file in the cfagent.conf since cfrunCommand reads cfagent.conf by default.


Next: , Previous: Communication example 7, Up: Scenario 3

1.3.2 Communication example 8

     #cfagent.conf for puller
     
     control:
     
      domain = ( mydomain.com )
      serverip = ( 192.10.10.2 )   #server ip address
      master = (  /home/mark/inputs )
      actionsequence = ( copy )
     
     copy:
     
        /master/cfengine/inputs server=$(serverip)
                   dest=(master)
                   recurse=inf
                   trustkey=on
     


Previous: Communication example 8, Up: Scenario 3

1.3.3 Communication example 9

     
     #Pusher
     #cfservd.conf for pusher
     
     control:
     
      domain = ( mydomain.com )
      clients = ( 192.10.10 )   #peer subnet
      AllowConnectionsFrom = ( $(clients) ) #allow clients to pull data
      AllowMultipleConnectionsFrom = ( $(clients) )
      TrustKeysFrom = ( $(clients) )
     
     admit:
     
       /master/cfengine/inputs   $(clients)
     

The client will just run cfservd.conf which will grant access to remote machine to pull data. In addition the client needs cfrun.hosts file. The cfrun.hosts must contain the IP or the name of the machine we are requesting to pull our data. We can now run the cfrun command to parse the policy file on all the hosts listed in cfrun.hosts file. The cfrun.hosts file should be placed in /var/cfengine/inputs and should contain 192.10.10.1. We can also use the optional host list instead of cfrun.hosts files.

  • From the mailing list: `We have a directory on some application servers that is full of log files. For various reasons we cannot use syslog to log remotely to our syslog server. I'm considering using the "copy" feature of cfengine to sync the log files across once per day. Would you all have any suggestions or best practices on how to accomplish this?'
  • `I want email sent when I use cfrun. My cfrun command is set to "cfagent"; will my problem be solved if I change it to "cfexecd"? Can I specify command line options in cfrunCommand or do I need to write a wrapper?'
  • I would also like to have alerts go to a separate e-mail address. In particular, I want them to be sent to RT so that we can track problems. Can this be done?
  • We import several files and each of these files has, say, a copy action, will the order of the copies follow the order of the imports? For example, if I have:
              cfagent.conf:
              import:
                   cf.A
                   cf.X
              cf.A:
              
              copy:
                   /path/to/a dest=/path/to/b
              cf.X:
              copy:
                   /path/to/x dest=/path/to/y
              
    

    Is /path/to/a guaranteed to be copied before /path/to/x?


Next: , Previous: Communication Overview, Up: Top

2 Authentication

Authentication is about making sure you are who you say you are. Traditionally, there are two main approaches: a trusted third party (arbiter of the truth) approach and the challenge approach. The trust third party allows us to use a third party that the two individuals who want to authenticate each other trust to take the decision, as usually done in e-commerce site. The challenge approach allows the individuals to decide whether to trust each other rather than using a third party. CFEngine uses the challenge approach. Its model is based in the Secure Shell (OpenSSH). It allows two machines to authenticate each other by the machine deciding whether to accept the offered keys. For key exchange between client and server, the server has to decide if it will trust the client by using the TrustKeysFrom directive. The TrustKeysFrom directive allows the server to accept keys from one or more machines.

On the client side the client has to also specify if it will trust key from the server by using the trustkey directive. The trustkey directive allows a client to decide whether to accept keys from a server. The cfengine authentication model is base on ssh scheme, however unlike ssh, cfengine authentication is not interactive and the keys are generated by cfkey program instead of ssh key-gen program. The ssh interaction is accomplished in cfengine using the trustkey directive. Once the keys have been exchange the trustkey=on is no longer effective. The cfkey when run generate the cfengine key and store it in /var/cfengine/ppkeys subdirectory.


Next: , Previous: Authentication, Up: Authentication

2.1 Communication example 10

The server side configuration

     
     control:
     
      domain = ( mydomain.com )
      clients = ( 192.10.10 )   #peer subnet
      AllowConnectionsFrom = ( $(clients) ) #allow clients to pull data
      AllowMultipleConnectionsFrom = ( $(clients) )
      TrustKeysFrom = ( $(clients) )
     
     admit:
     
       /master/cfengine/inputs   $(clients)   #allow clients to pull data from only the inputs directory
     


Previous: Communication example 10, Up: Authentication

2.2 Communication example 11

The client side configuration:

     
     #client side policy file, cfagent.conf
     
     control:
     
      domain = ( mydomain.com )
      serverip = ( 192.10.10.1 )   #server ip address
      master = (  /home/mark/inputs )
      actionsequence = ( copy )
     
     copy:
        /master/cfengine/inputs server=$(serverip)
                  dest=(master)
                  recurse=inf
                  trustkey=on
     #end
     


Next: , Previous: Authentication, Up: Top

3 Encryption

CFEngine uses the public private key pairs generated by cfkey to encrypt data during file transfer. CFEngine uses RSA encryption algorithm to encrypt information.


Previous: Encryption, Up: Encryption

3.1 Communication example 12

The encrypt directive is used to specify encryption in cfengine. To encrypt file transmission all you have to do is to include the encrypt=on or encrypt=true in the policy file.

     
     #cfagent.conf
     
     control:
      domain = ( mydomain.com )
      serverip = ( 192.10.10.2 )   #server ip address
      master = (  /home/mark/inputs )
      actionsequence = ( copy )
     
     copy:
     
        /master/cfengine/inputs server=$(serverip)
              dest=(master)
              recurse=inf
              trustkey=on
              encrypt=on
     


Next: , Previous: Encryption, Up: Top

4 Debugging tips

CFEngine has debugging tools that help to troubleshooting. You can run cfengine in debug mode by using the options dn where n range from nothing to 2. So we have -d0,-d1,-d2 and -d3. These options will generate outputs which enable one to debug error in the policy file. -d1 includes parsing information but d2 does not include passing information. -d0 means all debugging information and -d3 is for summary parsing information.

Command example

     cfagent -d2

When setting up cfservd, you might see the error message

     Apr 9 11:22:27 host.ex.org cfservd[613]: Host authentication failed or access denied

This means that cfservd cannot or will not authenticate the connection from your client machine. The message is generic. It is deliberately non-specific so that anyone attempting to attack or exploit the service will not be given information which might be useful to them. There is a simple checklist for curing this problem:

Remember that you can run both cfagent and cfservd in debugging mode to see how the authentication takes place:

     cfagent -d2
     cfservd -d2

Cfagent reports "access denied" regardless of the nature of the error, to avoid giving away information which might be used by an attacker. To find out the real reason for a denial, use debugging mode -d2.


Next: , Previous: Debugging Tips, Up: Top

5 Starting with cfrun

To use cfrun, you start by creating a configuration file called cfrun.hosts in /var/cfengine/inputs. In its simplest form, it simply contains a list of host names (one per line) that are to be contacted. If there are special options that you would like to set, globally or for a particular host, they can also be placed in the file. For example, the domain name is needed if you are going to use unqualified host names and your name resolution mechanism does not append a default domain.

Here is an example file:

     domain=cfengine.org
     access=mark,aeleen
     outputdir=/tmp/cfoutput
     maxchild=20
     hostnamekeys=true
     
     gudinne
     wallace:3333
     ...
     include=cfrun.external.hosts

Here, we define a list of allowed users, a directory for placing the output of cfrun queries, a maximum number of children to spawn for parallel connections, and required that hosts use key-based authentication. We also list two hosts (one with an alternate communication port), as well as including an external file listing more.

If the outputdir directive is in place, cfrun automatically uses a parallelized batch method of communication.


Next: , Previous: Starting with cfrun, Up: Starting with cfrun

5.1 Using the cfrun command

The cfrun command itself has the following form:

     cfrun - local options [host list] -- remote options -- remote classes

If not host list is included, then all of the hosts in cfrun.hosts are contacted.

Since cfrun addresses remote hosts from a local host, there is an ambiguity in whether options are intended for the cfrun command itself, or whether they are meant to be passed on to the agent on the remote hosts. To clarify this distinction, the arguments are organized as follows:

Here are some examples, all of which use the host list in cfrun.hosts:

cfrun -- -- linux
Run on all machines, specifying class linux.
cfrun -- -p
Just parse policy file on all hosts.
cfrun -v -- -v
Verbose output on local system and remote hosts.
cfrun -v -- -k -- solaris
Verbose local output; suppress copy/specify solaris on remote.


Next: , Previous: Using the cfrun command, Up: Starting with cfrun

5.2 DHCP and Dynamic Addresses

If you are using dynamic addressing for hosts, cfengine will struggle to justify its trust in the public keys it sees. To make sense of public keys one requires both a key and an independent identity to tie it to. Once a key has been trusted, the key alone is (in principle) sufficient identity (just as a fingerprint is good enough to represent you, once it has been registered).

When IP addresses change, cfservd loses its coupling between address and key identity and so it has to start re-evaluating. There are two cases to consider, and the default behavior is like this:

This can cause a problem for hosts with IPV4 addresses given by DHCP, since the address-key binding is only temporary. cfservd works around this by allowing you do define a new access list called

     DynamicAddresses = ( 192.240.1 )

If a connecting address is unknown, but lies in this range, cfservd will look in a database to see if the key itself is known, bound to a different address. If the key is found, cfservd trusts the binding and re-binds the key to the new IP address. If the key is not known, then (again) normal trust rules apply for accepting a new key.

Servers should always have fixed IP addresses in general, otherwise you have no idea to whom you are connecting.


Previous: DHCP and Dynamic Addresses, Up: Starting with cfrun

5.3 Public Key Exchange Issues

Public key exchange is a subtle idea. The issues are not difficult to understand, but they are seldom expressed very clearly.

The principle of a public key system is to associate an identity with a key, which can be freely made public knowledge. The difficulty is not in distributing the key, but in being certain who is really the owner of a key that you have received.

Imagine you wanted to know the identity of a stranger whom you have never seen before. What proof would you accept of his or her identity? A name tag? A letter of reference? A DNA test? Of course, an evil identical twin would be able to pass all of these tests and still fool you.

It is important to understand that trust in identity is something we always grant in an entirely personal way. There is always a chance of being wrong: cryptographic methods do not eliminate this doubt (although they sometimes are presented as doing so). Trust is risk, and you simply have to live with it.

There are two common models of trust management:

Key exchange in cfengine is very similar to that in the secure shell. However, cfengine uses separate keys from ssh that are generated using the cfkey program.

Cfagent is not an interactive program, so when it first receives a key, the decision as to whether to accept it must be made non-interactively. The natural solution is to make this decision part of policy. There are two methods for accomplishing this:

Once a key has been accepted on trust, it is trusted for ever, or until you revoke the key by explicitly deleting the key from /var/cfengine/ppkeys. So once the key has been exchanged, the trustkey option has no effect. Thus, on the client side it does not matter if you leave trustkey options in place. On the server side, however, remember that the trust rule applies to many hosts, some of which you might not have considered. Always take care with trust issues.


Previous: Starting with cfrun, Up: Top

6 Security Implications of using cfengine

Though the actual security implication of using cfengine is minimal we still need to be aware of possible risk and how we can protect ourselves. CFEngine uses autonomous agents which are complete on their own. Each agent manages it check sum database without the support of external server. This means if someone tampers with the database he could breach cfengine security. One of the solutions to this is to keep cfengine database at a secure location on the system or take a backup of the database.

We could also use neighborhood watch approach where databases of agents are distributed to the neighbors which can then be compared to the original agent’s database for consistency.

CFEngine depends on the policy configuration file for its operations. If this file is changed by an attacker, cfengine will implement the policy of the attacker. It is therefore important to ensure that cfengine configuration file is secured. CFEngine also runs with open port 5308 and therefore it is important to protect the port from external attack. It may be advisable to block external access to the port.

CFEngine authentication depends on public and private key pairs. The cfengine public keys transfer can be done implicitly or explicitly. It is important to ensure accountable key distribution.


Next: , Previous: Security Implications of using cfengine, Up: Security Implications of using cfengine

6.1 Security of pulling files


Next: , Previous: Security of pulling files, Up: Security Implications of using cfengine

6.2 CFEngine and Firewalls

Some users want to use cfengine's remote copying mechanism through a firewall, in particular to update the cfengine policy on hosts inside a DMZ (so-called de-militarized zone). Firewalls are often shrouded in myth and mystery. It is important to see the firewall security model together with the cfengine security model. Amongst the difficulties one faces, the firewall administrator is not often the same as the cfengine administrator and does not trust anyone or anything. You might have to convince this person to make changes that help you out, so it is important to understand the consequences of your security strategy.

Any piece of software that traverses a firewall can, in principle, weaken the security of the barrier. On the other hand, a strong piece or software might have better security than the firewall itself. Consider the example in the figure;

A cfengine host outside a firewall

We label the regions inside and outside of the firewall as the “secure area" and “Demilitarized Zone" for convenience. It should be understood that the areas inside a firewall is not necessarily secure in any sense of the word unless the firewall configuration is understood together with all other security measures.

Our problem is to copy files from the “secure” source machine to hosts in the DMZ, in order to send them their configuration policy updates. There are two ways of getting files through the firewall:

One of the main aims of a firewall is to prevent hosts outside the secure area from opening connections to hosts in the secure area. If we want cfagent processes on the outside of the firewall to receive updated policies from the inside of the firewall, information has to traverse the firewall.


Next: , Previous: CFEngine and Firewalls, Up: CFEngine and Firewalls

6.2.1 CFEngine trust model

Cfengine's trust model is fundamentally at odds with the external firewall concept. CFEngine says: “I am my own boss. I don't trust anyone to push me data.” The firewall says: “I only trust things that are behind me.” The firewall thinks it is being secure if it pushes data from behind itself to the DMZ. CFEngine thinks it is being secure if it makes the decision to pull the data autonomously, without any orders from some potentially unknown machine. One of these mechanisms has to give if firewalls are to co-exist with cfengine.

From the firewall's viewpoint, push and pull are different: a push requires only an outgoing connection from a trusted source to an untrusted destination; a pull necessarily requires an untrusted connection being opened to a trusted server within the secure area. For some firewall administrators, the latter is simply unacceptable (because they are conditioned to trust their firewall). But it is important to evaluate the actual risk. We have a few observations about the latter to offer at this point:


Next: , Previous: CFEngine trust model, Up: CFEngine and Firewalls

6.2.2 Policy Mirror in the DMZ

You can compromise by creating a policy mirror in the DMZ. This is the recommended way to copy files, so that normal cfengine pull methods can then be used by all other hosts in the DMZ, using the mirror as their source. The policy mirror host should be as secure as possible, with preferably few or no other services running that might allow an attacker to compromise it. In this configuration, you are using the mirror host as an envoi of the secure region in the DMZ.

Any method of pushing a new version of policy can be chosen in principle: CVS, FTP, RSYNC, SCP. The security disadvantage of the push method is that it opens a port on the policy-mirror, and therefore the same vulnerability is now present on the mirror, except that now you have to trust the security of another piece of software too. Since this is not a cfengine port, no guarantees can be made about what access attackers will get to the mirror host.


Previous: Policy Mirror in the DMZ, Up: CFEngine and Firewalls

6.2.3 Pulling through a wormhole

Suppose you are allowed to open a hole in your firewall to a single policy host on the inside. To distribute files to hosts that are outside the firewall it is only necessary to open a single tunnel through the firewall from the policy-mirror to the cfengine service port on the source machine. Connections from any other host will still be denied by the firewall. This minimizes the risk of any problems caused by attackers.

To open a tunnel through the firewall, you need to alter the filter rules. A firewall blocks access at the network level. Configuring the opening of a single port is straightforward. We present some sample rules below, but make sure you seek the guidance of an expert if necessary.

Cisco IOS rules look like this

     ip access-group 100 in
     access-list     100 permit tcp mirror host source eq 5308
     access-list     100 deny   ip  any any

Linux iptables rules might look something like this:

     iptables -N newchain
     iptables -A newchain -p tcp -s mirror-ip 5308 -j ACCEPT
     iptables -A newchain -j DENY

Once a new copy of the policy is downloaded by cfengine to the policy mirror, other clients in the DMZ can download that copy from the mirror. The security of other hosts in the DMZ is dependent on the security of the policy mirror.


Next: , Previous: CFEngine and Firewalls, Up: Security Implications of using cfengine

6.3 Neighbourhood watch

CFEngine can be centralized or decentralized depending on the requirement and the choice of the user. The centralized infrastructure consists of policy server which will store the policy configuration files for distribution; the rest of the hosts will pull their policy from this centralized server. The merit of centralized administration are that it aids consistency by providing single point of decision making, change of policy is easy since it is done at one place, backup and version control are also convenient. However, centralized administration could hinder local customization; it is inappropriate for privacy and security if we have completely independent departments or services which needs to coexist and work together.


Previous: Centralization and Decentralization, Up: Security Implications of using cfengine

6.4 Tamperproof data and distributed monitoring

Message digests are supposed to be unbreakable, tamperproof technologies, but of course everything can be broken by a sufficiently determined attacker. Suppose someone wanted to edit a file and alter the cfengine checksum database to cover their tracks. If they had broken into your system, this is potentially easy to do. How can we detect whether this has happened or not?

A simple solution to this problem is to use another checksum-based operation to copy the database to a completely different host. By using a copy operation based on a checksum value, we can also remotely detect a change in the checksum database itself.

Consider the following code:

     # Neighbourhood watch
     
     control:
     
       allpeers = (
                  SelectPartitionNeighbours(/path/hostlist,#,random,4)
                  )
     
     copy:
     
           /var/cfengine/checksum_digests.db
     
                             dest=/safekeep/chkdb_$(this)
                             type=checksum
                             server=$(allpeers)
                             inform=true          # warn of copy
                             backup=timestamp
                             define=tampering
     
     alert:
     
       tampering::
     
            'Digest tampering detected on a peer'
     

It works by building a list of neighbours for each host. The function SelectPartitionNeighbours

can be used for this. Using a file which contains a list of all hosts running cfengine (e.g. the cfrun.hosts file), we create a list of hosts to copy databases . Each host in the network therefore takes on the responsibility to watch over its neighbours.

The copy rule attempts to copy the database to some file in a safekeeping directory. We label the destination file with $(this) which becomes the name of the server from which the file was collected. Finally, we backup any successful copies using a timestamp to retain a complete record of all changes on the remote host. Each time a change is detected, a copy will be kept of the old. The rule contains triggers to issue alerts and warnings too just to make sure the message will be heard.

In theory, all four neighbours should signal this change. If an attacker had detailed knowledge of the system, he or she might be able to subvert one or two of these before the change was detected, but it is unlikely that all four could be covered up. At any rate, this approach maximizes the chances of change detection.

Finally, in order to make this copy, you must, of course, grant access to the database in cfservd.conf.

     
     # cfservd.conf
     
     admit:
     
     any::
     
        /var/cfengine/checksum_digests.db  mydomain.tld
     

Let us now consider what happens if an attacker changes a file an edits the checksum database. Each of the four hosts that has been designated a neighbour will attempt to update their own copy of the database. If the database has been tampered with, they will detect a change in the md5 checksums of the remote copy versus the original. The file will therefore be copied.

It is not a big problem that others have a copy of your checksum database.  They cannot see the contents of your files from this.  A possibly greater problem is that this configuration will unleash an avalanche of messages if a change is detected. This makes messages visible at least.

  • Explain why cfengine is tamper proof?
  • What are the security implications of running cfengine?
  • Explain change management and how cfengine implements change management?

Table of Contents