LDAP

ディレクトリのユーザーが自分のパスワードでサインインし、ディレクトリのグループを通じてロールを得られるようにします

  1. 仕組み
  2. 設定
  3. グループ
  4. ロールへの対応付け
  5. 複数のディレクトリ
  6. 接続のテスト
  7. Active Directory の例
  8. OpenLDAP の例
  9. よくある落とし穴

仕組み

AnsibleForms はバインドアカウントでディレクトリに接続してユーザーを検索し、そのユーザーとしてバインドしてパスワードを 確認します。

  1. ユーザーがユーザー名とパスワードでサインインします。その名前の ローカル ユーザーがいない場合に LDAP が試されます。
  2. AnsibleForms はディレクトリの認証情報にあるバインドアカウントでバインドし、 検索ベース の中で ユーザー名属性 が ユーザー名と等しいエントリを検索します。
  3. 見つかったエントリとして、入力されたパスワードでバインドします。
  4. グループをエントリから(またはグループ検索で)読み込み、フィルターをかけ、 ldap/ のプレフィックスを付けます。

UPN 形式のユーザー名( jdoe@example.com )でユーザーが見つからない場合は、 @ より前の部分で一度だけ再試行されます。そのため、ユーザー名属性が 短い名前を保持していても、ユーザーはどちらの形式でもサインインできます。パスワードが間違っている場合は再試行されません。

一つの設定で Active Directory、OpenLDAP などに対応します。7.3.0 からは 複数のディレクトリ を持てます。


設定

7.3.0 からは、設定はディレクトリごとです。 アクセス > LDAP には、ドメインのないユーザー名を検索する順にディレクトリが並びます。

アクセス > LDAP

行メニュー 動作
編集 ディレクトリのページを開きます
接続テスト テスト用のユーザー名とパスワードでログインを試します。 接続のテスト を参照
有効にする、無効にする ディレクトリをオン/オフにします。 main は削除せずにオフにします
上へ移動、下へ移動 検索順での位置を変えます
削除 ディレクトリを削除します。 main では表示されますが無効です

ディレクトリを追加すると、そのページのタブにあたる 4 つのステップでフィールドを入力します。 詳細 には 有効 、 名前 、 説明 があります。

タブ 設定 意味
認証情報 認証情報 必須。 接続 > 認証情報 の ldap 認証情報で、接続先を保持します。下記を参照
ユーザー 検索ベース ユーザー検索を始める DN。例: OU=Users,DC=example,DC=com 。サブツリーも検索されます
ユーザー ユーザー名属性 ログイン名と照合する属性。AD では sAMAccountName (既定)、OpenLDAP では uid
ユーザー メール属性 メールアドレスを保持する属性。通常は mail
ユーザー サインインドメイン user@domain 形式のサインインをこのディレクトリに直接送るドメイン。 複数のディレクトリ を参照
グループ グループ属性 グループを保持するユーザーエントリの属性( memberOf 、既定)。グループ検索を使う場合は groups
グループ グループ検索ベース グループ検索を始める DN
グループ グループクラス グループの objectClass。例: group 、 groupOfNames 、 posixGroup
グループ グループメンバー属性 メンバーを列挙するグループの属性。例: member 、 uniqueMember 、 memberUid 。既定は member
グループ グループメンバーのユーザー属性 メンバーの値が保持しているユーザーの属性。例: dn 、 uid 。既定は dn
グループ グループフィルター 正規表現。名前が一致するグループだけが残ります。空の場合はすべてのグループが残ります

最後の三つのグループフィールドの既定値は、グループ検索を使う場合にだけ適用されます。次のセクションを参照してください。

ldap 認証情報は、ディレクトリへの接続方法と、どのアカウントで検索するかを保持します。

フィールド 意味
サーバー フィールドごとに一つ。 host 、 host:port 、 ldaps://host:port の形式で、この順に試されます。一つに接続できなければ次が試されます
ポート 通常の LDAP は 389 、LDAPS は 636
TLS を有効にする LDAPS( ldaps:// )で接続します。ポート 389 での StartTLS には対応していません
証明書を無視 サーバー証明書の検証を省略します。 TLS を有効にする がオンのときだけ表示されます
証明書 証明書を検証する場合に、AnsibleForms がサーバーに提示するクライアント証明書(PEM)
CA バンドル 証明書を検証する場合に、サーバー証明書に署名した CA 証明書(PEM)
バインドユーザー DN ディレクトリを検索するサービスアカウントの DN
バインドユーザーのパスワード そのパスワード。暗号化して保存するか、 シークレットストア から読み込みます

ldap 認証情報を追加、変更できるのは管理者だけです。 認証情報を変更できるユーザー を参照してください。 7.2.0 までは、サーバー、TLS、バインドアカウントは LDAP 設定のフィールドでした。7.3.0 へのアップグレードでこれらは認証情報に移されます。 認証情報内のアドレス を参照してください。

アップグレード前のディレクトリ サーバーの移動先
独自のバインド DN とパスワードがあり、認証情報がない main-ldap のような <directory>-ldap という名前の新しい ldap 認証情報
サーバーのない認証情報がある その認証情報
すでに別のサーバーを保持する認証情報がある <credential>-<directory> という名前の認証情報のコピー。ディレクトリはそのコピーを指すようになります

名前が使われている場合は -2 、 -3 と続きます。構成シードのディレクトリはそのまま残ります。シードが管理しているためです。


グループ

グループは二つの場所のいずれかから取得され、 グループ属性 がどちらを使うかを決めます。

  • ユーザーエントリの属性 。通常は memberOf です。Active Directory や、 memberof オーバーレイを使う OpenLDAP で一般的な構成です。
  • グループ検索 。 memberOf のないディレクトリ向けです。 グループ検索ベース と グループクラス の両方が 設定されている場合にだけ実行されます。AnsibleForms は、 グループメンバー属性 にユーザーの グループメンバーのユーザー属性 を 含む、そのクラスのグループを検索し、結果を属性 groups に保存します。これを使うには グループ属性 を groups に設定します。

グループ属性 が memberOf の場合、設定されたグループ検索は実行されますが、その結果はロールに使われません。

各グループは DN で、AnsibleForms は最初の CN を残します。 CN=AF-Admins,OU=Groups,DC=example,DC=com は AF-Admins になります。 その名前に グループフィルター が適用され、残ったグループに ldap/ のプレフィックスが付きます: ldap/AF-Admins 。

大きなディレクトリでは、フィルターによってトークンとジョブを小さく保てます。無効な正規表現の場合はすべてのグループが残り、ログに記録されます。


ロールへの対応付け

config.yaml では、LDAP グループは ldap/<group CN> 、LDAP ユーザーは ldap/<username> と書きます。どちらも大文字と小文字が区別されます。

roles:
  - name: admin
    groups:
      - local/admins
      - ldap/AF-Admins
  - name: operator
    groups:
      - ldap/AF-Operators
    users:
      - ldap/jdoe

ユーザー名は、ユーザーが入力したものではなく、ディレクトリが返す ユーザー名属性 の値です。 ロールオプションについては ロール を参照してください。


複数のディレクトリ

7.3.0 からは、それぞれ独自のサーバー、ユーザー、グループを持つ複数のディレクトリを使えます。メンバーはディレクトリの名前で区別されます。

ディレクトリ ユーザー名 グループ ロールでの指定
main jdoe ldap/AF-Admins ldap/jdoe 、 ldap/AF-Admins
corp などそのほか corp/jdoe ldap/corp/AF-Admins ldap/corp/jdoe 、 ldap/corp/AF-Admins

ユーザーはサインイン時に corp\jdoe または corp/jdoe とディレクトリを指定するか、ディレクトリが持つドメインのアドレスで サインインします。ドメインのないユーザー名は、有効なすべてのディレクトリで順に試されます。 other という名前のディレクトリがない場合の other\jdoe のような名前も同様で、入力されたとおりに検索されます。

ユーザーを知っている最初のディレクトリが判定します。そこでパスワードが間違っていればそれが答えとなり、次のディレクトリは 試されません。同じ名前の別人がいる可能性があるためです。接続できないディレクトリはスキップされます。

7.2.0 まで default という名前だったディレクトリは、7.3.0 から main という名前になります。アップグレードで名前が変わり、新しいインストールは main から始まります。メンバーは短い名前のままなので、メンバーを指定しているロールを変更する必要はありません。 main ディレクトリは 名前を変更できず、ディレクトリ名に使えるのは英字、数字、 - 、 _ だけです。


接続のテスト

接続テスト では、テスト用のユーザー名とパスワードを入力し、保存の有無にかかわらず画面上の設定でログインを試します。 成功すると、ユーザーのディレクトリエントリが表示され、使うべき正確な属性名とグループの DN がわかります。

存在しないテストユーザーでも成功と報告されます。接続とバインドアカウントは機能しており、ユーザーが見つからないだけです。 よくあるエラー:

メッセージ 原因
Bad server or port (connection failed) ホスト名を解決できないか、ポートに到達できません。
Wrong binding credentials ディレクトリの認証情報のバインド DN またはパスワードが間違っています。
Unable to verify the certificate サーバー証明書が認証情報の CA バンドルで署名されていません。
Certificate is not valid 認証情報の証明書または CA バンドルに、有効な PEM 証明書が含まれていません。

Active Directory の例

この例では、LDAPS で二つのドメインコントローラーに接続し、名前が AF- で始まるグループだけを残します。

設定 値
認証情報 > サーバー dc01.example.com 、次に dc02.example.com
認証情報 > ポート 636
認証情報 > TLS を有効にする オン
認証情報 > 証明書を無視 オフ。クライアント証明書と企業 CA の CA チェーンを設定
認証情報 > バインドユーザー DN CN=svc-ansibleforms,OU=Service Accounts,DC=example,DC=com
検索ベース OU=Users,DC=example,DC=com
メール属性 mail
ユーザー名属性 sAMAccountName
グループ属性 memberOf
グループフィルター ^AF-

CN=AF-Operators,… のメンバーは ldap/AF-Operators を持つロールに一致し、 jdoe または jdoe@example.com としてサインインします。


OpenLDAP の例

この例では groupOfNames エントリに対するグループ検索を使うため、 memberof オーバーレイがなくても動作します。

設定 値
認証情報 > サーバー ldap.example.com
認証情報 > ポート 636
認証情報 > TLS を有効にする オン
認証情報 > バインドユーザー DN cn=readonly,dc=example,dc=com
検索ベース ou=people,dc=example,dc=com
メール属性 mail
ユーザー名属性 uid
グループ属性 groups
グループ検索ベース ou=groups,dc=example,dc=com
グループクラス groupOfNames
グループメンバー属性 member
グループメンバーのユーザー属性 dn

cn=af-admins,ou=groups,dc=example,dc=com に含まれるユーザーには、グループ ldap/af-admins が付与されます。 posixGroup のグループでは、 グループメンバー属性 に memberUid 、 グループメンバーのユーザー属性 に uid を使います。

memberof オーバーレイを使う場合は、グループ検索のフィールドを空にし、 グループ属性 を memberOf に設定します。


よくある落とし穴

LDAP の問題のほとんどは、次のいずれかに行き着きます。

  • 同じ名前のローカルユーザー。 ローカルユーザーが先に確認されるため、その名前ではディレクトリに問い合わせが行きません。
  • グループがない、または違うグループになる。 グループ属性が存在する必要があります(グループ検索では groups )。 memberOf は入れ子のグループを扱いません。
  • グループ名が一致しない。 大文字と小文字を合わせて ldap/<CN> を使い、グループフィルターがそのグループを残すか確認してください。
  • CN で始まらないグループ DN。 グループ名として使われるのは最初の CN= の値だけなので、すべてのグループ DN は CN= (または cn= )で始まる必要があります。
  • 証明書。 TLS には認証情報の二つの証明書フィールドと、一致するサーバー名が必要です。証明書を無視はテスト専用です。
  • 保存できない設定。 ディレクトリが 構成シード から来ている場合、そのページは 読み取り専用です。代わりにシードファイルを変更してください。

ログインに失敗すると汎用メッセージが表示されます。理由はサーバーがログに記録し、監査ログにも残ります。Active Directory の場合は、ディレクトリのコードから Wrong password 、 Account locked 、 Password expired などに変換されます。