No expansion of $(connection.hostname)

45 views
Skip to first unread message

Enrico Scholz

unread,
Mar 22, 2016, 9:50:54 AM3/22/16
to help-c...@googlegroups.com
Hi,

I try to utilize the 'shortcut' statement in cfengie-3.8.1 to allow
clients to copy files from a relative path "host_cfinput".

In cf-serverd's configuration I wrote

| bundle server generic_rules {
| access:
| "/srv/cfengine3/$(connection.hostname)"
| shortcut => "host_cfinput";
| }

and try to restrict access by subsequent

| access:
| "/srv/cfengine3/foo.example.com"
| admit_keys => { "MD5=362c5fcf568b492f78ae392229299c05" };
|
| access:
| "/srv/cfengine3/bar.example.com"
| admit_keys => { "MD5=0a9082478b1a1466f6e56fd5e48db8c4" };

rules (but this does not seem to matter).


When client tries to copy from 'source => "host_cfinput/somefile"', the
server reports

| Failed to canonicalise filename '/srv/cfengine3/$(connection.hostname)/somefile' (realpath: No such file or directory)


How are $(connection.XXXX) like variables to be used?



Enrico

Nick Anderson

unread,
Mar 22, 2016, 11:17:50 AM3/22/16
to Enrico Scholz, help-c...@googlegroups.com
On 03/22/2016 08:50 AM, Enrico Scholz wrote:
> How are $(connection.XXXX) like variables to be used?

Hi Enrico,

The connection variables are expanded by cf-serverd when clients
connect. In the
case of connection.hostname, the variable expands to the hostname of the
connecting agent as determined by a *reverse DNS lookup* from
cf-serverd. So you
need to make sure that you have proper reverse dns resolution in order
to use
that. If instead of organizing the files by hostname, you organized them
by key
sha you should be able to allow each host access to its own directory using
something like the following:

#+begin_src cfengine3
bundle server my_special_access_rules
{
access:

# /srv/cfengine3/MD5=0a9082478b1a1466f6e56fd5e48db8c4/<stuff>

"/srv/cfengine3/$(connnection.key)"
shortcut => "host_cfinput",
admit_keys => { $(connetion.key) };
}
#+end_src

And then in an agent bundle you can do this:

#+begin_src cfengine3
bundle agent have_a_copy_of_my_files
{
files:
# Using the shortcut
"/tmp/myfiles/."
copy_from => remote_dcp("host_cfinput", $(sys.policy_hub)),
depth_search => recurse(inf);

# Without using the shortcut
"/tmp/another_myfiles/."
copy_from => remote_dcp("/srv/cfengine3/$(sys.key_digest)/.",
$(sys.policy_hub)),
depth_search => recurse(inf);
}
#+end_src

Now you can have a directory for each host in /srv/cfengine3/ named for the
public key sha of the host. Each host is only allowed to access its own
directory since you have mapped the directory to the admit_keys in a 1:1
relationship.

For reference, here is what my srv directory looks like:

[root@hub masterfiles]# find /srv/cfengine3/
/srv/cfengine3/
/srv/cfengine3/SHA=008647e169b06b93c52f4d0f0517ecd4eec893ee150d8f6ab842e2040160a7bb
/srv/cfengine3/SHA=008647e169b06b93c52f4d0f0517ecd4eec893ee150d8f6ab842e2040160a7bb/hostname.txt
/srv/cfengine3/SHA=ee29780b3c86d486699f97e30c5924431475b1b06e02c2724dd925c1524afef6
/srv/cfengine3/SHA=ee29780b3c86d486699f97e30c5924431475b1b06e02c2724dd925c1524afef6/hostname.txt
/SHA=ee29780b3c86d486699f97e30c5924431475b1b06e02c2724dd925c1524afef6/another_file.txt

And the directories that it copied down:

[root@hub masterfiles]# find /tmp/myfiles/
/tmp/myfiles/
/tmp/myfiles/another_file.txt
/tmp/myfiles/hostname.txt

You have new mail in /var/spool/mail/root
[root@hub masterfiles]# find /tmp/another_myfiles
/tmp/another_myfiles
/tmp/another_myfiles/another_file.txt
/tmp/another_myfiles/hostname.txt

I hope this helps.



signature.asc

Enrico Scholz

unread,
Mar 22, 2016, 11:54:29 AM3/22/16
to help-c...@googlegroups.com
Nick Anderson <nick.a...@cfengine.com> writes:

>> How are $(connection.XXXX) like variables to be used?
>
> The connection variables are expanded by cf-serverd when clients
> connect. In the case of connection.hostname, the variable expands to
> the hostname of the connecting agent as determined by a *reverse DNS
> lookup* from cf-serverd.

> So you need to make sure that you have proper reverse dns resolution
> in order to use that.

I have verified that the reverse lookup works.

In the meantime I have found out, that things seem to work as expected
when I add an empty

| admit_hostnames => { },


> If instead of organizing the files by hostname, you organized them
> by key sha you should be able to allow each host access to its own
> directory using something like the following:
>
> #+begin_src cfengine3
> # /srv/cfengine3/MD5=0a9082478b1a1466f6e56fd5e48db8c4/<stuff>
> "/srv/cfengine3/$(connnection.key)"

I would really like to avoid placing $(connection.key) in the filename,
because:

* it is unreadable (having dozens of directories with meaningless
'MD5=...' names makes it difficulty to find the directory belonging
to 'foo.example.com')

* it creates trouble when client key changes (e.g. because it was
compromised or because host will be reinstalled). 'git' (which is
used to organize my cfengine rules) does not support renaming of
files/directories and I would lose history of changes with 'git mv'.



Enrico

Nick Anderson

unread,
Mar 22, 2016, 12:55:55 PM3/22/16
to Enrico Scholz, help-c...@googlegroups.com
On 03/22/2016 10:54 AM, Enrico Scholz wrote:
> I would really like to avoid placing $(connection.key) in the filename,
> because:
>
> * it is unreadable (having dozens of directories with meaningless
> 'MD5=...' names makes it difficulty to find the directory belonging
> to 'foo.example.com')
>
> * it creates trouble when client key changes (e.g. because it was
> compromised or because host will be reinstalled). 'git' (which is
> used to organize my cfengine rules) does not support renaming of
> files/directories and I would lose history of changes with 'git mv'.

bundle server my_host_access_rules
{
vars:
# You can build a map of hostname to keys.
# You might prefer to do this in an external data file formated as
JSON and
# use readjson to read it in.
#
# {
# "hub": "SHA=e...",
# "host001": "SHA=b..."
# }

"name_to_key[hub]" string =>
"SHA=ee29780b3c86d486699f97e30c5924431475b1b06e02c2724dd925c1524afef6";
"hosts" slist => getindices( name_to_key );

access:
# Grant access to the directory named for the currently iterated
host to the public key sha for that host.
"/srv/cfengine3/$(hosts)/."
admit_keys => { "$(name_to_key[$(hosts)])" };
}

signature.asc
Reply all
Reply to author
Forward
0 new messages