... | @@ -587,7 +587,10 @@ general, it's safe to use `trocla create` as it will reuse existing |
... | @@ -587,7 +587,10 @@ general, it's safe to use `trocla create` as it will reuse existing |
|
password. It's actually how the `trocla()` function behaves in Puppet
|
|
password. It's actually how the `trocla()` function behaves in Puppet
|
|
as well.
|
|
as well.
|
|
|
|
|
|
## Exported resources
|
|
|
|
|
|
## Getting information from other nodes
|
|
|
|
|
|
|
|
### Exported resources
|
|
|
|
|
|
Our Puppet configuration supports [exported resources](https://puppet.com/docs/puppet/latest/lang_exported.html), a key
|
|
Our Puppet configuration supports [exported resources](https://puppet.com/docs/puppet/latest/lang_exported.html), a key
|
|
component of complex Puppet deployments. Exported resources allow one
|
|
component of complex Puppet deployments. Exported resources allow one
|
... | @@ -610,13 +613,30 @@ line). This rule doesn't take effect on the host applying the |
... | @@ -610,13 +613,30 @@ line). This rule doesn't take effect on the host applying the |
|
`roles::puppetmaster` class, but only on the LDAP server, through this
|
|
`roles::puppetmaster` class, but only on the LDAP server, through this
|
|
rather exotic syntax:
|
|
rather exotic syntax:
|
|
|
|
|
|
Ferm::Rule::Simple <<| tag == 'roles::puppetmaster' |>>
|
|
Ferm::Rule::Simple <<| tag == 'roles::puppetmaster' |>>
|
|
|
|
|
|
This tells the LDAP server to apply whatever rule was exported with
|
|
This tells the LDAP server to apply whatever rule was exported with
|
|
the `@@` syntax and the specified `tag`. Any Puppet resource can be
|
|
the `@@` syntax and the specified `tag`. Any Puppet resource can be
|
|
exported and realized that way.
|
|
exported and realized that way.
|
|
|
|
|
|
## Getting facts from other hosts
|
|
Note that there are security implications with collecting exported
|
|
|
|
resources: it delegates the resource specification of a node to
|
|
|
|
another. So, in the above scenario, the Puppet master could decide to
|
|
|
|
open *other* ports on the LDAP server (say, the SSH port), because it
|
|
|
|
exports the port number and the LDAP server just blindly applies the
|
|
|
|
directive. A more secure specification would explicitly specify the
|
|
|
|
sensitive information, like so:
|
|
|
|
|
|
|
|
Ferm::Rule::Simple <<| tag == 'roles::puppetmaster' |>> {
|
|
|
|
port => ['ldap'],
|
|
|
|
}
|
|
|
|
|
|
|
|
But then a compromised server could send a different `saddr` and
|
|
|
|
there's nothing the LDAP server could do here: it cannot override the
|
|
|
|
address because it's exactly the information we need from the other
|
|
|
|
server...
|
|
|
|
|
|
|
|
### PuppetDB lookups
|
|
|
|
|
|
A common pattern in Puppet is to extract information from host A and
|
|
A common pattern in Puppet is to extract information from host A and
|
|
use it on host B. The above "exported resources" pattern can do this
|
|
use it on host B. The above "exported resources" pattern can do this
|
... | @@ -644,10 +664,25 @@ like this: |
... | @@ -644,10 +664,25 @@ like this: |
|
deny all;
|
|
deny all;
|
|
<% } -%>
|
|
<% } -%>
|
|
|
|
|
|
This would be technically possible with a `concat` resource, but much
|
|
Note that there is a potential security issue with that approach. The
|
|
harder because you would need some special case when no resource is
|
|
same way that exported resources trust the exporter, we trust that the
|
|
exported (to avoid adding the `deny`) and take into account that other
|
|
node exported the right fact. So it's in theory possible that a
|
|
configuratinos might also be needed in the file.
|
|
compromised Puppet node exports an evil IP address in the above
|
|
|
|
example, granting access to an attacker instead of the proper node.
|
|
|
|
|
|
|
|
Also note that this will eventually fail when the node goes down:
|
|
|
|
after a while, resources are expired from the PuppetDB server and the
|
|
|
|
above query will return an empty list. This seems reasonable: we do
|
|
|
|
want to eventually revoke access to nodes that go away, but it's still
|
|
|
|
something to keep in mind.
|
|
|
|
|
|
|
|
Note that this could also be implemented with a `concat` exported
|
|
|
|
resource, but much harder because you would need some special case
|
|
|
|
when no resource is exported (to avoid adding the `deny`) and take
|
|
|
|
into account that other configuratinos might also be needed in the
|
|
|
|
file. It would have the same security and expiry issues anyways.
|
|
|
|
|
|
|
|
### Puppet query language
|
|
|
|
|
|
Note that there's also a way to do those queries without a Forge
|
|
Note that there's also a way to do those queries without a Forge
|
|
module, through the [Puppet query language](https://puppet.com/docs/puppetdb/5.2/api/query/tutorial-pql.html) and the
|
|
module, through the [Puppet query language](https://puppet.com/docs/puppetdb/5.2/api/query/tutorial-pql.html) and the
|
... | | ... | |