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
cfengine-hub
.
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 hubgituser
on
git-server-zero
and ensured that /srv/git
on 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 armv6l
The 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:~ $
Ok! Confirmed!
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 personal.yaml
:
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 /var/cfengine/inputs
!
# 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 foobarbaz
! Success!
$ 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.