LDAP
ディレクトリのユーザーが自分のパスワードでサインインし、ディレクトリのグループを通じてロールを得られるようにします
仕組み
AnsibleForms はバインドアカウントでディレクトリに接続してユーザーを検索し、そのユーザーとしてバインドしてパスワードを 確認します。
- ユーザーがユーザー名とパスワードでサインインします。その名前の ローカル ユーザーがいない場合に LDAP が試されます。
- AnsibleForms はディレクトリの認証情報にあるバインドアカウントでバインドし、 検索ベース の中で ユーザー名属性 が ユーザー名と等しいエントリを検索します。
- 見つかったエントリとして、入力されたパスワードでバインドします。
- グループをエントリから(またはグループ検索で)読み込み、フィルターをかけ、
ldap/のプレフィックスを付けます。
UPN 形式のユーザー名( jdoe@example.com )でユーザーが見つからない場合は、 @ より前の部分で一度だけ再試行されます。そのため、ユーザー名属性が 短い名前を保持していても、ユーザーはどちらの形式でもサインインできます。パスワードが間違っている場合は再試行されません。
一つの設定で Active Directory、OpenLDAP などに対応します。7.3.0 からは 複数のディレクトリ を持てます。
設定
7.3.0 からは、設定はディレクトリごとです。 アクセス > 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 などに変換されます。