使用Puppet管理Linux用户密码

38

我需要使用puppet创建一个带有密码的测试用户。

我已经阅读过,Puppet无法以通用跨平台的方式管理用户密码,这真是遗憾。 我正在为Red Hat Enterprise Linux Server release 6.3做这件事。

我按照以下步骤操作:

user { 'test_user': 
  ensure   => present,
  password => sha1('hello'),
}

puppet更新了用户的密码,但当我尝试登录时,Linux显示登录/密码不正确。

如果我在Linux中使用sudo passwd test_user手动设置密码,然后查看/etc/shadow并在puppet中硬编码该值,则它可以正常工作(我可以登录)。类似这样做:

user { 'test_user': 
  ensure   => present,
  password => '$1$zi13KdCr$zJvdWm5h552P8b34AjxO11',
}

我也尝试通过在sha1('hello')前面添加$1$,但它也不起作用(注意,$1$代表sha1)。

如何修改第一个示例以使其工作(使用puppet文件中的明文密码)?

附言:我知道我应该使用LDAP、sshkeys或其他东西,而不是在puppet文件中硬编码用户密码。然而,我只是为了运行puppet vagrant测试而这样做,所以在puppet文件中硬编码用户密码是可以的。


我遇到了与你类似的问题(在CentOS 6上),最终还是硬编码了从openssl passwd生成的哈希值 - 我猜测sha1是错误的算法,但Puppet似乎没有提供任何其他哈希算法。 - xiankai
2
@xiankai 是的,我看到 passwd 使用 DES 进行密码加密(请参阅 man crypt)。 - Slava Semushin
8个回答

38

Linux用户的密码以hash方式存储在/etc/shadow文件中。Puppet会将用户类型定义中提供的密码传递到/etc/shadow文件中。

使用openssl命令生成您的hash密码:

 #openssl passwd -1  
 #Enter your password here 
 Password: 
 Verifying - Password: 
 $1$HTQUGYUGYUGwsxQxCp3F/nGc4DCYM

上一个示例生成了以下哈希值:$1$HTQUGYUGYUGwsxQxCp3F/nGc4DCYM/

将此哈希密码添加到您的类中,如所示(不要忘记引号)。

user { 'test_user': 
  ensure   => present,
  password => '$1$HTQUGYUGYUGwsxQxCp3F/nGc4DCYM/',
}

根据openssl passwd --help文档,使用-1会使用MD5作为哈希算法。它似乎没有任何基于SHA的哈希选项,因此我认为这不是一个好方法。 - agxs
1
此外,更新版本确实包括SHA-512哈希,但您需要传递-6而不是-1。 - agxs

17

puppetlabs 的 stdlib 包实现了一个类似于所接受答案的 pw_hash 函数。

确保将该库添加到您的配置中。如果您使用 librarian,只需在您的 Puppetfile 中添加即可。

mod 'puppetlabs-stdlib'

然后要创建用户,只需要:

user { 'user':
  ensure => present,
  password => pw_hash('password', 'SHA-512', 'mysalt'),
}

2
迄今为止最好的方法,因为它不依赖于操作系统。所有其他显示的方法都需要特定的操作系统或软件包才能工作,而ps_hash似乎可以在所有*nix操作系统上工作。此外,它默认支持盐,而其他显示的方法则不支持。@mperrin您的示例中有一个错别字:“myhash”应该是“mysalt”。 - omni
3
我该如何避免存储明文密码并同时使用 pw_hash - Felipe Alvarez
1
我所有敏感信息,如明文密码或证书,都存储在使用gpg加密的hiera文件中。我使用由stackoverflow员工开发的工具Blackbox来帮助我进行日常任务,如加密/解密/部署和与可信合作者共享。 - mperrin
GPG的替代方案是eyaml,它在当前Puppet版本中似乎得到了很好的支持:https://github.com/voxpupuli/hiera-eyaml - pioto

12

在 Puppet 中,sha1 函数并不是用于 passwd 条目的,正如你所发现的。 我认为设置哈希而不是密码是一个好习惯!你本来就不应该能够恢复密码 - 你可以生成它一次,或者你可以让 Puppet 每次生成它 - 我的看法是生成那个哈希值一次就足够了... 在 Debian/Ubuntu 上可以像这样生成密码:

pwgen -s -1 | mkpasswd -m sha-512 -s

在 CentOS 上,你可以使用一些 grub-crypt 命令代替 mkpasswd...


2
如果尽管使用正确的哈希算法,您仍无法使密码验证正常工作,那么您的Puppet安装可能无法修改您的/etc/shadow,因为缺少libshadow库。我在这里更详细地介绍了这个陷阱。 - Michael Trojanek

10
我使用Puppet解析器函数中的Ruby字符串#crypt方法成功了,具体方法见:I had success (gist)
根据我的分析,它使用了crypt libc函数(请参阅:info crypt),并且采用相同的参数$n$[rounds=<m>$]salt,其中n是哈希函数(对于SHA-512为$6$),m是密钥强化轮数(默认为5000)。

1
$pass='password' $salt='salt' user{ "alise": ensure => present, password => inline_template("<%= '$pass'.crypt('$6$$salt') %>"), } - AhHatem

3
你可以使用 generate 函数让 Puppet 为您创建哈希表:
$password = 'hello'

user { 'test_user':
    ensure   => 'present',
    password => generate('/bin/sh', '-c', "mkpasswd -m sha-512 ${password} | tr -d '\n'"),
}

然而,这个解决方案需要mkpasswd依赖。 - desertkun

2

Puppet:带有SHA 512哈希密码的用户

如果您有Python 2.6,则可以使用我提出的方法而无需添加任何内容。我在CentOS 6.4上测试了此方法,使用了puppet 3.6.2

$pass="password"
$shatag="\$6\$"
$cmd="import crypt, base64, os, sys; sys.stdout.write(crypt.crypt('$pass', '$shatag' + base64.b64encode(os.urandom(16))[:8]))"
user { 'boop':
  ensure   => present,
  password => generate ("/usr/bin/python", "-c", $cmd),
}

说明

  1. sha标签用于指定我们想要的哈希方法,供crypt使用: 6是SHA-512哈希的类型

    • $1$ -> MD5
    • $2a$ -> Blowfish(不在主流glibc中,在某些Linux发行版中添加)
    • $5$ -> SHA-256(自glibc 2.7以来)
    • $6$ -> SHA-512(自glibc 2.7以来)

感谢 daveywiki_crypt

  1. sys.stdout.write在这里是为了避免print'\n'

  2. base64.b64encode(os.urandom(16))[:8])

    • os.urandom(16) 创建一个长度为16位的二进制字符串
    • base64.b64encode 将该字符串编码成base64格式
    • [:8] 取该字符串的前8个字符(因为base64编码的长度可能会变化)
  3. generate是一个在puppet master上创建文本的puppet函数。 你不能像你想要的那样使用这个函数,因为它被“保护”ê.é最后一篇帖子建议对此进行解决)

希望能帮到你


1
在我的Vagrantfile文件中,我做了这个:
$newuserid = ENV["USERNAME"]

config.vm.provision :puppet do |puppet|
    puppet.module_path    = "modules"
    puppet.manifests_path = "manifests"
    puppet.manifest_file  = "main.pp"
    puppet.facter         = {"newuserid" => $newuserid}
    puppet.options        = "--verbose"    
end

在我的 main.pp 文件中:
user { $newuserid :
  ensure  => present,
  home    => "/home/${newuserid}",
  managehome => true,
  gid => "mygid",
}

exec { 'set password':
  command => "/bin/echo \"${newuserid}:${newuserid}\" | /usr/sbin/chpasswd",
  require => User [ $newuserid ],
}

0
只需使用 grub-crypt --sha-512 生成加密密码并粘贴即可。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接