Uploaded image for project: 'CFEngine Community'
  1. CFEngine Community
  2. CFE-2613

Ship cf-keycrypt functionality

    XMLWordPrintable

    Details

    • Type: Task
    • Status: Done
    • Priority: Medium
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: 3.16.0, 3.15.3
    • Component/s: cf-secret
    • Labels:
      None

      Description

      Jon Henrik Bjørnstad has kindly re-licensed cf-keycrypt so that we can vendor it.

      https://github.com/cfengineers-net/cf-keycrypt/pull/5

      https://github.com/cfengineers-net/cf-keycrypt/commit/c89ea91b07a69e4ec2f70fdbd5fc07d791b461a8

      There 2 main ways to use cf-keycrypt.

      1. Encrypt for a particular node

      On policy hub:

      hub# cf-keycrypt -H 192.168.1.20 -i /path/to/plain_input_file -o /path/to/encrypted_output_file
      

      -H will look in lastseen database to find the public key it has recorded for a particular ip address.

      This file can then be made accessible on the policy hub and copied over to the client in question. You could even
      put it in masterfiles if you want.

      On the client to decrypt:

      client# cf-keycrypt -d /var/cfengine/ppkeys/localhost.pub -i /path/to/encrypted_input_file -o /path/to/plain_output_file
      

      Only the client with the corresponding private key will be able to decrypt.

      2. Encrypt for a particular group of nodes

      Create a public/private keypair for the group on the policy hub:

      hub# cf-key -f /path/to/keyfiles/securitygroup1
      

      You will then have securitygroup1.priv and securitygroup1.pub under /path/to/keyfiles. You can then distribute the private key to all nodes of part of that group, potentially by using encryption per node as described above. Or you could use admit rules in cf-serverd on the policy hub.

      You can now use cf-keycrypt to encrypt for the group

      On policy hub:

      hub# cf-keycrypt -e /path/to/keyfiles/securitygroup1.pub -i /path/to/plain_input_file -o /path/to/encrypted_output_file
      

      On the hosts holding the private key:

      client# cf-keycrypt -d /path/to/keyfiles/securitygroup1.pub -i /path/to/encrypted_input_file -o /path/to/plain_output_file
      

      The following two examples is mainly for use with commands promises in CFEngine as follows:

      commands:
      
         "/var/cfengine/libexec/cf-keycrypt -e /path/to/keyfiles/securitygroup1.pub -i /path/to/plain_input_file -o /path/to/encrypted_output_file";
      
      

      But you could potentially also use it to read encrypted data into memory as the following example shows.

      hub# cat /tmp/data.json
      {
      	"key1": "value1"
      }
      
      hub# cf-keycrypt -H 192.168.1.20 -i /tmp/data.json -o /tmp/data.json.crypt
      

      Then you could use it directly in policy like this:

      cf-keycrypt.cf:

      body common control {
       bundlesequence => { "cf_keycrypt" };
      }
      
      
      
      bundle agent cf_keycrypt {
       vars:
        "secret_data" data => parsejson(
          execresult(
           "$(sys.workdir)/libexec/cf-keycrypt -d $(sys.workdir)/ppkeys/localhost.priv -i /tmp/data.json.crypt -o -",
           "noshell"
          )
         );
      
       reports:
        cfengine_3::
         "$(secret_data[key1])";
      }
      
      client# cf-agent -K -f cf-keycrypt.cf 
      R: value1
      

      How to test

      Testing encryption/decryption with a specific key

      1) Generate a key with cf-key
      cf-key /tmp/mykey

      2) Encrypt a file using the key
      cf-keycrypt -e /tmp/mykey.pub -i /path/to/plain -o /path/to/encrypted

      3) Decrypt the file
      cf-keycrypt -d /tmp/mykey.pub -i /path/to/encrypted -o /path/to/newplain

      4) Compare the file before and after encryption
      diff /path/to/plain /path/to/newplain

      Testing encryption based on a hosts IP

      For this test IP should be derived from the localhost.

      1) Encrypt a file using the key
      cf-keycrypt -H IP -i /path/to/plain -o /path/to/encrypted

      2) Decrypt the file
      cf-keycrypt -d /tmp/mykey.pub -i /path/to/encrypted -o /path/to/newplain

      3) Compare the file before and after encryption
      diff /path/to/plain /path/to/newplain

      Testing encryption based on a hosts name

      For this test HOSTANME should be derived from the localhost.

      1) Encrypt a file using the key
      cf-keycrypt -H HOSTNAME -i /path/to/plain -o /path/to/encrypted

      2) Decrypt the file
      cf-keycrypt -d /tmp/mykey.pub -i /path/to/encrypted -o /path/to/newplain

      3) Compare the file before and after encryption
      diff /path/to/plain /path/to/newplain

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                vpodzime Vratislav Podzimek
                Reporter:
                a10042 Nick Anderson
              • Votes:
                2 Vote for this issue
                Watchers:
                9 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved:

                  Summary Panel