/etc/shadowに書くパスワードハッシュや、useradd -p、Dockerfile、cloud-initの設定に渡すパスワードハッシュが欲しいときは、openssl passwdを使う。

$ openssl passwd -6 mypassword
$6$WMRtE02GkGSMf10.$mYCFLPTsiq5WANnx1NtmBOezAmxLpMJRMqnUqD6rl07foEcCi6kAztMsFVIk27cg7jY.ClMhNhp.vMbl91.n50

-6を付けるとSHA-512方式のハッシュになる。Linuxで広く使われている方式である。ソルト(ランダムな値)は実行のたびに変わるため、同じパスワードでも出力は毎回異なる。

実行例はUbuntu 24.04のOpenSSL 3.0.13のもの。

方式を選ぶ

openssl passwdは、オプションで以下の方式を選べる。

オプション方式出力の先頭
-6SHA-512$6$
-5SHA-256$5$
-1MD5$1$
-apr1Apache用のMD5$apr1$
$ openssl passwd -5 -salt abcdefgh mypassword
$5$abcdefgh$oWz3yhi5bvYMdaRPye7gIGmvGlE3SPNNKbR0gAll3aB
$ openssl passwd -1 -salt abcdefgh mypassword
$1$abcdefgh$k/zxlPoTG.GNe1rFllS.W.
$ openssl passwd -apr1 -salt abcdefgh mypassword
$apr1$abcdefgh$7BgPNa9e5BDegjQKI8xWp0

オプションを省略すると、OpenSSL 3.0ではMD5方式($1$)になる。MD5方式は強度が低いため、/etc/shadow用には-6を指定する。

$ openssl passwd mypassword
$1$O3nQ/nuF$.8nJcORvGtJxPw4RuJFVO/

-crypt(DES方式)はOpenSSL 3.0で削除された。

$ openssl passwd -crypt -salt ab mypassword
passwd: Unknown option: -crypt
passwd: Use -help for summary.

/etc/shadowに設定する

usermod -pやuseradd -pは、ハッシュ済みのパスワードを受け取る。

$ usermod -p "$(openssl passwd -6 mypassword)" [ユーザー名]

/etc/shadowの2番目のフィールドに、ハッシュが設定される。

$ grep '^tu:' /etc/shadow | cut -c1-40
tu:$6$abcdefgh$oLS1rGK4lgcGC1pX.2W993IA8

$6$などの$はシェルの変数展開の対象になる。コマンドラインに直接貼り付ける場合は、シングルクォートで囲む。

パスワードをコマンドラインに書かない

openssl passwd -6 mypasswordのようにパスワードを引数で渡すと、psの出力やシェルの履歴に残る。以下の方法で避けられる。

パスワードを省略すると、対話的に入力を求められる。入力は画面に表示されず、確認のために2回入力する。

$ openssl passwd -6
Password:
Verifying - Password:
$6$...

-stdinを付けると、標準入力から読み込む。末尾の改行は取り除かれるため、echoで渡しても同じハッシュになる。

$ echo 'mypassword' | openssl passwd -6 -stdin

-inでファイルから読み込む方法もある。

$ openssl passwd -6 -in pw.txt

ソルトを固定する

-saltでソルトを指定すると、同じパスワードから同じハッシュを得られる。

$ openssl passwd -6 -salt abcdefgh mypassword
$6$abcdefgh$oLS1rGK4lgcGC1pX.2W993IA8lR78HDKGKVffSLo1vsBwBx7BMfusZG93xlucBJAgJ91sTe/823AJaAf79KjO0

Ansibleなど、実行のたびにハッシュが変わると差分として扱われるツールで使える。通常の運用ではソルトを固定せず、ランダムなままにする。

ソルトの長さには上限がある。-6と-5は16文字、-1と-apr1は8文字までで、超えた分は切り捨てられる。

$ openssl passwd -6 -salt abcdefghijklmnopqrstuvwxyz mypassword
$6$abcdefghijklmnop$jxZ5UKgPKWlCx21QPZbkQOj73EKOWhff2HX66XmEGXBN7/VGv5K5AH0mgtIbyEHEwJOO3UibHo1CrTlQvXbbS/

mkpasswdと同じハッシュになるか確認する

Debian系のmkpasswd(whoisパッケージに含まれる)と、同じソルトと方式で同じハッシュが得られる。

$ mkpasswd -m sha-512 -S abcdefgh mypassword
$6$abcdefgh$oLS1rGK4lgcGC1pX.2W993IA8lR78HDKGKVffSLo1vsBwBx7BMfusZG93xlucBJAgJ91sTe/823AJaAf79KjO0

Apacheの.htpasswd用のハッシュを作る

-apr1は、Apacheのhtpasswdが生成するMD5方式のハッシュと同じ形式である。.htpasswdには「ユーザー名:ハッシュ」の形式で書く。

$ echo "user:$(openssl passwd -apr1 mypassword)" >> .htpasswd

htpasswdが生成したハッシュからソルトを取り出して、openssl passwd -apr1に渡すと、同じハッシュを再現できる。

$ htpasswd -nbm user mypassword
user:$apr1$j3etLdp4$I88g0SjptrZF21cFqZxNk1
$ openssl passwd -apr1 -salt j3etLdp4 mypassword
$apr1$j3etLdp4$I88g0SjptrZF21cFqZxNk1

複数のパスワードをまとめて処理する

引数に複数のパスワードを並べると、1行ずつハッシュが出力される。

$ openssl passwd -6 -salt abcdefgh a b
$6$abcdefgh$GjMgmmowSihU3X8xhdMxaCaEziO5NUh/IZqYnnZhN1j7.JYnm2e5BnPfWNUdj17OlEroBdrPtMnfsmwWCrkw70
$6$abcdefgh$QNDsjVtcjgKxzgqPVjOqfIzf0lELKpeIMXOOsA7k/T6H5MgnypPn6v5t9JJKExNaYlbmMCtYN.GTrFAEjXtiS/

バージョンによる違い

OpenSSL 3.5や3.6でも、-6の出力は同じである。

macOS標準の/usr/bin/openssl(LibreSSL 3.3.6)のpasswdは、-6と-5に対応していない。unknown option '-6'というエラーになる。-1、-apr1、-cryptが使える。

$ /usr/bin/openssl passwd -6 mypassword
unknown option '-6'

macOSで-6を使う場合は、Homebrewなどでインストールしたopensslを使う。

参考

openssl-passwd - OpenSSL Documentation