Next: , Previous: Installation of cfd, Up: Configuring cfd


7.3.2 Configuration file cfd.conf

The server daemon is controlled by a file called cfd.conf. The syntax of this configuration file is deliberately modelled on cfengine's own configuration file, but despite the similarities, you cannot mix the contents of the two files.

Though they are not compatible, cfengine.conf and cfd.conf are similar in several ways:

Note that the classes in the cfd.conf file do not tell you the classes of host which have access to files and directories, but rather which classes of host pay attention to the access and deny commands when the file is parsed.

Host name authentication is not by class or group but by hostname, like the /etc/exports file on most unix systems. The syntax for the file is as follows:

     
      control:
     
        classes::
     
            domain = ( DNS-domain-name )
     
            cfrunCommand = ( "script/filename" )  # Quoted
     
            AutoExecCommand = ( "cfengine-start-script" )
     
            AutoExecInterval = ( 60 )
     
            MaxConnections = ( maximum number of forked daemons )
     
            ChecksumDatabase = ( filename )
     
            IfElapsed = ( time-in-minutes )
     
            DenyBadClocks = ( false )
     
            AllowConnectionsFrom = ( IP numbers )
     
            DenyConnectionsFrom = ( IP numbers )
     
            AllMultipleConnectionsFrom = ( IP numbers )
     
            LogAllConnections = ( false/true )
     
            SkipVerify = ( IP numbers )
     
      groups:
     
        Group definitions
     
      import:
     
        Files to import
     
      admit: | grant:
     
        classes::
     
           /file-or-directory
     
             wildcards/hostnames
     
      deny:
     
        classes::
     
           /file-or-directory
     
             wildcards/hostnames root=hostlist secure=true/on
     

The file consists of a control section and access information. You may use the control section to define any variables which you want to use in the remainder of your file. Two variables are special here, they are reserved.

cfrunCommand
This string is the command which you would like to be executed remotely by the cfrun command.
AutoExecCommand
This is the name of a command which you use to execute cfengine automatically after the interval specified in AutoExecInterval. Since the output route is ambiguous for a daemon, you should provide a wrapper for cfengine which mails you the output, just as you would with cron. This script should not normally produce any output itself. Any output will go to syslog.
AutoExecInterval
A number of minutes after which you would like cfengine to be run, even if you do not force a run with cfrun. This can be used instead of, or in addition to cron. If used with cron, take precautions to set suitable values for IfElapsed so that unnecessary overlap is avoided.
MaxConnections
This integer value sets a limit on the maximum number of child daemon threads which cfd will `fork' in order to handle remote requests. The default value is ten.
IfElapsed
The IfElapsed anti-spamming filter is also built into cfd so that a remote user cannot even get as far as causing cfengine to parse its input files (which could be used for spamming in itself). The time is in minutes, the default is one hour.


ChecksumDatabase
This is the path and filename to a database which will cache MD5 checksum values server-side. This optimization is only available if you have the Berkeley database library `libdb' on your system. If this variable is not defined, no database caching will be used and checksum values will be computed directly on request. The utility of this solution is a trade-off between the time it takes to compute the checksum versus the time for a disk-based lookup.
DenyBadClocks
If this is set to off, cfd will not deny access to clients whose clocks are off by more than one hour. The default is to deny access to systems whose clocks differ by more than one hour. This can prevent messages of the form `Can't stat' file when remote copying.
AllowConnectionsFrom
This variable allows a list of numerical IP masks to be specified, which cfd will allow connections from. If the list is not empty and a host whose IP address is not specified attempts to connect to the daemon, its connection will be closed immediately. This can be used to prevent hanging connection attacks from malicous hosts and other denial of service attacks which would bind thread resources.
               control:
          
                AllowConnectionsFrom = ( 128.39.89  192.2.0.10 )
          
     


DenyConnectionsFrom
Hosts which are included by the allow-list above can be explicitly denied access using this list.
               control:
          
                DenyConnectionsFrom = ( 128.39.89.76 )  # rogue host
          
     


AllowMultipleConnectionsFrom
This variable should contain a list of IP wildcards to hosts which are allowed simultaneous sessions on the server. Hosts which are not in this list are allowed to connect only once, i.e. they must terminate and reconnect in order to establish a new session. This is to prevent a possible attacker from opening multiple sockets and never closing them, resulting in a denial of service attack. Hosts IP's can be placed here if they could have overlapping copy sessions (e.g. long backup transfers which can run over time). This prevents the error message "Multiple connections denied/spam shield".

This replaces the AllowMultipleConnections boolean variable which existed in version 1.5.4 (only).

SkipVerify
If connecting hosts use a Network Address Translator in order to share an IP address, reverse lookup will fail to give a correct verification of host identity. You can switch off cfd's verification of host identity for specific IP addresses or patterns using this command. E.g.
          
          SkipVerify = ( 192.0.0.10  192.0.2.  )
          
     

NOTE!! This is a security risk because it means that cfd implicitly trusts the connecting hosts! You should be very careful in using Network Address Translators in a secure environment. It is not recommended for sites which require a high level of security.

LogAllConnections
If set to true, every successful connection will be logged to syslog. This could be useful for identifying abuses of the service, if the server should come under attack, e.g. a denial of service attack. The IP address can then be excluded from the allowed connections list.
root=
This list specificies the names of hosts which are to have read access to files, regardless of the owner of the file. This effectively gives root users on connecting hosts privileges to non-root owned files on the server, but not vice-versa, similar to the NFS root mapping, except that there is no question of a client being able to modify files on the server. Caution: cfd trusts the DNS service, so be aware that cache poisoning attacks are a possible way of bypassing access controls.
secure=true
If this option is set, cfd will only serve the named files if the copy access type is secure, i.e. on an encrypted link. This presupposes that cfengine has been compiled with a working DES or SSLeay library.

Following the control section comes a list of files or directories and hosts which may access these. If permissions are granted to a directory then all sub directories are automatically granted also. Note that symbolic links are not checked for, so you may need to specifically deny access to links if they are plain files, but cfd does not follow symbolic links and give access to files in other directories.

Fully qualified hostnames should be given in this file. Do not forget to define the domain name. Authentication calls the unix function gethostbyname() and so on to identify and verify connecting hosts, so the names in the file must reflect the type on names returned by this function. You may use wildcards in names to match, for instance, all hosts from a particular domain.

Here is an example file

     #####################################################
     #
     # This is a cfd config file
     #
     #####################################################
     
     groups:
     
       PasswdHost = ( nexus )
     
     #####################################################
     
     control:
     
       #
       # Assuming CFINPUTS is defined
       #
     
       cfrunCommand = ( "/usr/local/bin/cfengine" )
     
       variable = ( /usr/local/publicfiles )
     
     #####################################################
     
     admit:   # Can also call this grant:
     
        PasswdHost::
     
          /etc/passwd
     
             *.iu.hioslo.no
     
         FtpHost::
     
         # An alternative to ftp, grant anyone
     
            /local/ftp/pub
     
              *
     
         any::
     
            $CFINPUTS/cfrun.sh
     
              *.iu.hioslo.no
     
     #####################################################
     
     deny:
     
        /etc/services
     
            borg.iu.hioslo.no
     
       /local/ftp
     
            *.pain-in-the-ass.com
     
     

NOTE I: cfd is not rpc.mountd, access control is by filename, not by device name. Do not assume that files lying in subdirectories are not open for access simply because they lie on a different device. You should give the real path name to file and avoid symbolic links.

NOTE II: access control is per host and per user. User names are assumed to be common to both hosts. There is an implicit trust relationship here. There is no way to verify whether the user on the remote host is the same user as the user with the same name on the local host.

If you still have problems with lack of access, it could be that you have forgotten to define the domain name for your network, or that you do not understand the TCP wrappers files /etc/hosts.access and /etc/hosts.deny.