在shell脚本中使用passwd命令


Answers:


93

来自“ man 1 passwd”:

   --stdin
          This option is used to indicate that passwd should read the new
          password from standard input, which can be a pipe.

所以你的情况

adduser "$1"
echo "$2" | passwd "$1" --stdin

[更新]评论中提到了一些问题:

您的passwd命令可能没有--stdin选项:chpasswd 按照ashawley的建议使用实用程序。

如果您使用的不是bash外壳,则“ echo”可能不是内置命令,外壳将调用/bin/echo。这是不安全的,因为该密码将显示在进程表中,并且可以通过诸如之类的工具查看ps

在这种情况下,您应该使用另一种脚本语言。这是Perl中的示例:

#!/usr/bin/perl -w
open my $pipe, '|chpasswd' or die "can't open pipe: $!";
print {$pipe} "$username:$password";
close $pipe

您应该引用参数扩展。此外; 这绝不是便携式的形状或形式,甚至丝毫也不推荐。有关该主题的更多信息,请参见我的回复。
lhunath

2
请不要使用echo ... | 密码!这样,任何其他运行ps的用户都可以看到该密码。而且,您通过密码的地方(不同的程序,文件,管道等)越多,它泄漏到某处的可能性就越大。
布赖恩·坎贝尔

@lhunath:您对报价是正确的,我会解决的。@Brian:“ echo”是内置的bash,它将不会显示在“ ps”输出中(至少以bash显示,不确定sh)
09年

3
如果bash那么passwd "$1" <<< "$2"
glenn jackman 2011年

1
@glennjackman请注意,此处的字符串隐式创建了临时文件,这些文件可能会被外部源读取。
lhunath 2015年

61

唯一的解决方案适用于Ubuntu 12.04:

echo -e "new_password\nnew_password" | (passwd user)

但是第二个选项仅在我更改为时才有效:

echo "password:name" | chpasswd

至:

echo "user:password" | chpasswd

请参阅原始帖子中的说明:通过脚本更改密码


1
echo 'user:newpassword' | sudo chpasswd,或者没有sudo作为root。
ThorSummoner

如果在第一种情况下密码包含“ \ n”怎么办?有办法解决吗?如my@secret\npasword123
Eduardo Baitello,

1
与第一个相似,但会自动重复输入密码。另外,使用sudo,否则它将首先要求输入当前密码并将其弄乱。 echo password | sed 's/.*/\0\n\0/' | sudo passwd -q $USER 2> /dev/null
卡梅隆·塔克林德

27

阅读以下明智的话:

我引用:

在bash中您无能为力。passwd(1)不会从标准输入中读取。这是故意的。这是为了保护您。密码绝不打算放到程序中或由程序生成。它们只能由具有功能性大脑的实际人类的手指输入,并且永远都不会写下来。

尽管如此,我们还是吸引了很多用户问他们如何规避35年的Unix安全性。

它接着解释你如何可以设置您的shadow(5)正确密码,并为您展示GNU-只有I-护理有关的安全性,如果-IT-doesn't-MAKE-ME-觉得太太多滥用的三通passwd(1)

最后,如果您要使用愚蠢的GNU passwd(1)扩展名--stdin请不要通过密码将其放在命令行中。

echo $mypassword | passwd --stdin # Eternal Sin.
echo "$mypassword" | passwd --stdin # Eternal Sin, but at least you remembered to quote your PE.
passwd --stdin <<< "$mypassword" # A little less insecure, still pretty insecure, though.
passwd --stdin < "passwordfile" # With a password file that was created with a secure `umask(1)`, a little bit secure.

最后是您可以使用GNU做到的最好的事情passwd。尽管我仍然不推荐它。

将密码放在命令行上意味着即使对该框的访问最遥远的提示的任何人都可以监视ps或窃取密码。即使您认为自己的盒子很安全;这是您应该真正养成避免不惜一切代价避免的习惯(是的,即使付出更多的麻烦才能完成工作)。


1
请问为什么这仍然“还算不安全”?$ passwd --stdin <<< $(pass somehost / someuser)
杰克·唐

2
@JackTang您需要在参数扩展上加上引号。<<<相比具有良好权限的文件,其安全性不如<的原因,是因为<<<可能隐式创建了一个外部人员可读的临时文件。
lhunath

27

现在,您可以使用以下命令:

echo "user:pass" | chpasswd

5
由于某些原因,在尝试您的命令时收到以下错误:“身份验证令牌操作错误”。在chpasswd之前添加sudo可以解决此问题。
洛朗·范温克尔

2

对于那些需要通过脚本登录到sudoers文件中的用户帐户来远程“以root用户身份运行”的人,我发现了一个邪恶的可怕骇客,这无疑是非常不安全的:

sshpass -p 'userpass' ssh -T -p port user@server << EOSSH
sudo -S su - << RROOT
userpass
echo ""
echo "*** Got Root ***"
echo ""
#[root commands go here]
useradd -m newuser
echo "newuser:newpass" | chpasswd
RROOT
EOSSH

1

您可以使用chpasswd

echo $1:$2 | chpasswd


1

如果您的文档passwd不支持--stdin并且chpasswd出于某种原因而不想(或不能)使用,则此文档有效。

例:

#!/usr/bin/env bash

username="user"
password="pass"

passwd ${username} << EOD
${password}
${password}
EOD

在Arch Linux下测试。这passwd是软件包的元素,shadow-utils并从core/filesystem软件包中安装,由于软件包是必需的,因此通常默认情况下具有该元素core/base


0

你看的-p的选项adduser(据我所知这是另一个名字useradd)?您可能还希望查看使用纯文本密码的-P选项luseradd,但是我不知道这是否luseradd是标准命令(它可能是SE Linux的一部分,或者可能只是Fedora的一部分)。


0

在CentOS VMWare映像上对此进行了测试,我为此保留了该映像。请注意,您可能要避免将密码作为命令行参数,因为整个计算机上的任何人都可以从“ ps -ef”中读取密码。

也就是说,这将起作用:

user="$1"
password="$2"
adduser $user
echo $password | passwd --stdin $user

0

有时设置一个没人知道的密码很有用。这似乎可行:

tr -dc A-Za-z0-9 < /dev/urandom | head -c44 | passwd --stdin $user

5
最好禁用一个帐户/禁用其登录名,而不是给它一个未知的密码,但保持其登录名有效。
Daniel W.

2
passwd --delete或--lock
temoto 2015年

0

这是Teradata节点管理员的明确答案。

转到/etc/hosts文件,然后在文本文件中创建IP或节点名称的列表。

SMP007-1
SMP007-2
SMP007-3

将以下脚本放入文件中。

#set a password across all nodes
printf "User ID: "
read MYUSERID
printf "New Password: "
read MYPASS

while read -r i; do
    echo changing password on "$i"
    ssh root@"$i" sudo echo "$MYUSERID":"$MYPASS" | chpasswd
    echo password changed on "$i"
done< /usr/bin/setpwd.srvrs

好的,我知道我已经用ssh和root破坏了基本的安全规则,但是我会让安全人员来处理它。

现在,将此/usr/bin与您的setpwd.srvrs配置文件。

当您运行命令时,它会提示您一次输入用户ID,然后一次提示您输入密码。然后,脚本遍历setpwd.srvrs文件中的所有节点,并对每个节点执行无密码ssh,然后设置密码而无需任何用户交互或辅助密码验证。


我修复了最严重的错误,但这根本不是最佳实践。硬编码本地数据文件/usr/bin只是一个可怕的想法。
Tripleee

0

我偶然发现了相同的问题,由于某种原因,该--stdin选项在passwd我使用的版本中不可用(在Ubuntu 14.04中提供)。

如果您碰巧遇到相同的问题,可以使用以下chpasswd命令像我一样解决此问题:

echo "<user>:<password>" | chpasswd

0

对我而言,在Raspbian上,它仅以此方式工作(添加了旧密码):

#!/usr/bin/env bash

username="pi"
password="Szevasz123"
new_ps="Szevasz1234"

passwd ${username} << EOD
${password}
${new_ps}
${new_ps}
EOD

-1

您可以使用expect实用程序来驱动从tty读取的所有程序(与stdin相反,passwd就是这样做的)。Expect附带有可以立即运行的示例,用于处理各种交互式问题,例如passwd输入。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.