web-dev-qa-db-ja.com

エコーを使用して機密データを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)

ただし、引数は通常ps -auxで他のユーザーに表示されるため、echoに新しいパスワードをコマンドライン引数として渡すことを心配しています(echo行がpsに表示されることはありませんでした)。

返されたパスワードの前に値を付加し、それをchpasswdに渡す別の方法はありますか?

17
Nils Werner

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端末で生成されたパスワードを表示する代わりに。

15
Kusalananda

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文字以上離れます。

8
ilkkachu