LoginSignup
13
12

More than 5 years have passed since last update.

OpenAMでリスクベースのLDAP + TOTP多要素認証

Posted at

Overview

  • OpenAMでリスクベースの認証を実装する。
  • OTPはTOTP(Time based One-time Password)を使用する。
  • OATHの仕様に沿ったTOTPなのでOATH準拠のアプリ(Google Authenticator等)ならどの端末でもワンタイムパスワードを生成出来る。
  • リスクベース認証はアダプティブ認証とデバイスプリント認証を組み合わせて、IPが特定の範囲外の場合、ログインに何度も失敗した場合、前回ログイン時刻が一定の時間以上、前回とデバイスの環境が大きく異なる場合などにOTPを要求するようにする。
  • マルチレルムで認証データストアや認証方法、使えるリソースをレルムごとに分けれるようにする。

Requirements

  • OpenAM
  • Google Authenticator

Conditions

項目
最上位レルム /
最上位レルムドメイン openam-proxy.example.com
テスト用レルム test
テスト用レルムドメイン openam-proxy-test.example.com

Install

OpenAMのインストールは以前書いた手順を参照します。

TOTP認証の追加

  • レルムの追加

既存のレルムで認証方法を追加すると設定を失敗したときにまったくアクセス出来なくなる可能性もあるので別レルムに分ける。
TOPより「アクセス制御」 -> 「新規」を選択。

項目 補足
名前 test
/
レルム状態 アクティブ
レルムまたはDNSのエイリアス openam, openam-test.example.com, openam-test2.example.com, openam-proxy-test.example.com このレルムで使用するFQDNのリスト

「了解」をクリック作成する。

最上位のレルムについてもDNSのエイリアスを設定しておく。ここでアクセスするURLが決まる。
トップレベルドメインやセカンドレベルドメインが違う場合(example.com, example.net, example.org, hoge.com等)は「設定」 -> 「システム」 -> 「プラットフォーム」 -> 「Cookieドメイン」に該当するドメインを追加する。例: .example.org

  • hostsファイル編集

テスト用なので/etc/hostsで解決出来るようにする。

192.168.34.10 openam.example.com
192.168.34.11 openam2.example.com
192.168.34.10 openam-test.example.com
192.168.34.11 openam-test2.example.com
192.168.34.100 openam-proxy.example.com
192.168.34.100 openam-proxy-test.example.com
  • OATH認証の追加

「アクセス制御」-> レルム一覧から「test」 -> 画面上タブから「認証」-> モジュールインスタンスにOATHを「新規」をクリックし追加する。
作成後「OATH」をクリックしプロパティを編集する。OAuthではないので注意。

項目 補足
認証レベル 10 多要素認証なので高めの10を設定
ワンタイムパスワードの長さ 6 ワンタイムパスワードの長さ. Google Authenticatorに合わせて6にする。
秘密鍵の最小桁数 8 格納する秘密鍵の桁数
秘密鍵の属性名 title 秘密鍵を格納するLDAPの属性名。とりあえずtitleにしたが適切なカスタムattributeを作成して入れた方がいい。
使用する OATH アルゴリズム TOTP Time based One-time PasswordなのでTOTP
HOTPウインドウサイズ 100
カウンタ属性名 (空)
チェックサムの数字の追加 いいえ
トランケーションオフセット -1
TOTPタイムステップ期間 30
TOTPタイムステップ数 2
最終ログイン時間属性 description 最終ログイン時刻(Unixタイム)を格納するLDAP属性名。とりあえずdescriptionにしたが適宜カスタムattribute等追加して対応する
  • 認証連鎖の追加

「アクセス制御」-> レルム一覧から「test」 -> 画面上タブから「認証」-> 認証連鎖の「ldapService」を選択 -> インスタンスに「OATH」を追加 -> 「保存」をクリック。

  • ntpdの設定

時刻にもとづいて認証しているのでクライアントとサーバーで大幅にずれると認証が上手くいかなくなる。
数秒なら許容出来るが100秒とかいくと無理だった。VM上で検証していてPCを閉じていたときにずれてハマった。

$ yum install ntp

$ vim /etc/ntp.conf

  restrict 192.168.1.0 mask 255.255.255.0 nomodify notrap #192.168.1.0/24内からのntpリクエストは受け付ける
  server ntp.nict.jp # デフォルトのcentosのサーバは遅いのでこちらを使う。
  server ntp.jst.mfeed.ad.jp

$ ntpdate ntp.nict.jp
$ service ntpd start
$ chkconfig ntpd on

冗長化設定

冗長化自体のインストールは以前書いた手順を参照します。

TOPより「設定」 -> 「サーバーとサイト」 で新規サーバーを追加する。
ドメインはそれぞれ重複しないように設定していく。

サーバー

サーバー名 サイト名
http://openam.example.com:8080/openam test
http://openam2.example.com:8080/openam test
http://openam-test.example.com:8080/openam testrealm
http://openam-test2.example.com:8080/openam testrealm

サイト

サイト名 プライマリURL 割り当てられたサーバー
test http://openam-proxy.example.com:80/openam http://openam.example.com:8080/openam, http://openam2.example.com:8080/openam
testrealm http://openam-proxy-test.example.com:80/openam http://openam-test.example.com:8080/openam, http://openam-test2.example.com:8080/openam

リスクベース認証の追加

OpenAMはリスク評価に基づいて認証方法を柔軟に選択出来る。
例えば社外のIPからのアクセスの場合はOTP認証を追加する、過去に認証を失敗している場合は更に認証を要求する等。

Device ID(Match)

OpenAM 12.0.0からDevice Identifer情報に基づく認証が追加された。Device ID(Match), Device ID(Save)の2つ。Device Print ModuleはHOPTのみ対応で使い勝手が悪かったけどこちらは他の認証にチェイン出来るので色々使いやすい。
MatchはDeviceID(Save)で保存されたデバイス情報のリストに現在のデバイスがどれくらい合致しているかのチェックを行う。閾値を超えなければ成功、超えれば失敗。なお複数デバイス登録されている場合最も近いデバイスの値が用いられる。
条件は「十分」でサーバに登録されていないデバイスからの接続の場合他のOTP認証やLDAP認証にチェインすると便利。

Device ID(Save)

デバイス情報を保存する。条件は「必要」で認証連鎖の最後に追加しておく。これより前のモジュールで認証の成功、失敗に関わらず必ず次に進む条件(「オプション」か「必要」)にしておくと必ず保存出来る。あと最後に置いておくと最初の方に置くより書き込み負荷が小さいから。

アダプティブ認証

認証失敗

過去に認証に失敗(一部分ではなく全体として失敗)していた場合リスクスコアが増える。
有効にするにはアカウントロック機能を有効にし、失敗した記録を認識させる必要がある。
アカウントロックは「アクセス制御」-> レルム選択 -> 上部タブ「認証」 -> 「すべてのコア設定」 -> 「アカウントロック」から有効に出来る。アカウントロックを有効にするとロックまでの許容回数、ロック時のメール通知、ロックアウト時間等設定等を出来る。

IPアドレスレンジ

特定のIPレンジの場合リスク値を増やす。例: 社外のIPの場合等。
ホワイトリスト形式で許可するIPの一覧を追加する。

設定例

  • 10.0.2.15 (単一)
  • 192.168.34.0/24 (レンジ)
  • 10.0.2.0-10.0.2.100 (レンジ)

IPレンジを認識する点はロードバランサがある場合ロードバランサから見たIP。
ロードバランサの背後にある場合は「サーバーおよびサイト」より
サイト名→高度→com.sun.identity.authentication.client.ipAddressHeaderにX-Forwarded-Forをそれぞれセットする。

バグ
  • OpenAM v11.0.0においてログレベルを「メッセージ」にしデバッグメッセージも表示させた状態かつIPレンジを有効にした状態でIPレンジに一つだけIPv4アドレスをレンジ指定なしで登録した場合an IPv6 address should contain 8 shortsとエラーが出る。

[#OPENAM-3607] Adaptive IP check fails when message level debug enabled - ForgeRock JIRA R7982で修正された模様。

対策: 「サーバーおよびサイト」より各サーバのログレベルを「エラー」にする。

IPアドレス履歴

ログインしたIPアドレスを記録し、記録にないIPの場合リスク値を増やす。
LDAPの属性名にiphistoryなどの項目を作りデータストアに認識させる必要がある。

項目
IP履歴チェック 有効
プロファイル属性名 iphistory
成功したIPアドレスを保存 有効
デバイス Cookie

デバイスにCookieをセットしその値が含まれていればチェックを成功とする。

最終ログインからの経過時間

最終ログインからの経過時間をCookieに保存し次回ログイン時設定した期間を超えていたらチェックを失敗とする。

位置情報

アクセス元の国からリスク値を算出する。

curl -L -O http://geolite.maxmind.com/download/geoip/database/GeoLite2-Country.mmdb.gz
gunzip GeoLite2-Country.mmdb.gz > GeoLite2-Country.mmdb
mv GeoLite2-Country.mmdb /var/lib/
  • 設定
項目
位置情報データベースの場所 /var/lib/GeoLite2-Country.mmdb
有効な国コード jp
  • アダプティブ認証の追加
※注意: アダプティブ認証ポストプロセスを追加しないと動作しない

TOPより「アクセス制御」 -> レルム一覧から「test」を選択 ->
上部タブから「認証」を選択 -> モジュールインスタンスにタイプ「Adaptive」を追加。

「レルム一覧」から「test」を選択 -> 「すべてのコア設定」 -> 「認証ポストプロセスクラス」に
「org.forgerock.openam.authentication.modules.adaptive.Adaptive」クラスを追加する

認証連鎖にアダプティブ認証を追加する。条件は十分(認証に成功した場合は次の認証を実行しない、失敗した場合は次の認証を実行する)にする。

認証連鎖のプロパティ例

インスタンス 条件 オプション
DataStore 必須
アダプティブリスク 十分
OATH 必要

この認証連鎖の意味としては

  1. データストア(LDAP)での認証での成功は必須。認証に成功すれば終了し、失敗すれば先へ進まない
  2. データストアでの認証に失敗し、アダプティブ認証でリスクが高いと判断したアクセスの場合OTPへ進む
  3. OATH認証の条件は必要(必ず成功が必要)なのでここで認証に失敗すると全体として失敗

という具合になる。

References

OpenAMが提供する様々な認証方式 (1/4):CodeZine
OSSによるアイデンティティ管理(2):不正ログインを食い止めろ! OpenAMで認証強化 (1/2) - @IT

13
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
12