Felipe Ortega
2012-Aug-01 12:28 UTC
[Puppet Users] rand losing its randomness after using fqdn_rand
Hi, I''m a newbie puppet user, and I''m facing some weird behaviour in my testing environment. I''m using Debian packages from testing/Wheezy (version 2.7.18) via apache+passenger installation. Also: $ ruby -v ruby 1.8.7 (2012-02-08 patchlevel 358) [x86_64-linux] I developed the following custom function (with some help from Google) to generate the shadow password of any new user: module Puppet::Parser::Functions newfunction(:shadow_pwd, :type => :rvalue) do |args| passwd = args[0] case args[1] when ''md5'' algo = ''$1$'' when ''blowfish'' algo = ''$2$'' when ''sha256'' algo = ''$5$'' when ''sha512'' algo = ''$6$'' end o = [(''a''..''z''),(''A''..''Z''),(''0''..''9'')].map{|i| i.to_a}.flatten salt = (0..8).map{ o[rand(o.length)] }.join hash = passwd.crypt(algo + salt) end end it takes two arguments, the cleartext password and the algorithm to encrypt it. So, with this setup, on every run of the puppet agent, a new shadow password was assigned to the user. Well, in fact it was always the same cleartext password, but as the salt was different on every run, the shadow password of the user was different too, and puppet updated the user password accordingly. Here comes a new class, puppet, to manage the agent configuration on every node. I chose to run puppet agent via cron task, and in order to prevent every agent try to get the catalog at the same time, I use the following code snippet (picket up online): $first = fqdn_rand(30) $second = $first + 30 cron {''puppet'': command => ''/usr/bin/puppet agent --no-daemon --onetime'', user => ''root'', minute => [$first,$second], ensure => present, require => Class[''puppet::install''], } This works OK too, it creates a new task in the crontab file of user root, executing the command twice an hour, always on the same two minutes. But then I realized the shadow password of the users were not being updated anymore (only when I change the cleartext password). After some debugging, I found out that the salt was always the same! Further debugging led me to the definition of the fqdn_rand function, and the culprit seems to be this line: srand(Digest::MD5.hexdigest([lookupvar(''::fqdn''),args].join('':'')).hex) which sets the seed used for the rand function. After all this stuff, what should I do? Is it a bug in fqdn_rand? Because after using it, rand loses its randomness. Or, is it my fault for not setting the seed in my custom function? If so, how and where should a set the seed so it works as before using fqdn_rand? Thanks in advance for your answers. Greetings. -- You received this message because you are subscribed to the Google Groups "Puppet Users" group. To view this discussion on the web visit https://groups.google.com/d/msg/puppet-users/-/FjokplF1IuoJ. To post to this group, send email to puppet-users@googlegroups.com. To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
R.I.Pienaar
2012-Aug-01 17:13 UTC
Re: [Puppet Users] rand losing its randomness after using fqdn_rand
----- Original Message -----> From: "Felipe Ortega" <ortegaga@gmail.com> > To: puppet-users@googlegroups.com > Sent: Wednesday, August 1, 2012 5:28:23 AM > Subject: [Puppet Users] rand losing its randomness after using fqdn_rand > > > Hi, > > > I''m a newbie puppet user, and I''m facing some weird behaviour in my > testing environment. > I''m using Debian packages from testing/Wheezy (version 2.7.18) via > apache+passenger installation. Also: > > > $ ruby -v > ruby 1.8.7 (2012-02-08 patchlevel 358) [x86_64-linux] > > > I developed the following custom function (with some help from > Google) to generate the shadow password of any new user: > > > module Puppet::Parser::Functions > newfunction(:shadow_pwd, :type => :rvalue) do |args| > passwd = args[0] > case args[1] > when ''md5'' > algo = ''$1$'' > when ''blowfish'' > algo = ''$2$'' > when ''sha256'' > algo = ''$5$'' > when ''sha512'' > algo = ''$6$'' > end > o = [(''a''..''z''),(''A''..''Z''),(''0''..''9'')].map{|i| i.to_a}.flatten > salt = (0..8).map{ o[rand(o.length)] }.join > hash = passwd.crypt(algo + salt) > end > end > > > it takes two arguments, the cleartext password and the algorithm to > encrypt it. > > > So, with this setup, on every run of the puppet agent, a new shadow > password was assigned to the user. Well, in fact it was always the > same cleartext password, but as the salt was different on every run, > the shadow password of the user was different too, and puppet > updated the user password accordingly. > > > Here comes a new class, puppet, to manage the agent configuration on > every node. I chose to run puppet agent via cron task, and in order > to prevent every agent try to get the catalog at the same time, I > use the following code snippet (picket up online): > > > $first = fqdn_rand(30) > $second = $first + 30 > cron {''puppet'': > command => ''/usr/bin/puppet agent --no-daemon --onetime'', > user => ''root'', > minute => [$first,$second], > ensure => present, > require => Class[''puppet::install''], > } > > > This works OK too, it creates a new task in the crontab file of user > root, executing the command twice an hour, always on the same two > minutes. > > > But then I realized the shadow password of the users were not being > updated anymore (only when I change the cleartext password). After > some debugging, I found out that the salt was always the same! > Further debugging led me to the definition of the fqdn_rand > function, and the culprit seems to be this line: > > > srand(Digest::MD5.hexdigest([lookupvar(''::fqdn''),args].join('':'')).hex) > > > which sets the seed used for the rand function. > > > After all this stuff, what should I do? Is it a bug in fqdn_rand? > Because after using it, rand loses its randomness. Or, is it my > fault for not setting the seed in my custom function? If so, how and > where should a set the seed so it works as before using fqdn_rand?I''d say this is a bug in fqdn_rand, but if you wish to work around it in your function you can also just call srand() when your function get called Would be great if you could file a bug about fqdn_rand -- 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+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
Eric Shamow
2012-Aug-01 17:48 UTC
Re: [Puppet Users] rand losing its randomness after using fqdn_rand
Not sure that this should be considered a bug in fqdn_rand - the idea with fqdn_rand is that it should generate the same random number each time it is run in order to maintain idempotency. The salt will be different on *different* hosts, but it will be the same on the same host. -Eric -- Eric Shamow Professional Services http://puppetlabs.com/ (c)631.871.6441 On Wednesday, August 1, 2012 at 1:13 PM, R.I.Pienaar wrote:> > > ----- Original Message ----- > > From: "Felipe Ortega" <ortegaga@gmail.com (mailto:ortegaga@gmail.com)> > > To: puppet-users@googlegroups.com (mailto:puppet-users@googlegroups.com) > > Sent: Wednesday, August 1, 2012 5:28:23 AM > > Subject: [Puppet Users] rand losing its randomness after using fqdn_rand > > > > > > Hi, > > > > > > I''m a newbie puppet user, and I''m facing some weird behaviour in my > > testing environment. > > I''m using Debian packages from testing/Wheezy (version 2.7.18) via > > apache+passenger installation. Also: > > > > > > $ ruby -v > > ruby 1.8.7 (2012-02-08 patchlevel 358) [x86_64-linux] > > > > > > I developed the following custom function (with some help from > > Google) to generate the shadow password of any new user: > > > > > > module Puppet::Parser::Functions > > newfunction(:shadow_pwd, :type => :rvalue) do |args| > > passwd = args[0] > > case args[1] > > when ''md5'' > > algo = ''$1$'' > > when ''blowfish'' > > algo = ''$2$'' > > when ''sha256'' > > algo = ''$5$'' > > when ''sha512'' > > algo = ''$6$'' > > end > > o = [(''a''..''z''),(''A''..''Z''),(''0''..''9'')].map{|i| i.to_a}.flatten > > salt = (0..8).map{ o[rand(o.length)] }.join > > hash = passwd.crypt(algo + salt) > > end > > end > > > > > > it takes two arguments, the cleartext password and the algorithm to > > encrypt it. > > > > > > So, with this setup, on every run of the puppet agent, a new shadow > > password was assigned to the user. Well, in fact it was always the > > same cleartext password, but as the salt was different on every run, > > the shadow password of the user was different too, and puppet > > updated the user password accordingly. > > > > > > Here comes a new class, puppet, to manage the agent configuration on > > every node. I chose to run puppet agent via cron task, and in order > > to prevent every agent try to get the catalog at the same time, I > > use the following code snippet (picket up online): > > > > > > $first = fqdn_rand(30) > > $second = $first + 30 > > cron {''puppet'': > > command => ''/usr/bin/puppet agent --no-daemon --onetime'', > > user => ''root'', > > minute => [$first,$second], > > ensure => present, > > require => Class[''puppet::install''], > > } > > > > > > This works OK too, it creates a new task in the crontab file of user > > root, executing the command twice an hour, always on the same two > > minutes. > > > > > > But then I realized the shadow password of the users were not being > > updated anymore (only when I change the cleartext password). After > > some debugging, I found out that the salt was always the same! > > Further debugging led me to the definition of the fqdn_rand > > function, and the culprit seems to be this line: > > > > > > srand(Digest::MD5.hexdigest([lookupvar(''::fqdn''),args].join('':'')).hex) > > > > > > which sets the seed used for the rand function. > > > > > > After all this stuff, what should I do? Is it a bug in fqdn_rand? > > Because after using it, rand loses its randomness. Or, is it my > > fault for not setting the seed in my custom function? If so, how and > > where should a set the seed so it works as before using fqdn_rand? > > > > I''d say this is a bug in fqdn_rand, but if you wish to work around it > in your function you can also just call srand() when your function get > called > > Would be great if you could file a bug about fqdn_rand > > -- > 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 (mailto:puppet-users@googlegroups.com). > To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com (mailto:puppet-users+unsubscribe@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+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
R.I.Pienaar
2012-Aug-01 17:58 UTC
Re: [Puppet Users] rand losing its randomness after using fqdn_rand
----- Original Message -----> From: "Eric Shamow" <eric@puppetlabs.com> > To: puppet-users@googlegroups.com > Sent: Wednesday, August 1, 2012 10:48:26 AM > Subject: Re: [Puppet Users] rand losing its randomness after using fqdn_rand > > Not sure that this should be considered a bug in fqdn_rand - the idea > with fqdn_rand is that it should generate the same random number > each time it is run in order to maintain idempotency.The bug is that it does: * set salt to cause consistant random numbers * get random data I think it should do: * set salt to cause consistant random numbers * get random data * reset salt to produce random data This will retain the behaviour of fqdn_rand and not break random for everyone else -- 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+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
Calvin Walton
2012-Aug-01 18:30 UTC
Re: [Puppet Users] rand losing its randomness after using fqdn_rand
On Wed, 2012-08-01 at 18:58 +0100, R.I.Pienaar wrote:> From: "Eric Shamow" <eric@puppetlabs.com> > > Not sure that this should be considered a bug in fqdn_rand - the idea > > with fqdn_rand is that it should generate the same random number > > each time it is run in order to maintain idempotency. > > The bug is that it does: > > * set salt to cause consistant random numbers > * get random data > > I think it should do: > > * set salt to cause consistant random numbers > * get random data > * reset salt to produce random data> This will retain the behaviour of fqdn_rand and not break random for everyone elseI was going to say that an even *better* solution would be to do this: * Create a private Random object for use only by fqdn_rand * Set the seed on the private Random object, without disturbing the Kernel.rand implementation * get random data from the private Random object ...but then I remembered that the Random class was introduced in Ruby 1.9, so this won''t work on older versions like 1.8.7, and I had forgotten that fqdn_rand should always return the same number on the same machine when it is called with the same arguments. The definition of ''srand'' is actually kind of interesting: srand(number=0) => old_seed so the patch to fix this is actually quite trivial: diff --git a/lib/puppet/parser/functions/fqdn_rand.rb b/lib/puppet/parser/functi index 93ab98b..987815c 100644 --- a/lib/puppet/parser/functions/fqdn_rand.rb +++ b/lib/puppet/parser/functions/fqdn_rand.rb @@ -7,6 +7,7 @@ Puppet::Parser::Functions::newfunction(:fqdn_rand, :type => :rva $random_number_seed = fqdn_rand(30,30)") do |args| require ''digest/md5'' max = args.shift - srand(Digest::MD5.hexdigest([lookupvar(''::fqdn''),args].join('':'')).hex) + old_seed = srand(Digest::MD5.hexdigest([lookupvar(''::fqdn''),args].join('':'')).hex) rand(max).to_s + srand(old_seed) end -- Calvin Walton <calvin.walton@kepstin.ca> -- 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+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
David Schmitt
2012-Aug-01 21:11 UTC
Re: [Puppet Users] rand losing its randomness after using fqdn_rand
On 2012-08-01 14:28, Felipe Ortega wrote:> So, with this setup, on every run of the puppet agent, a new shadow > password was assigned to the user. Well, in fact it was always the same > cleartext password, but as the salt was different on every run, the > shadow password of the user was different too, and puppet updated the > user password accordingly.Others have already answered about the puppet bug. I''d like to additionally point out, that it''s Bad Practice to generate multiple hashes from the same cleartext as this will reduce the amount of work needed when attacking the hash. Best Regards, David -- 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+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
Felipe Ortega
2012-Aug-02 09:59 UTC
Re: [Puppet Users] rand losing its randomness after using fqdn_rand
El miércoles, 1 de agosto de 2012 20:30:52 UTC+2, Calvin Walton escribió:> > On Wed, 2012-08-01 at 18:58 +0100, R.I.Pienaar wrote: > > From: "Eric Shamow" <eric@puppetlabs.com> > > > Not sure that this should be considered a bug in fqdn_rand - the idea > > > with fqdn_rand is that it should generate the same random number > > > each time it is run in order to maintain idempotency. > > > > The bug is that it does: > > > > * set salt to cause consistant random numbers > > * get random data > > > > I think it should do: > > > > * set salt to cause consistant random numbers > > * get random data > > * reset salt to produce random data > > > This will retain the behaviour of fqdn_rand and not break random for > everyone else > > I was going to say that an even *better* solution would be to do this: > > * Create a private Random object for use only by fqdn_rand > * Set the seed on the private Random object, without disturbing > the Kernel.rand implementation > * get random data from the private Random object > > ...but then I remembered that the Random class was introduced in Ruby > 1.9, so this won''t work on older versions like 1.8.7, and I had > forgotten that fqdn_rand should always return the same number on the > same machine when it is called with the same arguments. > > The definition of ''srand'' is actually kind of interesting: > srand(number=0) => old_seed > so the patch to fix this is actually quite trivial: > > diff --git a/lib/puppet/parser/functions/fqdn_rand.rb > b/lib/puppet/parser/functi > index 93ab98b..987815c 100644 > --- a/lib/puppet/parser/functions/fqdn_rand.rb > +++ b/lib/puppet/parser/functions/fqdn_rand.rb > @@ -7,6 +7,7 @@ Puppet::Parser::Functions::newfunction(:fqdn_rand, :type > => :rva > $random_number_seed = fqdn_rand(30,30)") do |args| > require ''digest/md5'' > max = args.shift > - > srand(Digest::MD5.hexdigest([lookupvar(''::fqdn''),args].join('':'')).hex) > + old_seed = > srand(Digest::MD5.hexdigest([lookupvar(''::fqdn''),args].join('':'')).hex) > rand(max).to_s > + srand(old_seed) > end > > -- > Calvin Walton <calvin.walton@kepstin.ca> > >Hi again, I''ve tried the patch submitted by Calvin Walton, and it''s almost working. There are two remaining issues: 1.- The patch needs some more lines, because it returns the "new old seed" value. So the new patch would be: diff --git a/puppet/parser/functions/fqdn_rand.rb.orig b/puppet/parser/functions/fqdn_rand.rb index 93ab98b..6482449 100644 --- a/puppet/parser/functions/fqdn_rand.rb.orig +++ b/puppet/parser/functions/fqdn_rand.rb @@ -7,6 +7,8 @@ Puppet::Parser::Functions::newfunction(:fqdn_rand, :type => :rvalue, :doc => $random_number_seed = fqdn_rand(30,30)") do |args| require ''digest/md5'' max = args.shift - srand(Digest::MD5.hexdigest([lookupvar(''::fqdn''),args].join('':'')).hex) - rand(max).to_s + old_seed = srand(Digest::MD5.hexdigest([lookupvar(''::fqdn''),args].join('':'')).hex) + exit_value = rand(max).to_s + srand(old_seed) + exit_value end 2.- I need to restart apache on the master server (remember I was using Passenger) to get a different salt value of the shadow password. Without the patch, I always get the same salt value, no matter if I restart the apache server or not. -- You received this message because you are subscribed to the Google Groups "Puppet Users" group. To view this discussion on the web visit https://groups.google.com/d/msg/puppet-users/-/nAuJ64JrsdAJ. To post to this group, send email to puppet-users@googlegroups.com. To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.