Quantum周りのたった1つの問題に1週間以上ハマって絶望するも、
絞りだすような勘で生還してブログ再開!!
今回はなんとっ!KeystoneデータをLDAPで管理するという一風変わった情報をお届けします!
LDAPを採用した理由
どうしてわざわざLDAPにしたのか、というと、
まず、既にLDAPが存在し、他の複数のソフトウェアのアカウント管理に用いていたため、OpenStackも同様に既存のLDAPユーザでログインしたかった、というのが1つ。
次に、LDAPユーザから削除された(例えば退職したとか)場合に、そのユーザが管理していたVMを自動的に(もしくは一括して)削除できるようにするこ とで、VMをより管理しやすくしたかったから。Horizonの表示上は見えませんが、実は novadb.instances テーブルには user_id が保存されているし、nova-manage vm list でも確認できるので、実現することは容易いです。
ということで、ユーザデータだけは既存LDAPのデータを使用し、それ以外のテナントやロールは新規に作成。さらに、一部を除いてデータ管理は keystone コマンドではなく、LDAP Account Manager(LAM)で行うというルールの元に構築していっています。
LDAPサーバslapdの構築
テストデータとなる slapd をControllerNodeにでも作成します。
パッケージインストール
apt-get install slapd ldap-utils
|
設定は以下のようにしています。
- 組織DNS : openstack.org
- バックエンド : HDB
- DN管理者 : admin / rootpass
dpkg-reconfigure slapd
# データ確認slapcat | less
|
設定
- パスワードのSSHAを取得し、設定ファイルに利用します。
slappasswd{SSHA}PNof4WRW8ckd7bWQRfof1CVmgeQ14B09
|
- 設定ファイルを作成します。
/etc/ldap/slapd.conf
include /etc/ldap/schema/core.schema
include /etc/ldap/schema/cosine.schema
include /etc/ldap/schema/inetorgperson.schema
include /etc/ldap/schema/nis.schema
pidfile /var/run/slapd/slapd.pid
argsfile /var/run/slapd/slapd.args
loglevel 0
modulepath /usr/lib/ldap
moduleload back_hdb
tool-threads 1
backend hdb
database hdb
suffix "dc=openstack,dc=org"
rootdn "cn=admin,dc=openstack,dc=org"
rootpw {SSHA}PNof4WRW8ckd7bWQRfof1CVmgeQ14B09
directory /var/lib/ldap
|
- 今回は slapd.conf で設定したため、slapd.d はどけておく必要があります。
mv /etc/ldap/slapd.d /etc/ldap/__slapd.d~orig
|
schema修正
- Keystone+LDAPが必要としている項目 enabled をスキーマに追加します。
- 編集対象が core.schema なのが心苦しいですが、仕方ありません。
- (参考)Re: [Keystone] Creating tenant failed when using ldap as identity backend: ‘attribute type undefined’
/etc/ldap/schema/core.schema
# 追加 360行目あたり
attributetype ( 2.5.4.66 NAME ‘enabled‘
DESC ‘RFC2256: enabled of a group‘
EQUALITY booleanMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.7
SINGLE-VALUE )
# 変更 443行目あたり
objectclass ( 2.5.6.9 NAME ‘groupOfNames‘
DESC ‘RFC2256: a group of names (DNs)‘
SUP top STRUCTURAL
MUST ( member $ cn )
MAY ( businessCategory $ seeAlso $ owner $ ou $ o $ description $ enabled ) )
# MAY ( businessCategory $ seeAlso $ owner $ ou $ o $ description ) )
|
DB_CONFIG
- これは好みで設定しておきます。
/var/lib/ldap/DB_CONFIG
set_cachesize 0 268435456 2
set_flags DB_TXN_NOSYNC
set_lg_regionmax 20971520
set_lg_max 10485760
set_lg_bsize 524288
set_lk_max_objects 5000
set_lk_max_locks 5000
set_lk_max_lockers 5000
|
- 設定したら再起動します。
/etc/init.d/slapd restart
|
LDAPに基本データを入れる
- 必要な ou を入れます。
- domains はGrizzlyから必要になっています。
- 全て同じ階層に作成していますが、users だけ別の階層にしたりしても、問題なく動作します。
usersのみ既存データを想定しているので、実際は、わかりやすくするためにusers以外は1つdc階層を下げました
suffix を別にすることは slapd において可能ではありますが、1つのLAMで管理できなくなるので不採用にしています
/etc/keystone/openstack.ldif
dn: ou=groups,dc=openstack,dc=org
objectClass: top
objectClass: organizationalUnit
ou: groups
dn: ou=users,dc=openstack,dc=org
objectClass: top
objectClass: organizationalUnit
ou: users
dn: ou=roles,dc=openstack,dc=org
objectClass: top
objectClass: organizationalUnit
ou: roles
dn: ou=machines,dc=openstack,dc=org
objectClass: top
objectClass: organizationalUnit
ou: machines
dn: ou=domains,dc=openstack,dc=org
objectClass: top
objectClass: organizationalUnit
ou: domains
|
- LDIFを作成したら、追加します。
ldapadd -h localhost -x -D "cn=admin,dc=openstack,dc=org" -W -f /etc/keystone/openstack.ldif
# データの確認slapcat | lessldapsearch -x -LLL -h localhost -p 389 -b dc=openstack,dc=org | less
|
LAM (LDAP Account Manager) のインストール
パッケージ
apt-get install ldap-account-manager cronolog
|
設定
- 管理ユーザ や OU を編集します。
/var/lib/ldap-account-manager/config/lam.conf
# slapdの管理ユーザ
serverURL: ldap://localhost:389
admins: cn=admin,dc=openstack,dc=org
passwd: {SSHA}PNof4WRW8ckd7bWQRfof1CVmgeQ14B09
treesuffix: dc=openstack,dc=org
# 表示言語
defaultLanguage: ja_JP.utf8:UTF-8:日本語 (日本)
# ユーザ/グループIDの最小値変更してみたり
modules: posixAccount_minUID: 5000
modules: posixGroup_minGID: 5000
# 基本OUのsuffixを変更
types: suffix_user: ou=users,dc=openstack,dc=org
types: suffix_group: ou=groups,dc=openstack,dc=org
types: suffix_host: ou=machines,dc=openstack,dc=org
types: suffix_smbDomain: dc=openstack,dc=org
|
Apacheの設定
- ログ排除条件を指定して、
/etc/apache2/conf.d/logenv.conf
SetEnvIf Request_URI \.(gif|jpg|png|js|css|ida|exe)$ no_log
|
- 元のサイト設定を削除して
rm /etc/apache2/conf.d/ldap-account-manager
|
- VirtualHostでちゃんと指定しておきます。(※プライベートDNSに追加できれば)
/etc/apache2/sites-available/lam
<VirtualHost *:80>
ServerName ldap.openstack.org
CustomLog "|/usr/bin/cronolog /var/log/apache2/lam/access/%Y%m/%Y%m.log" combined env=!no_log
ErrorLog "|/usr/bin/cronolog /var/log/apache2/lam/error/%Y%m/%Y%m.log"
Alias /lam /usr/share/ldap-account-manager
<Directory /usr/share/ldap-account-manager>
Options +FollowSymLinks
AllowOverride All
Order allow,deny
Allow from all
DirectoryIndex index.html
</Directory>
<Directory /var/lib/ldap-account-manager/tmp>
Options -Indexes
</Directory>
<Directory /var/lib/ldap-account-manager/tmp/internal>
Options -Indexes
Order allow,deny
Deny from all
</Directory>
<Directory /var/lib/ldap-account-manager/sess>
Options -Indexes
Order allow,deny
Deny from all
</Directory>
<Directory /var/lib/ldap-account-manager/config>
Options -Indexes
Order allow,deny
Deny from all
</Directory>
<Directory /usr/share/ldap-account-manager/lib>
Options -Indexes
Order allow,deny
Deny from all
</Directory>
<Directory /usr/share/ldap-account-manager/help>
Options -Indexes
Order allow,deny
Deny from all
</Directory>
<Directory /usr/share/ldap-account-manager/locale>
Options -Indexes
Order allow,deny
Deny from all
</Directory>
</VirtualHost>
|
- 他、security系とか好みで編集したら、
- 設定を有効にしてリロードします。
a2ensite lamapache2ctl configtest/etc/init.d/apache2 reload
|
LAMでデータ作成
- LAMにアクセスしてみます。
- http://ldap.openstack.org/lam/
- LAMでOpenStack管理ユーザと、一般ユーザのグループ/ユーザを作成しておきます。
- openstack:10000 グループを作る
- OpenStackAdmin:10000、パスワード:root、openstackグループ所属、業種:default でユーザを作る
- member:10001、パスワード:member、openstackグループ所属、業種:default でユーザを作る
『業種』は businessCategory の項目となっています
既存ユーザデータに小文字の admin を混ぜるのが嫌だったので OpenStackAdmin を管理者にしています
- さらにLAMでdefaultドメインを作成しておきます。
- domains の子エントリを作成
- デフォルト -> groupOfNames
- RDN:cn, cn=default, member:uid=OpenStackAdmin,ou=users,dc=openstack,dc=org
usersデータの businessCategory と紐付いたデータです
お互いの default が一致していないとアカウントは有効になりません
keystone連携
設定
- keystone.conf をLDAP仕様に変更します。
- 設定は関連部のみ、それとメモを書いておきます。
/etc/keystone/keystone.conf
[identity]
driver = keystone.identity.backends.ldap.Identity
[ldap]
url = ldap://192.168.0.11
user = cn=admin,dc=openstack,dc=org
password = rootpass
#user = uid=OpenStackAdmin,ou=users,dc=drecom,dc=co,dc=jp
#password = adminpass
suffix = dc=openstack,dc=org
use_dumb_member = True
dumb_member = cn=dumb,dc=nonexistent
allow_subtree_delete = False
query_scope = one
page_size = 0
alias_dereferencing = default
user_tree_dn = ou=users,dc=openstack,dc=org
user_objectclass = inetOrgPerson
user_filter =
user_id_attribute = uid
user_name_attribute = cn
user_mail_attribute = mail
user_pass_attribute = userPassword
user_domain_id_attribute = businessCategory
user_enabled_attribute = enabled
user_enabled_mask = 0
user_enabled_default = True
user_attribute_ignore = tenant_id,tenants
user_allow_create = False
user_allow_update = False
user_allow_delete = False
user_enabled_emulation = False
user_enabled_emulation_dn =
tenant_tree_dn = ou=groups,dc=openstack,dc=org
tenant_objectclass = groupOfNames
tenant_filter =
tenant_id_attribute = cn
tenant_name_attribute = ou
tenant_member_attribute = member
tenant_desc_attribute = description
tenant_enabled_attribute = enabled
tenant_domain_id_attribute = businessCategory
tenant_attribute_ignore =
tenant_allow_create = True
tenant_allow_update = True
tenant_allow_delete = True
tenant_enabled_emulation = False
tenant_enabled_emulation_dn =
role_tree_dn = ou=roles,dc=openstack,dc=org
role_objectclass = organizationalRole
role_filter =
role_id_attribute = cn
role_name_attribute = ou
role_member_attribute = roleOccupant
role_attribute_ignore =
role_allow_create = True
role_allow_update = True
role_allow_delete = True
domain_tree_dn = ou=domains,dc=openstack,dc=org
domain_filter =
domain_objectclass = groupOfNames
domain_id_attribute = cn
domain_name_attribute = ou
domain_member_attribute = member
domain_desc_attribute = description
domain_enabled_attribute = enabled
domain_attribute_ignore =
domain_allow_create = True
domain_allow_update = True
domain_allow_delete = True
domain_enabled_emulation = False
domain_enabled_emulation_dn =
|
- 編集したら再起動します。
/etc/init.d/keystone restart
|
メモ
- LDAPの管理者権限は、プロジェクトやロール操作をする時だけ記述して、通常時はOpenStack管理者ユーザにでもして読み込み権限だけにしておく(ポリシー次第)
- user_objectclass = person にしたら内部でobjectClassがperson,personで重複してエラーになる
- Grizzlyでは description の値のデフォが desc になっているので明示的に設定する
- use_dumb_member = True でないと tenant-create ができないので dumb_member とともに設定する
- dumb_member は roleOccupant に仮で入るデータなので値はなんでもよい
- user_name_attribute は cn が理想だが、日本語だと取得の際にエラーになるので、その場合は uid にでもする
- user_enabled_attribute のために enabled を core.schema に入れたが、入れずに済む方法を探しても、他にちょうどよいboolean型が無いため無理っぽかった
- domain関連はGrizzlyから必要になった
データ追加
- プロジェクトなど最初必要なものを追加していきます。
- 初めて追加する時は、LAMのツリービューを見ながらやるとデータの所在がわかってよいです。
プロジェクト(ou=groups)
TENANT_NAME=admin
keystone tenant-create --name=$TENANT_NAMEkeystone tenant-list
|
ユーザ(ou=users)
- 外道運用ルールでは keystone user-create はせず、LAM上での作成とするため実際にはコマンドは不要ですが、動作確認のために書いておきます。
- LAMでは businessCategory : default 属性の追加が必要。LAMの表示上は”業種”
USER_NAME=OpenStackAdmin
keystone user-create \ --tenant-id $(keystone tenant-list | grep " $TENANT_NAME " | awk ‘{print $2}‘) \ --name $USER_NAME --pass adminpass --email [email protected] --enabled truekeystone user-list
|
ロール(ou=roles)
- 管理者と一般ユーザ用のロールを追加しておきます。
- admin, KeystoneAdmin, KeystoneServiceAdmin はソース直書きの固定管理者用ロールです
- それ以外の一般ユーザが必要なので Member を作成しておきます
- policy.json はいったんそのままで、別記事で書きます
keystone role-create --name="admin"keystone role-create --name="KeystoneAdmin"keystone role-create --name="KeystoneServiceAdmin"keystone role-create --name="Member"keystone role-list
|
プロジェクト/ユーザ/ロールの関連付け(groupsのcnのさらに上にcnが作成される)
- 管理者ユーザを全ての固定管理ロールに入れておきます。
keystone user-role-add \ --tenant-id $(keystone tenant-list | grep " $TENANT_NAME " | awk ‘{print $2}‘) \ --user-id $(keystone user-list | grep " $USER_NAME " | awk ‘{print $2}‘) \ --role-id $(keystone role-list | grep " admin " | awk ‘{print $2}‘)
keystone user-role-add \ --tenant-id $(keystone tenant-list | grep " $TENANT_NAME " | awk ‘{print $2}‘) \ --user-id $(keystone user-list | grep " $USER_NAME " | awk ‘{print $2}‘) \ --role-id $(keystone role-list | grep " KeystoneAdmin " | awk ‘{print $2}‘)
keystone user-role-add \ --tenant-id $(keystone tenant-list | grep " $TENANT_NAME " | awk ‘{print $2}‘) \ --user-id $(keystone user-list | grep " $USER_NAME " | awk ‘{print $2}‘) \ --role-id $(keystone role-list | grep " KeystoneServiceAdmin" | awk ‘{print $2}‘)
|
データの確認
# 全データslapcat | less # 動作確認。取得できなかったら見直しcurl -d ‘{"auth": {"tenantName": "admin", "passwordCredentials":{"username": "OpenStackAdmin", "password": "rootpass" }}}‘ \ -H "Content-type:application/json" http://192.168.0.11:35357/v2.0/tokens \ | python -mjson.tool | less
|
テストプロジェクト追加
- 基本的に admin プロジェクトはネットワーク設定やスナップショット編集などをするためのものにして普段は放置し、2つ目以降のプロジェクトをガリガリ使うようにしています。
# プロジェクト追加TENANT_NAME=testkeystone tenant-create --name=$TENANT_NAME # ユーザ名定義だけ。実際の追加はLAMでUSER_NAME=member
# ユーザロールに追加ROLE_NAME=Member
keystone user-role-add \ --tenant-id $(keystone tenant-list | grep " $TENANT_NAME " | awk ‘{print $2}‘) \ --user-id $(keystone user-list | grep " $USER_NAME " | awk ‘{print $2}‘) \ --role-id $(keystone role-list | grep " $ROLE_NAME " | awk ‘{print $2}‘) # 確認keystone tenant-list
keystone user-list
curl -d ‘{"auth": {"tenantName": "test", "passwordCredentials":{"username": "member", "password": "memberpass" }}}‘ \ -H "Content-type:application/json" http://192.168.0.11:35357/v2.0/tokens \ | python -mjson.tool | less
|
ユーザ追加の際にグループ追加する手順
- LAMでユーザを追加したら、OpenStackでも認証できるように、手動で user-role のデータを追加する必要があります。
- ツリービューの ou=groups を選択
- testプロジェクトのcnを選択
- Memberロールのcnを選択
- roleOccupant にユーザの uid を追加
- LDAPのデータをKeystoneでも有効にするには、ユーザのbusinessCategoryにdefaultが入っていて、かつ、上記 user-role データが存在する必要があります。それ以外のユーザは OpenStack を触ることができない、ということです。
後片付け
- 色々終わったら、LDAPユーザを切り替えておきます。
- さきほども書きましたが、これはお好みで、私はできるだけLDAP管理者権限を撒き散らしたくないのでパスワードを消しておき、読み込みのみでKeystoneで利用するようにしています。
/etc/keystone/keystone.conf
[ldap]
url = ldap://192.168.0.11
#user = cn=admin,dc=openstack,dc=org
user = uid=OpenStackAdmin,ou=users,dc=openstack,dc=org
password = adminpass
|
- 編集したら再起動します。
/etc/init.d/keystone restart
|
- LDAPをそこそこ知らないと厳しい設定かもしれませんが、やってみると意外に悪くなく、特に問題なく運用できています。
- ただ、FolsomからGrizzlyにするとスキーマが変わって古いデータは使えなかったりしたので、その辺の対応は覚悟しておく必要がありそうです。
时间: 2024-08-12 04:51:34