Nan,
 You're going down the same line of thought I had as an alternative to 
embedding it in the Cert itself. The reason to embed it in the cert is that you 
avoid having all of the "if its not here, go check there" code. You don't need 
to maintain a database with this data either. In our case we have many puppet 
masters behind a load balancer, so we 'd have to leverage a database to hold 
the data, or risk having each of our puppet servers have different data on them 
about our nodes. 

 If it turns out that the cert-side of the fix will take too long to implement 
(bug #7243), then we may go down that path anyways.. but I like the idea of the 
data being locked into the CSR and subsequently the Cert itself, as its 
exceedingly hard to change after that. This also opens up the door for people 
to add custom authentication data into their certs for their environments... 
maybe checks against some custom Unique identifier of hardware, or something 
else along those lines to validate that the server is truly allowed to connect 
in to puppet.

 FWIW, its because we leverage puppet over the internet to manage cloud systems 
that we really care about this. Had we just been managing internal networked 
systems, this may not be such a big deal. The benefits here though are pretty 
obvious I think...

 PS, I've also submitted bug 7244 — requesting that the 'autosign' code be 
extended to allow for external 'autosign classifiers'. This would allow 
autosigning to work and for the puppet implementors to determine what mechanism 
they want to use to allow or disallow an autosigned SSL cert. In our case we've 
written our own mechanism around this, but we'd love to move it into something 
more "supported".

—Matt

On Apr 26, 2011, at 9:25 AM, Nan Liu wrote:

> Why embed this in the cert, rather than custom facts? Your second
> requirement is interesting, on one hand the client can set the class
> info as part of the certificate, on the other hand you doesn't want
> the client to change it afterwards.
> 
> I would suggest client submit the list of classes as a custom fact,
> and serverside override so once the setting is obtained the client can
> not override the value. So if the server doesn't have the class info
> matching the CN, store the initial class info from client facts into a
> server location (db, file) that can be retrieved later via enc,
> extlookup.
> 
> So something along the line of
> 
> # server_class is obtained either from ENC or extlookup which is based
> on client certificate name.
> if $server_class {
> $base_class = $server_class
> } else {
> # client_class is a custom function, and can be as simply as
> FACTER_client_class environment variable.
> $base_class = $client_class
> # write a custom function to store the client_class to either the
> extlookup or ENC location.
> store($client_class, $certname)
> }
> 
> If you need to allow the client to client set it later on, you can
> either manually update the server side settings or just write a
> wrapper for puppet cert --clean that will remove the ENC or extlookup
> data for this client.
> 
> Thanks,
> 
> Nan
> 
> On Tue, Apr 26, 2011 at 9:00 AM, Matt Wise <w...@wiredgeek.net> wrote:
>> 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 <w...@wiredgeek.net> 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 puppet-users@googlegroups.com.
>>>> To unsubscribe from this group, send email to 
>>>> puppet-users+unsubscr...@googlegroups.com.
>>>> 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 puppet-users@googlegroups.com.
>> To unsubscribe from this group, send email to 
>> puppet-users+unsubscr...@googlegroups.com.
>> 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 puppet-users@googlegroups.com.
> To unsubscribe from this group, send email to 
> puppet-users+unsubscr...@googlegroups.com.
> 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 puppet-users@googlegroups.com.
To unsubscribe from this group, send email to 
puppet-users+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/puppet-users?hl=en.

Reply via email to