我正在尝试使用 puppet 管理 Unix 用户。Puppet 提供了足够的工具来创建帐户并提供 authorized_keys 文件,但没有设置用户密码,也无法告诉用户。
我编写了一个 Python 脚本,用于生成随机密码并通过电子邮件发送给用户。问题是,无法使用 Python 启动 passwd Unix 命令,因此我编写了一个 Bash 脚本,命令如下:
echo -ne "$password\n$password\n" | passwd $user
passwd -e $user
手动启动后,脚本运行正常,创建的用户的密码通过电子邮件发送。但是当 puppet 启动它时,只有 python 脚本被执行,就好像 os.system('/bin/bash my_bash_script') 被忽略了一样。没有显示任何错误。用户获得了密码,但 passwd 命令未启动。
puppet 是否有任何限制阻止我执行我所描述的操作?或者,我如何才能更改用户帐户及其到期时间并通过电子邮件发送密码?
我可以提供更多信息,但目前我不知道哪些是准确的。
非常感谢!
编辑:这是具有相同症状的基本代码:
python:设置用户密码.py
#!/usr/bin/python
import os
import sys
user = sys.argv[1]
mail = sys.argv[2]
os.system('/bin/bash /root/tools/setuserpassword.sh '+user+' '+mail)
bash:设置用户密码.sh
#!/bin/bash
# Password setup for the account
password=`pwgen -N1 --secure 10`
echo -ne "$password\n$password\n" | passwd $USER > /dev/null 2>&1
[[ $? -ne 0 ]] && exit 2
# Setup the expirancy label to make sure user
# change its password upon fist success login
chage -d0 $USER
# Email sending to inform user of his new password
echo -ne "Hello, $USER;\n
The password is:\n
$password\n" | mail -s "$USER account created" $MAIL
这是模块(这边没有问题)
define add_user ( $email, $uid, $gid ) {
$username = $title
user { $username:
comment => "$email",
home => "/home/$username",
shell => "/bin/bash",
uid => $uid,
gid => $gid,
}
exec { "/root/tools/setuserpassword.py $username $email":
path => "/bin:/usr/bin:/usr/sbin/sbin",
refreshonly => true,
subscribe => user[$username],
onlyif => "cat /etc/shadow | grep $username | grep '!'",
require => Package['pwgen'],
}
答案1
无需使用 bash 脚本,只需使用我正在用于其他内容的下一个函数来生成影子加密密码:
def shadow(self,password):
SomeZolt="$6$"+''.join(random.choice(string.ascii_uppercase + string.digits) for x in range(9))+"$"
return crypt.crypt(password, SomeZolt)
之后,向您的 Python 脚本中写入附加功能,该脚本将打开 /etc/shadow 文件并写入使用此函数为该用户获取的加密密码,从而生成如下行:
some_user:!!:15579:0:99999:7:::
使其看起来像:
some_user:$1$JShdquwdjsd38hSJhdqwdkwd:15579:0:99999:7:::
因此 some_user 将拥有指定的密码。
另外,您可以通过将 puppet 语句更改为以下形式直接设置用户:
user { $username:
comment => "$email",
home => "/home/$username",
shell => "/bin/bash",
uid => $uid,
gid => $gid,
password => "SomeAlreadyEncryptedPassword",
}
您可以顺便使用指定的函数获取加密的密码,然后将其插入到语句中。
答案2
感谢您的回答,我按照您的建议编写了一个 def 来生成密码哈希并将其放入 /etc/shadow 文件中。
如果有人感兴趣的话,这是我编写的脚本:
class Unix_Account:
def __init__(self, user):
self.user = user
self.password = ''.join(
random.choice(
string.ascii_uppercase + string.ascii_lowercase + string.digits
) for x in range(password_length)
)
self.salt = '$6$'+''.join(
random.choice(string.ascii_uppercase + string.digits
) for x in range(9))+'$'
self.line = self.user+':'+crypt.crypt(self.password, self.salt)+':0:0:99999:7:::'
def change_password(self):
self.result = re.sub(self.user+".*", self.line, file('/etc/shadow', 'r').read())
file('/etc/shadow', 'w').write(self.result)
然后另一个类将密码发送给用户。
密码有效期设置为 0,以便用户在第一次连接时被迫更改密码。
通过 SSH 建立连接,必须使用适当的密钥来设置密码。该密码用于 sudo 命令。
再次感谢!