Hi there, I have a problem I don''t know how to solve. Let''s say you have two services, applications, whatever that communicate with each other, and they establish a shared password or key to authenticate to the other part. This happens with DHCP/DNS (I think is called dynamic zone update, the DHCP server updates the DNS zone with information from the dynamically configured hosts; in this case you generate a shared key using dnssec-keygen) or Bacula (a modular backup solution, uses shared passwords so the modules (director, file server, storage server) may communicate with each other; in this case I think you may use any string as a password). The problem is that I potentially may have a lot of machines with this kind of configuration, and I would like not to use the same password / key in every machine for security reasons. It''s evident I neither wouldn''t like to specify this in puppet manifests by hand. The ideal solution would be that puppet would be able to generate some random password / key (I think I can achieve this using a custom function) that I would then assign to a variable and write that to the configuration files using templates. The problem is that this would generate a different file every time the manifest is evaluated, so the files involved would change every time the puppet daemon runs.... so I''m stuck, any ideas? am I missing anything obvious? Best regards Jose _______________________________________________ Puppet-users mailing list Puppet-users@madstop.com https://mail.madstop.com/mailman/listinfo/puppet-users
On Feb 7, 2007, at 10:30 AM, José González Gómez wrote:> Hi there, > > I have a problem I don''t know how to solve. Let''s say you have two > services, applications, whatever that communicate with each other, > and they establish a shared password or key to authenticate to the > other part. This happens with DHCP/DNS (I think is called dynamic > zone update, the DHCP server updates the DNS zone with information > from the dynamically configured hosts; in this case you generate a > shared key using dnssec-keygen) or Bacula (a modular backup > solution, uses shared passwords so the modules (director, file > server, storage server) may communicate with each other; in this > case I think you may use any string as a password). > > The problem is that I potentially may have a lot of machines with > this kind of configuration, and I would like not to use the same > password / key in every machine for security reasons. It''s evident > I neither wouldn''t like to specify this in puppet manifests by > hand. The ideal solution would be that puppet would be able to > generate some random password / key (I think I can achieve this > using a custom function) that I would then assign to a variable and > write that to the configuration files using templates. The problem > is that this would generate a different file every time the > manifest is evaluated, so the files involved would change every > time the puppet daemon runs.... so I''m stuck, any ideas? am I > missing anything obvious?You could write a custom function to generate these keypairs on the server: https://reductivelabs.com/trac/puppet/wiki/WritingYourOwnFunctions I''m somewhat hesitant about recommending this, because it seems like it''s going to encourage a proliferation of custom functions that others won''t have access to, but it''s definitely the best way to get this at this point. -- As a general rule, don''t solve puzzles that open portals to Hell. --------------------------------------------------------------------- Luke Kanies | http://reductivelabs.com | http://madstop.com
> You could write a custom function to generate these keypairs on the > server: > > https://reductivelabs.com/trac/puppet/wiki/WritingYourOwnFunctions > > I''m somewhat hesitant about recommending this, because it seems like > it''s going to encourage a proliferation of custom functions that > others won''t have access to, but it''s definitely the best way to get > this at this point.Revisiting the high level interface to package installation; are custom functions currently the only way to pull a list of package names and URL''s from a LDAP or SQL server in order to insert those objects into the configuration manifest? You mentioned I should look at the rails integration a while back, and I''m just now catching up on my mailing list traffic, so I''m hoping there''s some chatter about that here. Does the rails integration intersect this problem, or is it something completely different? Cheers, Jeff McCune
On Feb 7, 2007, at 12:26 PM, Jeff McCune wrote:> > Revisiting the high level interface to package installation; are > custom functions currently the only way to pull a list of package > names and URL''s from a LDAP or SQL server in order to insert those > objects into the configuration manifest? > > You mentioned I should look at the rails integration a while back, and > I''m just now catching up on my mailing list traffic, so I''m hoping > there''s some chatter about that here. Does the rails integration > intersect this problem, or is it something completely different?I''m disappointed; here I was hoping you had great answers to the problems in this thread, and I find you only have more questions. :) There are basically two ways you can inject data into a Puppet configuration during compilation: Custom functions, or collection from the Rails database. Functions are a little bit too powerful, IMO, because they have full access to the scope tree. The insane, unsupportable things you could do from there are pretty open-ended. I''m going to have faith to start with, but this might need to be locked down some if people get too insane. I think it would be pretty straightforward to write a function that called a command and turned the results into a list, which I think is a sane and reasonable function; e.g., package { lister("/bin/packages_to_install $hostname"): ensure => install } Much more than that and I get a bit skittish. As I mentioned, your other option is collection from the database. This is meant to be a closed system -- hosts would only collect information that another host exported. However, SQL is SQL, and you can write whatever you want to the database and then set up a collection to retrieve it as appropriate. There''s nothing I could ever do to stop this, and it''s probably something I''ll do my best to support because I think it''s a decent way to interact with Puppet configurations. -- Yesterday upon the stair I met a man who wasn''t there. He wasn''t there again today -- I think he''s from the CIA. --------------------------------------------------------------------- Luke Kanies | http://reductivelabs.com | http://madstop.com
On 2/7/07, Luke Kanies <luke@madstop.com> wrote:> On Feb 7, 2007, at 12:26 PM, Jeff McCune wrote: > > > > Revisiting the high level interface to package installation; are > > custom functions currently the only way to pull a list of package > > names and URL''s from a LDAP or SQL server in order to insert those > > objects into the configuration manifest? > > > > You mentioned I should look at the rails integration a while back, and > > I''m just now catching up on my mailing list traffic, so I''m hoping > > there''s some chatter about that here. Does the rails integration > > intersect this problem, or is it something completely different? > > I''m disappointed; here I was hoping you had great answers to the > problems in this thread, and I find you only have more questions. :) > > There are basically two ways you can inject data into a Puppet > configuration during compilation: Custom functions, or collection > from the Rails database. > > Functions are a little bit too powerful, IMO, because they have full > access to the scope tree. The insane, unsupportable things you could > do from there are pretty open-ended. I''m going to have faith to > start with, but this might need to be locked down some if people get > too insane. I think it would be pretty straightforward to write a > function that called a command and turned the results into a list, > which I think is a sane and reasonable function; e.g., > > package { lister("/bin/packages_to_install $hostname"): ensure => > install } >So, I wrote a trivial function that returns every line of a file as an element of an Array. It works great and is remarkably simple. If I add a package name to the file, the clients get the package resource through the manifest. Now, I''d like to start adding some more complex bits of how I deploy packages, namely alias => foobar and require => [ foo, bar], so I''ll have three functions in total; get_package_names, get_alias_given_name and get_dependencies_given_name. The function object should initialize and cache all of these bits once, when the package listing is initially retrieved so the subsequent functions don''t have to hammer the external data store. So, this brings me to another question: Is the block created by calling newfunction(name, options = {}, &block) initialized once, or is the object initialized each time it''s called? I''m trying to relate this to how I conceptualize class variables as opposed to instance variables in ruby. I guess this can best be explained by asking how to write a function that returns an integer, incremented each time the function is called? Does what I''m asking make sense? Cheers, -Jeff
On Feb 7, 2007, at 3:15 PM, Jeff McCune wrote:> So, I wrote a trivial function that returns every line of a file as an > element of an Array. It works great and is remarkably simple. If I > add a package name to the file, the clients get the package resource > through the manifest. > > Now, I''d like to start adding some more complex bits of how I deploy > packages, namely alias => foobar and require => [ foo, bar], so I''ll > have three functions in total; get_package_names, get_alias_given_name > and get_dependencies_given_name. > > The function object should initialize and cache all of these bits > once, when the package listing is initially retrieved so the > subsequent functions don''t have to hammer the external data store. > > So, this brings me to another question: Is the block created by > calling newfunction(name, options = {}, &block) initialized once, or > is the object initialized each time it''s called? I''m trying to relate > this to how I conceptualize class variables as opposed to instance > variables in ruby.When you define a function, Puppet just turns the block into an instance method on the Scope class named ''function_<name>''. However, if you use instance variables, note that Puppet uses a scope tree with many scope instances.> I guess this can best be explained by asking how to write a function > that returns an integer, incremented each time the function is called? > Does what I''m asking make sense?Yeah, it makes sense. If all of the packages are defined in the same scope, then just use a normal instance variable. If they''re defined in different scope, you''ll probably have to use a class variable. Is that sufficient? -- A cult is a religion with no political power. -- Tom Wolfe --------------------------------------------------------------------- Luke Kanies | http://reductivelabs.com | http://madstop.com
2007/2/7, Luke Kanies <luke@madstop.com>:> > On Feb 7, 2007, at 10:30 AM, José González Gómez wrote: > > > Hi there, > > > > I have a problem I don''t know how to solve. Let''s say you have two > > services, applications, whatever that communicate with each other, > > and they establish a shared password or key to authenticate to the > > other part. This happens with DHCP/DNS (I think is called dynamic > > zone update, the DHCP server updates the DNS zone with information > > from the dynamically configured hosts; in this case you generate a > > shared key using dnssec-keygen) or Bacula (a modular backup > > solution, uses shared passwords so the modules (director, file > > server, storage server) may communicate with each other; in this > > case I think you may use any string as a password). > > > > The problem is that I potentially may have a lot of machines with > > this kind of configuration, and I would like not to use the same > > password / key in every machine for security reasons. It''s evident > > I neither wouldn''t like to specify this in puppet manifests by > > hand. The ideal solution would be that puppet would be able to > > generate some random password / key (I think I can achieve this > > using a custom function) that I would then assign to a variable and > > write that to the configuration files using templates. The problem > > is that this would generate a different file every time the > > manifest is evaluated, so the files involved would change every > > time the puppet daemon runs.... so I''m stuck, any ideas? am I > > missing anything obvious? > > You could write a custom function to generate these keypairs on the > server: > > https://reductivelabs.com/trac/puppet/wiki/WritingYourOwnFunctions > > I''m somewhat hesitant about recommending this, because it seems like > it''s going to encourage a proliferation of custom functions that > others won''t have access to, but it''s definitely the best way to get > this at this point. > >The problem here is that if I generate a random key every time the function is called I guess the template would generate a different file every time, so the file on the client would be changed every time the puppet client runs. So if this is the proposed solution I guess I should have some kind of key database, so if a key is requested for an already existing host I should return the existing key. I''m curious... how is people solving this? do you specify those keys by hand? haven''t you faced this problem? do you use the same key everywhere? Best regards Jose _______________________________________________ Puppet-users mailing list Puppet-users@madstop.com https://mail.madstop.com/mailman/listinfo/puppet-users
On Thu, Feb 08, 2007 at 12:10:15PM +0100, José González Gómez wrote:> 2007/2/7, Luke Kanies <luke@madstop.com>: > >You could write a custom function to generate these keypairs on the > >server: > > [snip] > > > The problem here is that if I generate a random key every time the function > is called I guess the template would generate a different file every time, > so the file on the client would be changed every time the puppet client > runs. So if this is the proposed solution I guess I should have some kind of > key database, so if a key is requested for an already existing host I should > return the existing key. I''m curious... how is people solving this? do you > specify those keys by hand? haven''t you faced this problem? do you use the > same key everywhere?I''d be tempted that you could create the "key" by using a HMAC function over the service name, hostname, ip address or other invariant information keyed with a secret known only to the puppet master. So, if we had our hypothetical function "hmac_sha1", we''d have in site.pp: $secretkey = "somethingreallysecret" Then for your service: file { ''/some/random/file'': ensure => present, content => hmac_sha1($hostname, $secretkey); } Or you could do something similar simply by concatenating the hostname and secret key, in this case, if you don''t need to be able to demonstrate that it''s cryptographically secure. -- Ceri Storey <cez@necrofish.org.uk> ''What I really want is "apt-get smite"'' --Rob Partington http://unix.culti.st/
On Feb 8, 2007, at 5:10 AM, José González Gómez wrote:> The problem here is that if I generate a random key every time the > function is called I guess the template would generate a different > file every time, so the file on the client would be changed every > time the puppet client runs. So if this is the proposed solution I > guess I should have some kind of key database, so if a key is > requested for an already existing host I should return the existing > key. I''m curious... how is people solving this? do you specify > those keys by hand? haven''t you faced this problem? do you use the > same key everywhere?I expect, like so many other sysadmin problems, people are hacking to get by and choosing non-optimal solutions. You''re right that a key database of some kind (even something as simple as flat files) is the solution. -- The trouble with the rat race is that even if you win, you''re still a rat. -- Lily Tomlin --------------------------------------------------------------------- Luke Kanies | http://reductivelabs.com | http://madstop.com
On Thu, Feb 08, 2007 at 12:10:15PM +0100, José González Gómez wrote:> The problem here is that if I generate a random key every time the function > is called I guess the template would generate a different file every time, > so the file on the client would be changed every time the puppet client > runs. So if this is the proposed solution I guess I should have some kind of > key database, so if a key is requested for an already existing host I should > return the existing key. I''m curious... how is people solving this? do you > specify those keys by hand? haven''t you faced this problem? do you use the > same key everywhere?newfunction(:blah, :type => :rvalue) do |args| valuefile = "/etc/puppet/blahstuff/#{args[0]}" unless File.exists?(valuefile) File.open(valuefile, ''w'') { |fd| fd.write(generate_blah()) } end File.read(valuefile) end Write a generate_blah method and you''re set. Perhaps with a slightly more tasteful function name, though... - Matt