SSHAのhtpasswd
NginxでBASIC認証をしてみたのですが、htpasswdファイルを作るのにちょっとてこずった話です。
Nginxのドキュメントを読むと、BASIC認証を有効にするにはconfファイルに
auth_basic "closed site";
auth_basic_user_file conf/htpasswd;
を追加するだけとのこと。今回はバーチャルホスト全体を認証付きにしたかったので、serverコンテキストにこれを追加しました。
htpasswdファイルは、MD5ベースのapr1形式なら、Apacheのhtpasswdコマンドを使うか、”openssl passwd”で作れる、と書いてあったんですが、その後ろに、他の形式も”{scheme}data”形式でサポートしてて、スキーマとしてはPLAIN、SHA、SSHAが用意されているとのことです。ただ、PLAINとSHAは非推奨なので、実質、apr1かSSHAのどちらかということになります。
わざわざhtpasswdコマンドを使うためにapacheのパッケージをインストールするのもしゃくだし、opensslでやるならMD5でもSHA-1でも大して変わらないから、SHA-1のほうのSSHAで作ることにしました。
まず、「SSHAとは」でググってJULYさんのブログで勉強しました。ソルトは4バイトで、パスワード+ソルトをSHA-1でハッシュ化して、それにソルトをくっつけてBASE64すればよさげだったので、シェルスクリプトを書いてみました。
#!/bin/sh
if [ $# -ne 2 ]
then
echo "Usage: $0 user passwd" 1>&2
exit 1
fi
USER="$1"
PASSWD="$2"
SALT=`openssl rand 4`
echo -n "$USER:{SSHA}"
base64 <<_EOF
$(echo "${PASSWD}${SALT}" | openssl dgst -binary -sha1)$SALT
_EOF
これをhtpasswdって名前のファイルにして、chmod +x して、実行すると、
$ ./htpasswd user passwd
user:{SSHA}6rKEyj1LKPJKM6+5sXiFc4n6j1YIeHEsCg==
こんなかんじで出力されたので、これをauth_basic_user_fileで指定したファイルに書き込んで、service nginx reload してあげたら、すんなり認証画面が出てきて、ログインできました。