FAQ
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.

Search Discussions

  • R.I.Pienaar at Aug 1, 2012 at 5:13 pm

    ----- 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 at Aug 1, 2012 at 5:48 pm
    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" (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 at Aug 1, 2012 at 5:58 pm

    ----- 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 at Aug 1, 2012 at 6:30 pm

    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>

    --
    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 at Aug 2, 2012 at 9:59 am
    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.
  • David Schmitt at Aug 1, 2012 at 9:11 pm

    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.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
grouppuppet-users @
categoriespuppet
postedAug 1, '12 at 4:15p
activeAug 2, '12 at 9:59a
posts7
users5
websitepuppetlabs.com

People

Translate

site design / logo © 2022 Grokbase