使用 echo 将敏感数据传递到 chpasswd 是否安全?

使用 echo 将敏感数据传递到 chpasswd 是否安全?

我正在尝试使用 批量设置一些用户帐户密码chpasswd。密码应该随机生成并打印到stdout(我需要将它们写下来或将它们放入密码存储中),并且也传递到chpasswd.

天真地,我会这样做

{
  echo student1:$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 13 ; echo '')
  echo student2:$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 13 ; echo '')
} | tee >(chpasswd)

但是,我担心将新密码作为命令行参数传递给echo,因为参数通常对 中的其他用户可见ps -aux(尽管我从未echo在 中看到任何行出现ps)。

是否有其他方法可以在返回的密码前添加一个值,然后将其传递到chpasswd

答案1

您的代码应该是安全的,echo因为它是内置的 shell,因此不会显示在进程表中。

这是一个替代解决方案:

#!/bin/bash

n=20
paste -d : <( seq -f 'student%.0f' 1 "$n" ) \
           <( tr -cd 'A-Za-z0-9' </dev/urandom | fold -w 13 | head -n "$n" ) |
tee secret.txt | chpasswd

这将创建您的学生姓名和密码,n而无需在任何命令的任何命令行上传递任何密码。

paste实用程序将多个文件作为列粘合在一起,并在它们之间插入分隔符。在这里,我们使用:作为分隔符并给它两个“文件”(过程替换)。第一个包含seq创建 20 个学生用户名的命令的输出,第二个包含创建 20 个长度为 13 的随机字符串的管道的输出。

如果您有一个已生成用户名的文件:

#!/bin/bash

n=$(wc -l <usernames.txt)

paste -d : usernames.txt \
           <( tr -cd 'A-Za-z0-9' </dev/urandom | fold -w 13 | head -n "$n" ) |
tee secret.txt | chpasswd

这些会将密码和用户名保存到文件中,secret.txt而不是在终端中显示生成的密码。

答案2

echo很可能内置于 shell 中,因此它不会ps作为单独的进程出现。

但是您不需要使用命令替换,您可以直接将管道的输出直接发送到chpasswd

{  printf "%s:" "$username";
   head /dev/urandom | tr -dc A-Za-z0-9 | head -c 13 ; echo ''
} | chpasswd 

如果您想通过一次运行更改多个密码chpasswd,那么重复基本部分应该很容易。或者将其变成一个函数:

genpws() {
    for user in "$@"; do
        printf "%s:" "$user";
        head /dev/urandom | tr -dc A-Za-z0-9 | head -c 13
        echo
    done
}
genpws username1 username2... | chpasswd 

顺便说一句:这head /dev/urandom感觉有点奇怪,因为urandom不是面向线路的。它可能会从中读取过多的字节,这将影响内核的可用熵概念,进而可能导致/dev/random阻塞。只读取固定数量的数据,并使用类似base64将随机字节转换为可打印字符的方法(而不是仅仅扔掉获得的大约 3/4 字节)可能会更干净。

像这样的东西会给你大约。 16个字符和数字:

head -c 12 /dev/urandom | base64 | tr -dc A-Za-z0-9 

(也就是说,在 的输出中减去+和字符的数量。每个字符的概率为 1/32,所以如果我的组合正确,则大约有 99% 的机会留下至少 14 个字符,并且99.99% 的机会留下至少 12 个。)/base64

相关内容