passwdコマンドで対話的にパスワードを変更するのではなく、コマンドでワンライナーあるいはシェルスクリプト実行で変更したい場合、chpasswdを使用する。
一人分のパスワード変更であれば以下のように書ける。

echo "username:password" | chpasswd

複数人のパスワードを一回で変更したければ、ファイルに同様の書式で、各行に各人の"username:password"を書けばいい。尚、空行が入らないように注意すること。

chpasswd < ファイル名

自分一人の使い捨てスクリプトであれば上記対応で問題ないが、サーバの初期構築で固定のユーザを一括で登録するなどの目的であれば、パスワードが平文でファイルやコマンドに記載されているのは、セキュリティ上好ましくない。

chpasswdは暗号化されたパスワードも受け取ってくれるので、ファイルに"username:encrypted_password"の書式で書くことにする。
encrypted_passwordの部分の書式は、/etc/shadowでも使用されているパスワードファイル用の形式と同じ。

$<ハッシュ方式>$<salt>$<ハッシュ後のパスワード>

この書式をPerlで作成する。

perl -e 'print "username:", crypt("plain_password", "\$6\$" . join ("", map { (a..z,A..Z)[rand 52] } 1..8)), "\n"' >> /tmp/passwordfile
  • $6$はSHA512でハッシュ化することを示している。
  • join ("", map { (a..z,A..Z)[rand 52] } 1..8)) は8桁のSaltをランダムに生成している。

簡略化すると以下のコマンドになる。

perl -e 'print "username:", crypt("plain_password", "\$6\$salt"), "\n"'

出力結果は以下のようになる。

username:$6$rYlftLJE$x.ucNeKnapdsGsX5KEHhgwnlhg1XV9nj7cF5ihl9lQHQlX2C8iUjMJf4VcZwjZhl5yyHBKU2.U1Lbjgbo4l.G1

/tmp/passwordfileに"username:encrypted_password"が出力されたので、これをchgpasswdに渡してあげれば良いが、暗号化されたパスワードをchgpasswdに渡す場合は、-e オプションが必要となる。

chgpasswd -e < /tmp/passwordfile