How to serve policy from a local git server
Posted by: Craig Comstock
Several months ago I started the practice of using CFEngine Enterprise and its Mission Portal UI on a daily basis to manage the connected devices in my home. To start, I brought up an old desktop machine,
cfengine-hub, to use as my hub and downloaded Enterprise, which is free for use up to 25 hosts.
The next step in using best practices is to deploy policy from a version control repository.
I use a local git server named
git-server-zero instead of Github or Gitlab as I like to be independent of the cloud when possible due to privacy and environmental concerns.
I will use the Mission Portal Version Control Repository settings section to setup this repo as the source of policy for
Configuring the git server
You can choose whether to use a username/password combination for your git URL or a passphrase-less key. I am choosing the latter.
root@cfengine-hub:~# ssh-keygen -o Generating public/private rsa key pair. Enter file in which to save the key (/root/.ssh/id_rsa): /root/.ssh/hub_rsa Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /root/.ssh/hub_rsa. Your public key has been saved in /root/.ssh/hub_rsa.pub. The key fingerprint is: SHA256:[a-z] root@cfengine-hub
In case the account on the hub gets compromised I want to prevent writes from this user. I created a new account called
git-server-zero and ensured that
git-server-zero has only read permissions for this user. Afterwards, I added the public key generated on
cfengine-hub to the
hubgituser‘s authorized keys.
root@git-server-zero:/home/hubgituser/.ssh# cat /root/.ssh/hub_rsa.pub >> authorized_keys
Now check that the connection works between my hub and the git server, while ensuring that I have no saved keys in my ssh-agent.
root@cfengine-hub:~# eval $(ssh-agent -s) Agent pid 6334 root@cfengine-hub:~# ssh-add -D All identities removed. root@cfengine-hub:~# ssh-add .ssh/hub_rsa Identity added: .ssh/hub_rsa (root@cfengine-hub) root@cfengine-hub:~# ssh hubgituser@git-server-zero Linux git-server-zero 4.9.59+ #1047 Sun Oct 29 11:47:10 GMT 2017 armv6lThe programs included with the Debian GNU/Linux system are free software; the exact distribution terms for each program are described in the individual files in /usr/share/doc/*/copyright. Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law. Last login: Wed Jul 15 16:14:33 2020 from 192.168.1.2 hubgituser@git-server-zero:~ $
Configuring Mission Portal Version Control Repository
Now to Mission Portal and entering the details as mentioned in Configuring Upstream VCS. Login and navigate to Settings and then Version control repository:
Enter details, select the private key file and click Apply.
Initial Sync of Policy
If you use Mission Portal to configure VCS settings then the initial sync will occur automatically after a little while. To test things out right away or if you configured manually then run the following:
root@cfengine-hub:/opt/cfengine/dc-scripts# cf-agent -KIf update.cf --define cfengine_internal_masterfiles_update info: Executing 'no timeout' ... '/var/cfengine/httpd/htdocs/api/dc-scripts/masterfiles-stage.sh' info: Command related to promiser '/var/cfengine/httpd/htdocs/api/dc-scripts/masterfiles-stage.sh' returned code defined as promise kept 0 info: Completed execution of '/var/cfengine/httpd/htdocs/api/dc-scripts/masterfiles-stage.sh'
Any troubles? Run the
masterfiles-stage.sh script in debug mode with
-D or also with
bash -x. For example, once I tried these steps and got a password prompt which I should not:
root@cfengine-hub:~# bash -x /var/cfengine/httpd/htdocs/api/dc-scripts/masterfiles-stage.sh -D Option Deploy Dir: /var/cfengine/masterfiles Option Params File: /opt/cfengine/dc-scripts/params.sh Cloning into bare repository '/opt/cfengine/git_git_server_zero__srv_git_masterfiles'... hubgituser@git-server-zero's password:
Test Policy Deployment
Now let’s try making a change to policy and see if it goes through. I push a commit to add a hashed password for a user promise in a file called
craig@laptop:~/src/masterfiles$ git push Enumerating objects: 9, done. Counting objects: 100% (9/9), done. Delta compression using up to 4 threads Compressing objects: 100% (5/5), done. Writing objects: 100% (5/5), 1.02 KiB | 1.02 MiB/s, done. Total 5 (delta 3), reused 0 (delta 0) To git-server-zero:/srv/git/masterfiles.git 265bb3b..292ee56 master -> master
And then ran the agent asking for updates again:
info: Copied file '/var/cfengine/masterfiles/services/autorun/personal.yaml' to '/var/cfengine/inputs/services/autorun/personal.yaml.cfnew' (mode '600') info: Backed up '/var/cfengine/inputs/services/autorun/personal.yaml' as 'var/cfengine/inputs/services/autorun/personal.yaml.cfsaved' info: Moved '/var/cfengine/inputs/services/autorun/personal.yaml.cfnew' to '/var/cfengine/inputs/services/autorun/personal.yaml' info: Updated '/var/cfengine/inputs/services/autorun/personal.yaml' from source '/var/cfengine/masterfiles/services/autorun/personal.yaml' on 'localhost' info: Purged '/var/cfengine/inputs/services/autorun/personal.yaml.cfsaved' copy dest directory info: Purged '/var/cfengine/inputs/cf_promises_release_id.cfsaved' copy dest directory info: files promise '/var/cfengine/inputs' repaired
The change is present in
# foobarbaz demo password - hashed_password: $6$hckmJCcp/vOWNjeH$s3FsHKoBuoVpKJW0XhuojyDK5yp1FqixtX5RE.kP8cwWpphmbIpeJ5lvsaKjDPp9I5FBRpBnXOHfrHW2nIM4k1
So let’s see if it takes effect on
cfengine-hub by trying to login as agent.
I can login with
$ hostname cfengine-hub $ whoami agent
Now I can make changes to policy, push the changes to my git server and the change will roll out to all my agents/hosts automatically.