OpenLDAP PBKDF2で安全にパスワードを格納する

Tue, Dec 15, 2015

OpenLDAP と仲間たち Advent Calendar 2015 15日目。

前回説明した通り、OpenLDAPはデフォルトでSSHA1を利用しますが、もはやSSHA1は十分安全とは言えません。

OpenLDAPはPBKDF2という、より安全なハッシュ形式を利用できますのでこちらを使いましょう。

OpenLDAPのPBKDF2モジュールで利用できるハッシュスキーマは以下の通りです。

  • {PBKDF2} - {PBKDF2-SHA1} の別名
  • {PBKDF2-SHA1}
  • {PBKDF2-SHA256}
  • {PBKDF2-SHA512}

今回はこのPBKDF2モジュールのビルド方法と利用方法を紹介します。

以前紹介したback-wtパッケージをインストールされた方は規定でこのPBKDF2モジュールを利用できますのでビルドする必要はありません。

ビルド方法

このPBKDF2モジュールは去年ぐらいに作ったので既に公式レポジトリにマージされていますが、contribディレクトリ以下に入っていてデフォルトではビルドされません。

ビルド手順は以下の通りです。

まずは普通にOpenLDAPをビルドします。

$ tar xf openldap-2.4.x.tgz
$ cd openldap-2.4.x
$ ./configure --enable-modules ... # あとはお好みのオプションで
$ make && make install

続いて、PBKDF2モジュールをインストールします。

$ cd contrib/slapd-modules/passwd/pbkdf2/
$ make
# make install

恐らくLDAPSを利用するために既にインストールされていると思いますが、 このモジュールをビルドするにはOpenSSL 1.0.0以降、もしくはNettle 2.7.1以降が必要です。

Debian系の人はlibssl-dev、Redhat系の人はopenssl-develをインストールしておいてください。

設定

cn=config データベースを利用している場合はcn=module,cn=configに以下の属性を追加します。

olcModuleLoad: pw-pbkdf2

slapd.confを利用している場合は以下を記述します

moduleload pw-pbkdf2

ハッシュの生成方法

ここでは、PBKDF2-SHA512ハッシュを生成していますが、PBKDF2-SHA256やPBKDF2-SHA1も利用可能です。

$ slappasswd -o module-load=pw-pbkdf2 -h {PBKDF2-SHA512} -s secret
{PBKDF2-SHA512}10000$s5CkofBwo6VREusoluEA5A$4DttBShBWz70rzj/IsuWVoOJdI2bFsmHp5k3TLYrPapyWn7J3dNgGOnBuxstyHz0B0aN8LaCMJYW15NEvnkfkg

この方法ではラウンド数が固定(10000回)になるので、任意のラウンド数を利用する場合は後述するPythonのライブラリを利用することを推奨します。

Python PassLib でハッシュを生成

PythonのライブラリPassLibでOpenLDAPのPBKDF2モジュールと互換性のある形式で生成できます。

サンプルコード:

#!/usr/bin/env python

from passlib.hash import ldap_pbkdf2_sha512
print(ldap_pbkdf2_sha512.encrypt("secret", rounds=10000))

メッセージフォーマット

メッセージフォーマットは以下のようになります。

{PBKDF2-SHA512}<Iteration>$<Adapted Base64 Salt>$<Adapted Base64 DK>

このAdapted Base64というのが曲者で通常のbase64ではないので自分でハッシュ値を生成する際は注意してください。

RFC 3062 LDAP Password Modify

RFC 3062 LDAP Password Modify拡張仕様を利用してパスワード変更を行う場合、

slapd.confに

password-hash {PBKDF2-SHA512}

というようにハッシュスキーマを指定してください。