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)
ただし、引数は通常ps -aux
で他のユーザーに表示されるため、echo
に新しいパスワードをコマンドライン引数として渡すことを心配しています(echo
行がps
に表示されることはありませんでした)。
返されたパスワードの前に値を付加し、それをchpasswd
に渡す別の方法はありますか?
echo
はシェルの組み込みなのでプロセステーブルに表示されないため、コードは安全である必要があります。
これが代替ソリューションです:
#!/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
ユーティリティは、いくつかのファイルを列として結合し、それらの間に区切り文字を挿入します。ここでは、:
を区切り文字として使用し、2つの「ファイル」(プロセス置換)を指定します。 1つ目は、20の学生のユーザー名を作成するseq
コマンドの出力を含み、2つ目は、長さ13の20個のランダムな文字列を作成するパイプラインの出力を含みます。
ユーザー名が既に生成されているファイルがある場合:
#!/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
端末で生成されたパスワードを表示する代わりに。
echo
はシェルに組み込まれている可能性が高いため、ps
には個別のプロセスとして表示されません。
ただし、コマンド置換を使用する必要はありません。パイプラインから直接chpasswd
に出力することができます。
{ printf "%s:" "$username";
head /dev/urandom | tr -dc A-Za-z0-9 | head -c 13 ; echo ''
} | chpasswd
chpasswd
を1回実行して複数のパスワードを変更する場合は、重要な部分を繰り返すのが簡単です。またはそれを関数にします:
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
余談ですが、urandom
は行指向ではないため、_head /dev/urandom
は少し奇妙に感じられます。そこから過剰なバイト数を読み取る可能性があり、カーネルの利用可能なエントロピーの概念に影響を与え、次に/dev/random
ブロッキングにつながる可能性があります。一定量のデータを読み取り、base64
のようなものを使用して、ランダムなバイトを印刷可能な文字に変換する(取得したバイトの約3/4を捨てるのではなく)方がきれいな場合があります。
このようなものはあなたに約を与えるでしょう。 16文字と数字:
head -c 12 /dev/urandom | base64 | tr -dc A-Za-z0-9
(つまり、+
の出力における/
およびbase64
文字の量から16を差し引いたものです。どちらかの可能性は1文字あたり1/32なので、組み合わせを正しく設定すると、これにより、約99%の確率で14文字以上、99.99%の確率で12文字以上離れます。