Ok, spoke with Jeff a bit on IRC about this. Part of this problem is easy it 
turns out. You can add '+ExportCertData' to the SSLOptions in Apache which will 
pass the CERT in PEM format to Puppet for each client when they connect. You 
can then do a custom node classifier that reads this data and does something 
intelligent. Again, easy. 

The hard part it turns out is getting some custom data into the SSL cert to 
begin with. The CSR thats generated does not get generated with 'certdnsnames' 
embedded in it, thats done purely on the Signing side (aka, your puppet ca). I 
had hoped I could set 'certdnsnames' on the client and that would be passed to 
the server in some way, but its not. 

I'm pretty sure at this point that some puppet code will need to change for 
this to work. I'll be submitting a puppet feature request for this in a few 
minutes.. 

—Matt


On Apr 26, 2011, at 6:50 AM, Matt Wise wrote:

> :) This is most definitely a hack. The issue is that once you start using 
> Puppet to push out secure-data that HostA might need, but HostB should never 
> be able to get — you run into this problem. If HostB is broken into and its 
> 'node type' is changed (whether by hostname, or editing a custom puppet 
> fact), it can suddenly get data for HostA. 
> 
> I am actually thinking that the 'Subject Alternative Name' may be the best 
> place for this kind of data — but I'm wondering whether theres any place in 
> Puppet where I an implement a hack that allows puppet to parse through these 
> fields and determine if they're valid. IE, perhaps in auth.conf? Or maybe 
> theres a way to use a 'prerun' command in puppet.conf that I can feed the 
> clients certificate to? Any thoughts there?
> 
> —Matt
> 
> On Apr 26, 2011, at 2:54 AM, Jeff McCune wrote:
> 
>> On Tue, Apr 26, 2011 at 4:10 AM, Matt Wise <[email protected]> wrote:
>>> I'm working out some security issues here and wanted to throw something out 
>>> there... I'll be digging in tonight to see whether something like this is 
>>> possible, so I'd appreciate feedback quickly if anyone happens to know if 
>>> this is possible. Imagine a scenario where our individual hosts actually 
>>> tell the puppet server which 'config' they want. This is our environment, 
>>> and its not changeable. (The short explanation — its done this way because 
>>> we provision nodes in several clouds where hostnames are not known until 
>>> after a host has booted). For now, our nodes actually check in and say "I 
>>> want XYZ class".
>>> 
>>> I'd like to have our nodes able to do this ONCE ... only when they generate 
>>> their CSR. After that, I'd like their 'base_class' to be embedded in the 
>>> CSR (And subsequently the CERT), so that a client cannot later change its 
>>> mind about what kind of host it is. Essentially I'm thinking the process 
>>> would be something like this:
>>> 
>>> Client:
>>> -) fill in 'base_class' somewhere (puppet.conf?)
>>> -) run puppet... host generates private key, and csr, and submits it to the 
>>> puppet ca master
>>> 
>>> Server:
>>> -) process signs CSR and provides Cert back to host (this is automated in 
>>> our case, but not with autosign.conf)
>>> 
>>> Client:
>>> -) begin actual puppet run.. request real configuration
>>> 
>>> Server:
>>> -) read 'base_class' from certificate, and fill in $base_class with that 
>>> data ..
>>> 
>>> 
>>> Thoughts? Any ideas on a good way to work this out?
>> 
>> 
>> This feels like quite a hack, but I agree with you there's no really
>> good way for Puppet to do this today.  The agent can set the
>> environment (puppet environment) it wants, but that doesn't really
>> give you what you want.
>> 
>> I would normally accomplish this using a custom fact, but you
>> mentioned this is security related so I see the desire to get the base
>> class embedded into the certificate data.  Practically speaking, the
>> certificate cannot be forged once signed.
>> 
>> You can easily change the certificate name in the request using:
>> 
>> puppet agent --certname=my_base_class
>> 
>> But! You're going to run into duplicate certificate names, which will
>> be a pain to manage.  Better instead, you could prefix each
>> certificate name with the FQDN, or some other unique identifier and a
>> character not valid for DNS hostnames:
>> 
>> puppet agent --certname="$(facter fqdn)::my_base_class"
>> 
>> You can then match against this in your puppet manifests or your
>> External Node Classifier by splitting out the string to the right of
>> the double colons.
>> 
>> Hope this helps,
>> -- 
>> Jeff McCune
>> Professional Services, Puppet Labs
>> @0xEFF
>> 
>> -- 
>> You received this message because you are subscribed to the Google Groups 
>> "Puppet Users" group.
>> To post to this group, send email to [email protected].
>> To unsubscribe from this group, send email to 
>> [email protected].
>> For more options, visit this group at 
>> http://groups.google.com/group/puppet-users?hl=en.
>> 
> 

-- 
You received this message because you are subscribed to the Google Groups 
"Puppet Users" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/puppet-users?hl=en.

Reply via email to