Keystone+LDAP+LAMでOpenStack管理

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にするとスキーマが変わって古いデータは使えなかったりしたので、その辺の対応は覚悟しておく必要がありそうです。


你可能感兴趣的:(Keystone+LDAP+LAMでOpenStack管理)