Cfengine configuration directory

Setting up keys for remote communication

Relevant classes: any

  1. On each host, run cfkey once to generate a public-private key pair.
  2. You will not need to copy these keys by hand to other hosts. Keys are exchanged automatically by cfengine.
  3. In the server configuration cfservd.conf, add lines to allow hosts to connect to the server. This is to permit a range of validation tests, like TCP wrappers, but more exacting.
      # Don't forget the domain name
    
      domain = ( example.org )
    
      cfrunCommand = ( "/var/cfengine/bin/cfagent" )
    
      # Prevent DOS attacks
    
      MaxConnections = ( 50 )
    
      AllowConnectionsFrom = (
                             128.39.75    # ipv4 prefixes
                             2001:700:700 # ipv6 prefixes
                             )
    
      #
      # Allow more than one simultaneous connection from friendly hosts
      #
    
      AllowMultipleConnectionsFrom = ( 128.39.89 128.39.74 128.39.75 )
    
      ###################################################################
      # THIS SECTION IS ABOUT THE TRUST MODEL
      #
      # Uncomment this only during the key exchange window.
      #
      # TrustKeysFrom = ( 128.39.89  128.39.74 2001:700:700:  128.39.74 128.39.75 )
    
    
      ##################################################################
      # ONCE KEYS ARE EXCHANGED
      #
      # Which users-keys are allowed to access the services on cfservd, e.g. with cfrun
      #
    
      AllowUsers = ( mark root )
    
    
  4. The problem of key distribution is the conundrum of every public key infrastructure. Key transference is handled by cfengine -- but the security of keys depends on a careful protection. The point to understand carefully is the TrustKeysFrom stanza. Normally when keys are offered to a server (e.g. ssh), they are accepted on trust because no one is available to make a decision about them. There is thus a race to be the first to submit a key claiming identity. Even with checks for correct IP address (which may be spoofed), it might be possible to submit a false key to a server. Cfservd blocks the acceptance of unknown keys by default. In order to accept such a new key, the IP address of the presumed client must be listed in the TrustKeysFrom stanza. Once a key has been accepted, it will never be replaced with a new key, thus no more trust is offered or required.
  5. Once you have arranged for the right to connect to the server, you must decide which hosts will have access to which files. This is done with admit/deny rules.
     admit:
    
       /files   hosts IPs root=mappedhost
    
    
    
  6. On the client side, i.e. cfrun and cfagent, what you do depends on which program you are running. There are three issues:
    1. Choosing the server (setting server=serverhost)
    2. Trusting the identity of a previously unknown server, and trusting the server's claimed key. Here the issue is the same as on the server side.
    3. Choosing whether data transfers should be encrypted (with encrypt=true)
Because there are two ways to connect to a cfservd server (cfagent and cfrun), there are two ways on managing trust of server keys. One is to set the option trustkey=true in a copy stanza, e.g.
copy:
    /source dest=/destination 
        mode=400
        o=root 
        server=serverhost

        # Uncomment this, when you are sure that the server can only be the real one
        # trustkey=true

Another way is to run cfrun. When you run cfrun, unknown server keys are offered to you interactively, as with ssh, for you to accept or deny manually:
host$ /local/sbin/cfrun ubik
cfrun(0):         .......... [ Hailing ubik.iu.hio.no ] ..........
WARNING - You do not have a public key from host ubik.iu.hio.no = 128.39.74.25
          Do you want to accept one on trust? (yes/no)
-->

One server, many clients: time windows

Normally, you will have a central server and many clients. Then the best way to transfer all the keys is to set the trustkey flags on server and clients sides to concide with a time at which you know that cfengine will be run, and when a spoofer is unlikely to know.

This is a one-off job, and the chance of a attacker being able to spoof a key transfer is highly remote. It would require skill and inside information, which would tend to imply that the trust model was already broken.

Another thing would be to run cfrun against all the hosts in the group from the central server and accept the keys one by one, by hand, though there is little to be gained from this.

What trust does NOT mean

Trusting a host for key exchange is unavoidable. There is no clever way to avoid it. Even tranferring the files manually by diskette, and examining every serial number of the computers you have, the host has to trust the information you are giving it. It is all based on assertion. You can make it essentially impossible for keys to be faked or attacked, but you cannot make it absolutely impossible. Security is about managing reasonable levels of risk, not about magic.

All security is based on a moment of trust at some point in time. Cryptographic key methods only allow the need for a repeat of that trust to be repeated. Every time after the first, trust is not needed, because they keys allow identity to be verified strongly.

Even if you leave the trust options switched on, you are not blindly trusting the hosts you know about. The only potential insecurity lies in any new keys. If you use wildcards or IP prefixes in the trust rules, then other hosts might be able to spoof their way in on trust because you have left open a hole for them to exploit. That is why it is recommended to return the system to the default state of zero trust immediately after key transfer, by commenting out the trust options.

Other users than root

Note that cfengine normally runs as user "root". If other users are to be granted access to the system, they must also generate a key and go through the same process. In addition, the users must be added to the server configuration file.

Out of band transfer

It is possible, though somewhat laborious to transfer the keys out of band, by copying /var/cfengine/ppkeys/localhost.pub to /var/cfengine/ppkeys/user-aaa.bbb.ccc.mmm on another host. e.g.
localhost.pub -> root-128.39.74.71.pub
This would be a silly way to transfer keys between hosts that you control yourself, but if transferring to long distance, remote hosts, it might be an easier way to manage trust.

Session encryption

Note finally: cfengine's encryption is for keeping private file contents. It is assumed that users will use this judiciously. There is nothing to be gained by encrypting the transfer of public files.
Back to documentation