ラベル ldap の投稿を表示しています。 すべての投稿を表示
ラベル ldap の投稿を表示しています。 すべての投稿を表示

2013/05/04

namecheapで購入したWildcardSSL証明書をOpenLDAPにインストールしてみた

これまで389ポートで運用してきたESXi 5.1上のOpenLDAPサーバにSSL証明書を適用してみました。

実際のところnamecheapは関係なくて、SSL証明書をどこで購入したのかは問題ではなくて、root CAや中間CA証明書の有無などが問題だったりします。

今回利用する証明書の構成や、対象サーバの環境は以下の通りです。

  • OS: Ubuntu 12.04 LTS 64bit版
  • SSL root CA Issuer: C=SE, O=AddTrust AB, OU=AddTrust External TTP Network, CN=AddTrust External CA Root
  • SSL Issuer: C=GB, ST=Greater Manchester, L=Salford, O=COMODO CA Limited, CN=PositiveSSL CA 2

最近は4階層のSSL証明書も普通にありますが、PositiveSSLの中間CA証明書は1つだけの3階層です。 4階層はテストしていませんが、c_rehashコマンドでハッシュファイルへのシンボリックリンクを作成するところを外さなければ、問題なく扱えるはずです。

ファイルの準備

SSL関連の操作ではファイル名は任意なのですが、扱うファイルの数は多い傾向があります。

まぎらわしいので参考のためにリストにしておきます。

  • WildcardSSL.crt: CN=*.example.com(Subject: OU=Domain Control Validated, OU=PositiveSSL Wildcard, CN=*.example.com)
  • PositiveSSLCA2.crt: 証明書 (Subject: C=GB, ST=Greater Manchester, L=Salford, O=COMODO CA Limited, CN=PositiveSSL CA 2)
  • AddTrustExternalCARoot.crt: CA証明書 (Subject: C=SE, O=AddTrust AB, OU=AddTrust External TTP Network, CN=AddTrust External CA Root)
  • newkey.nopass.pem: パスワードで保護されていないWildcardSSL.crtに対応する鍵ファイル
  • rootca.crt: PositiveSSLCA2.crt + AddTrustExternalCARoot.crtの2つのファイルが連結された単一CA証明書ファイル

*.crtファイルの内容は全て-----BEGIN CERTIFICATE-----で始まるので紛らわしいかと思います。 以下のコマンドで-inオプションの引数にファイルを指定すると中身を確認することができるので便利です。

$ openssl x509 -text -noout -in <cert filename>
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            6f:c7:b2:c6:af:e4:cc:a6:d3:61:4b:1f:6d:56:be:fd
    Signature Algorithm: sha1WithRSAEncryption
        Issuer: C=GB, ST=Greater Manchester, L=Salford, O=COMODO CA Limited, CN=PositiveSSL CA 2
        Validity
            Not Before: Dec 13 00:00:00 2012 GMT
            Not After : Dec 13 23:59:59 2014 GMT
...

newkey.nopass.pemファイルは-----BEGIN RSA PRIVATE KEY-----で始まるファイルで、パスワードで保護されていない形式です。

パスワードを外す方法はnewkey.pemがパスワードで保護された鍵ファイルだとして、$ openssl rsa < newkey.pem > newkey.nopass.pemのような要領で作成する事ができます。

ファイルの配置

準備したファイルをOpenLDAPサーバ上に配置していきます。

今回はUbuntuなのでシステムで準備している/etc/ssl/certs, /etc/ssl/privateがありますが、クライアント認証をするわけでもなくシステムデフォルトと一線を引いて管理するためにファイルの配置場所は別に準備します。

$ sudo mkdir -p /opt/openldap/ssl
$ sudo cp WildcardSSL.crt /opt/openldap/ssl
$ cat PositiveSSLCA2.crt AddTrustExternalCARoot.crt | sudo tee /opt/openldap/ssl/rootca.crt
$ sudo c_rehash /opt/openldap/ssl/
$ sudo chgrp openldap /opt/openldap/
$ sudo chmod 750 /opt/openldap/

ESXiサーバのシェルの場合などはc_rehashコマンドが準備されていない事もありますが、手動でのリンク管理は面倒なので利用しています。

うまくいくと、次のような内容の/etc/openldap/sslディレクトリが作成できてるはずです。

sudo $ sudo ls -l /opt/openldap/ssl
lrwxrwxrwx 1 root root   22 May  4 18:35 459f9267.0 -> WildcardSSL.crt
lrwxrwxrwx 1 root root   10 May  4 18:35 5f852f3e.0 -> rootca.crt
lrwxrwxrwx 1 root root   10 May  4 18:35 ed207a3e.0 -> rootca.crt
lrwxrwxrwx 1 root root   22 May  4 18:35 f8a2c70e.0 -> WildcardSSL.crt
-rw-r--r-- 1 root root 1679 May  4 18:27 newkey.nopass.pem
-rw-r--r-- 1 root root 3278 May  4 18:34 rootca.crt
-rw-r--r-- 1 root root 1801 May  4 18:09 WildcardSSL.crt

設定ファイルの変更

必要なファイルを配置したら、Openldapの設定ファイルの変更です。

Ubuntu 12.04 LTSでのopenldapの設定ファイルは/etc/ldap/slapd.d以下でLDAP管理となっています。 そのためファイルを編集するという分けにはいきません。

設定方法は、help.ubuntu.comのOpenLDAP TLS設定方法のページに詳しく掲載されています。

このページに書かれているように、LDIFファイル(/tmp/modify.tls.ldif)を作成してldapmodifyコマンドで実行していきます。

/tmp/modify.tls.ldifファイルの内容

dn: cn=config
add: olcTLSCACertificateFile
olcTLSCACertificateFile: /opt/openldap/ssl/rootca.crt
-
add: olcTLSCertificateFile
olcTLSCertificateFile: /opt/openldap/ssl/WildcardSSL.crt
-
add: olcTLSCertificateKeyFile
olcTLSCertificateKeyFile: /opt/openldap/ssl/newkey.nopass.pem
$ sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f /tmp/modify.tls.ldif
/etc/default/slapdの編集

slapdがサポートするプロトコルを指定する行に、ldaps:///を追加します。

/etc/default/slapdの変更個所抜粋

...
SLAPD_SERVICES="ldap:/// ldaps:/// ldapi:///"
...
APPARMOR対応

標準となっている/etc/ssl/ディレクトリ以下にアクセスする事がapparmorによって拒否されるため、今回はディレクトリを/etc/apparmor.d/local/usr.sbin.slapdに追加しました。

/etc/apparmor.d/local/usr.sbin.slapdファイルの内容

# Site-specific additions and overrides for usr.sbin.slapd.
# For more details, please see /etc/apparmor.d/local/README.

/opt/openldap/ r,
/opt/openldap/** r,

dh_apparmorパッケージをインストールしたのですが、うまく動かないのでシステム全体を再起動します。

$ sudo /sbin/shutdown -r now

稼働確認

ポートの確認

netstatで636ポートが開いている事を確認します。

$ netstat -nl | egrep '389|636' 
tcp        0      0 0.0.0.0:636             0.0.0.0:*               LISTEN     
tcp        0      0 0.0.0.0:389             0.0.0.0:*               LISTEN     
tcp6       0      0 :::636                  :::*                    LISTEN     
tcp6       0      0 :::389                  :::*                    LISTEN
ldapsによるクエリの実行

実際のクエリはDNなどを含むので、slapdumpなどでディレクトリの構造を把握しておく事が必要です。

$ openldap -x -H ldaps://openldap.example.com:636/ -b uid=user01,ou=People,dc=example,dc=com

もしホスト名をopenldap.example.comではなくlocalhostのように指定した場合には、SSLのCommonName(CN)に指定されているホスト名(*.example.com)との対応が取れずにエラーとなります。

$ ldapsearch -x -H ldaps://localhost:636/ -b uid=user01,ou=People,dc=example,dc=com
ldap_sasl_bind(SIMPLE): Can't contact LDAP server (-1)

localhostの部分をlocalhost.example.comのようにCNと対応するFQDNにすれば、正常に稼働します。

$ ldapsearch -x -H ldaps://localhost.example.com:636/ -b uid=user01,ou=People,dc=example,dc=com
# extended LDIF
#
# LDAPv3
...

まとめ

WildcardSSL証明書はけっこう便利です。 PDFファイルの署名にも論理的には使えますが、CA情報が登録されていないので適切な署名とはみてもらえません。

SSL接続時に警告が出るのはマルウェアなどでサイト誘導されているという認識を持たないと、まったく意味がないのですが、残念ながら世間では、この悪い常識が闊歩しているところもあります。

仕事など、責任を伴なう場面では、積極的にSSL化を勧めて環境を整備しましょう。

2013/02/06

OpenLDAPを導入したので、各OSでの設定方法をまとめてみる

UbuntuにOpenLDAPを導入して、ldap-account-manager (LAM)で管理しています。

VirtualBOXを使った時のOSへのログインユーザーの管理や、ミドルウェアを稼働させるユーザーの管理をOpenLDAPに一元化したいと思ったので、VMとして使っている主なOSでのldap設定をまとめました。

前提知識

LDAPの設定は様々なミドルウェアで行なえますが、微妙に設定できる名称や設定方法が異なります。

共通部分としてはサーバー名、ポート番号の他にバインドDN(とそのパスワード)、BaseDNなどがあります。

製品によってはユーザー名を構成するサブディレクトリ(ou=People等)の指定ができるものがあります。

また階層を辿るために、base,one,subなどのスコープを設定できるものもあります。 何も設定されていないOpenLDAPは自由に階層を辿る事ができるため、全部のディレクトリ情報を表示する事も可能な事が多く、サンプルもそのように構成されている場合があります。

しかし実際には、ディレクトリ全体を辿られてしまうと社員名とID,e-Mailアドレスとの紐付けなどをごっそり持っていかれる可能性があるため、自分自身のディレクトリ情報以外は編集ができず、それ以外の情報はDNで直に指定しないと閲覧できないように設定されている場合もあるでしょう。

LDAPについての設定方法は標準的な部分と、非標準的な暗黙知によって構成されています。 ActiveDirectoryを前提にしていると、Netscapeに由来するようなDirectory構成

ldapserverldapbasednに指定するサーバー名やBaseDN名は適宜変更してください。

CentOSなど(RedHat系)でのldapログイン設定

以前のブログでも書いていますが、コマンドラインから設定する事が可能です。

 $ sudo authconfig --enableldap --enableldapauth --ldapserver=openldap.example.org --ldapbasedn="ou=accounts,dc=example,dc=org" --updateall

これはCentOS 5.4で試した設定方法ですが、CentOS 6.3でも同様に使えます。

Ubuntuでのldapログイン設定

UbuntuではガイドのLDAPClientAuthenticationにあるように2つのコマンドを実行することでLDAPを設定する事になっています。

 $ sudo apt-get install ldap-auth-client nscd
$ sudo auth-client-config -t nss -p lac_ldap

Ubuntu 12.04 LTSで確認したところ次のようなログインできない問題が発生しました。

  • ログインできず、/var/log/auth.logに次のようなメッセージが表示される pam_ldap: could not open secret file /etc/ldap.secret (No such file or directory)
  • $ getent passwdではUserが表示されるのに、ログインできない
存在しない/etc/ldap.secretの問題

前者の/etc/ldap.secretを要求するのは、/etc/ldap.confでrootbinddnを有効にしているからです。

auth-client-configの設定画面で、クライアントからのパスワード変更を許していないので適当なrootbinddnと空のパスワードを入力したのが原因でした。

/etc/ldap.confからrootbinddn行の先頭に#をつけてコメントにする事で解決しました。

user名は認識されるのにログインできない

単純にnscdがリスタートされていないだけでした。

プロセスを再起動:$ sudo /etc/init.d/nscd restart して、無事にログイン($ ssh user1@example.org)する事ができました。

Debian 6.0.3でのldapログイン設定

DebianにはUbuntuにあったldap-auth-clientパッケージが存在しません。 そのためlibpam-ldap, libnss-ldapを手動で導入します。

$ sudo apt-get install libpam-ldap libnss-ldap
/etc/libnss-ldap.conf, /etc/pam_ldap.confファイルの確認

それぞれアンダースコア'_'やハイフン'-'が入っていてまぎらわしですが、この2つのファイルの内容を念のため確認します。

Ubuntuでの経験を活かして、rootbinddnやパスワードへは空文字列を入力してみましたが、libnss-ldap.confではrootbinddnが何も指定されないまま有効になっていました。

パスワード変更にはOSの機能を使わない事にしているので、今回もrootbinddn行はコメントアウトします。

面倒であれば、apt-getの実行時にadminのDNとパスワードを入力する事で、編集なしで良くなるはずです。

最後に/etc/nsswitch.confを有効にする

nsswitch.confなんて昔のBSD系やLinux OSにはなかったんですけどね…。Solaris 2.2か2.4ぐらいを触った時の衝撃といったらありませんでした…。

他のOSと同様にnsswitch.confのpasswd, group行のcompatfiles ldapに変更すれば完了です。

nscdのリスタート

ここまでで、LDAPに登録したIDにsu -の実行やログインができない場合には、nscdをリスタートしてみてください。

$ sudo /etc/init.d/nscd restart

基本的にはこれで完了するはずです。

FreeBSD 9.1でのldapログイン設定

基本的な流れはガイドのLDAP Authenticationの中にあります。 導入が必要なPortsは以下の通りです。

  • net/nss_ldap
  • security/pam_ldap

自動的に両方のPortsが依存しているnet/openldap24-clientも導入されます。

Portsのインストール(# make install)が完了したら、以下のように3つのファイルを編集するとLDAP認証が有効になります。

/usr/local/etc/nss_ldap.confの設定

基本的にはurlかhost,それにbaseを設定すれば動きますが、使っているLDAPサーバーのディレクトリ構成やサーバー自体の設定によっては必要な追加設定があるかもしれません。

/etc/pam.d/loginの編集

sshd経由でのログインも行なうのであれば、/etc/pam.d/sshdの設定も変更する必要があるはずです。

サンプルはガイドにあるので詳細は省きますが、auth sufficient /usr/local/lib/pam_ldap.so no_warnの設定を入れれば完了です。

/etc/nsswitch.confの編集

ここまでの設定が完了していて、/etc/nsswitch.confファイルのgroup行とpasswd行をcompatからfiles ldapに変更すればログインにldapが使われるようになります。

さいごに

LDAP認証ではBindDNやらAdminDNやらRootBindDNやら、似たようなものや、実質同じものが名前をかえて登場します。

LDAPサーバーの動きをちゃんと捉えるのは面倒ですが、いまならLPI-Japanが無償で配布している高信頼システム構築標準教科書やLPIC Level 3の教本なんかが、良いとっかかりになるはずです。

動きから抑えるのが良いのですが、普段はシステムの裏側にいて、簡単にldapsearchが試せる本番環境というのもあまりありません。

ネットワーク屋さんがルーター管理にRADIUSを動かしても特権用の共有IDなんかをファイルベースで作って終りだったり、本来はLDAPを使うべき場面なのに、他の方法で代用されている場合もあるかもしれないですね。

会社や学校でLDAPサーバーがあっても、それがLDAPサーバーだと気がつかない場合があるかもしれませんし、アクセス制御が厳密でなかなか挙動をリバースエンジニアリングするのは難しい場合もあるかもしれません。

なんにしてもLDAPサーバーを試す環境はいまのところ自分で動かすしかないので、単純にサーバーと管理ツールを入れて終りにしないで、高可用性を保つために何が必要か、よりセキュアな環境にするためには何ができるのか、考えてみると良いでしょう。

2012/12/09

RacktablesでLDAP認証をかける時の注意点

Racktablesは簡単に導入ができて、ビジュアル的にもそこそこ見栄えが良く、ネットワーク屋さんがexcelやvisioを使って書くであろう絵の基本的な部分はカバーできるツールではないでしょうか。

PHPベースなので、あいかわらず拡張性が良いとは思えませんが、とりあえず動いているので使ってみる事にしました。

今回は不特定多数で使用する前提で、Ubuntu上で稼働するopenldapを使ったLDAP認証と連携させる事にしました。

racktablesのadminユーザーで、承認するユーザー名を個別に設定する場合には難しい点はないのですが、グループで認証しようとする場合には、Active Directory(AD)が想定されているので、Openldap用に少しだけ変更してあげる必要があります。

基本的なopenldapの設定

今回は手間をかけないために、ldap-account-manager (LAM)を併用しています。

LAMをUbuntuで使う場合は、openldapがデフォルトでドメイン名をみて基本的なディレクトリを作成しています。 sudo slapcatなどで確認して、変更したい場合には、$ sudo dpkg-reconfigure slapdなどで自分の管理するドメイン(dc=example,dc=com)を設定します。

racktablesの導入

ポイントはだいたい次のようなところでしょうか。

  • mysqlをあらかじめ導入しておく
  • wwwrootディレクトリをScriptAliasに設定するなどし、Webサーバーの実行ユーザーには読取権限だけを与えておく
  • inc/secret.phpファイルをWebサーバーの実行ユーザーに書き換えられるよう権限を変更する ($ sudo chown www-data:www-data wwwroot)
  • http://localhost/racktables/など配置した場所に応じたパスの/install.phpにアクセスし、インストール作業を終える

PHPが参照するファイルはWebサーバーのアクセス制限には縛られないので、secert.phpはシンボリックリンクなどにして、Webサーバーの設定としてはシンボリックリンク参照を無効にしておくのがお勧めです。

racktablesにLDAP認証を設定する

inc/secret.phpファイルに既に入っている雛型だけで、LDAP認証は十分です。 domain行は使わないのでコメントのまま無効にしておきます。

だいたい次のようなコードになっています。

secret.phpファイルの内容抜粋


$user_auth_src = 'ldap';
$require_local_account = FALSE;
$LDAP_options = array
(
        'server' => 'localhost',
#       'domain' => 'example.com',
        'search_attr' => 'uid',
        'search_dn' => 'ou=People,dc=x200,dc=example,dc=com',
# // The following credentials will be used when searching for the user's DN:
#       'search_bind_rdn' => NULL,
#       'search_bind_password' => NULL,
        'displayname_attrs' => 'sn',
        'group_attr' => 'gidnumber',
        'group_filter' => '/^([0-9]+)$/',
        'options' => array (LDAP_OPT_PROTOCOL_VERSION => 3),
#       'use_tls' => 2,         // 0 == don't attempt, 1 == attempt, 2 == require
);

group_attrは基本がAD認証なので、posixAccountで定義されているgidNumberをキーにすると、group_attrに対応するgroup_filterも書き直す必要があります。

PHPのldapsearchのマニュアルをみると、ldapsearchは大文字、小文字を意識しないけれど、戻り値として返される配列のキーは小文字になる記述があります。

そのためgroup_attrに指定する文字列は小文字でなければいけません。

また、group_filterの設定は数字が期待されているので、ここでは全ての数字を許可していますが、ドメインのポリシーに従って、10000番台だけを許可するような設定がここで可能です。

racktablesでのauthorization設定

認証されたユーザーがracktablesにアクセスできるかどうかは、Configurationのpermissions設定で行ないます。

Configuration -> Permissions設定


allow {$userid_1}
allow {lgcn_10000}

デバッグの方法について

secret.phpを編集してもうまく動かない場合、内部動作を確認する方法がないので、printfデバッグの手法を使います。 auth.phpファイルを編集する場合には、認証失敗画面に出力されるよう、$ret['memberof'][]に代入するのがお勧めです。

さいごに

ネットワーク管理用のアプリはいろんな形態が考えられますが、物理的なラックに着目した点で、ユニークなアプリなのかなと思っています。

認証済みユーザーに閲覧権限だけ付与するのに、default tabだけへのアクセスを許可するようなアプローチもできそうですが、それでは閲覧できない情報がいろいろあるので良い方法がないか探しています。

この手のアプリケーションをいろいろみていて、拡張性なんかが気になってしまいます。 mediawikiのWeb API的なアプローチが内部構造として採れないか、ちょっといろいろ考えています。

2009/11/01

OpenLDAP: access権限の管理

olcAccessディレクティブの管理

slapd.confに代ってslapd.dを使っていると、Access権限(olcAccess)の管理が少しだけ面倒に思えてきます。 それはslapd.confのようにテキストエディタで古いものを削って、新しく付け足すわけではないから。

例えば最上位DNからの一括検索を拒否しつつ、パスワード情報は認証時以外には開示しない設定だとします。 slapd.dディレクトリの中で、アクセス権限は次のように管理されています。

olcAccess: {0}to dn.base="dc=example,dc=org" by * none
olcAccess: {1}to attrs="userPassword" by anonymous auth by * none
olcAccess: {2}to dn.children="dc=example,dc=org" by self read

この状態で下記のldifファイル(update.ldif)に対してldapmodifyを実行したとします。

dn: olcDatabase={1}bdb,cn=config
changetype: modify
replace: olcAccess
olcAccess: to dn.base="dc=example,dc=org" by * read
$ ldapmodify -x -W -D cn=admin,cn=config -f update.ldif

適当なところが一行置き換わるのかなと思いきや、3行だったolcAccessが1行に変更されています。

olcAccess: {0}to dn.base="dc=example,dc=org" by * read

不思議なことは何もないのですが、管理をする上では挙動をチェックして把握しておくのが重要だったりします。

管理用に何かWebベースやGUIなソフトウェアを使うかもしれません。 cn=config以下ならデータサイズが限られているので良いのですが、 データ件数が多いエントリをGUIなどのツールで開く時には、hard limitsに逹っするまでのサーバー側の負荷はもちろんですが、多くのエントリ情報を格納するツール側もそれなりのメモリを消費するためハングアップに気をつける必要があります。

台帳的な管理の手法

既に定義されているolcAccessの間に定義を挿入するというのは、少し面倒そうなので、簡単なシェルスクリプトを作成しました。

ツールは主に2つのパートから成ります。

  1. show_olcAccess.sh: 定義済みolcAccessエントリの確認ツール
  2. gen_access_ldif.sh: 一括登録、削除、更新用のldif生成ツール

どういう風に使えば便利そうかを想定すると…

$ ./show_olcAccess.sh > current.ldif ## olcAccessの行だけをcurrent.ldifに書き出す
$ vi current.ldif ## 追加したいolcAccess行を追加する
$ ./gen_access_ldif.sh < current.ldif | ldapmodify -x -W -D cn=admin,cn=config
## 最後は一気にldif形式のフォーマットを出力してldapmodifyに流し込む

show_olcAccess.sh: 定義済みolcAccessエントリの確認ツール

とりあえずは、"olcDatabase={1}bdb,cn=config"を決め打ちにしてolcAccessの各行を出力するようにします。

#!/bin/bash
ldapsearch -LLL -x -s base -W -D "cn=admin,cn=config" -b "olcDatabase={1}bdb,cn=config" olcAccess | while read line
do
  if /bin/echo -E "$line"|egrep ^olcAccess >/dev/null 2>&1 ; then
    l="$(/bin/echo -E "$line" | sed 's/{[0-9]*}//')"
    echo -E "$l"
  fi
done

これを実行すると次のような表示になります。

$ ./show_olcAccess.sh
olcAccess: to dn.base="dc=example,dc=org" by * none
olcAccess: to attrs="userPassword" by anonymous auth by * none
olcAccess: to dn.children="ou=accounts,dc=example,dc=org" by users read

わざわざ"olcAccess: {0}to"にある"{0}"の部分を取り去っているのは、後から編集する時に邪魔になるからです。 みるだけなら良いのですが、olcAccessを間に1行追加するのに、数字を全部後ろにずらしていくのは不毛でしょう。

gen_access_ldif.sh: 一括登録、削除、更新用のldif生成ツール

次はさきほど1行追加するのに使ったような"changetype: modify"を含むldapmodify用のLDIFファイルを生成します。

#!/bin/bash
db=${1:-"{1}bdb"}
opt="${2:-replace}"
## show header
echo "dn: olcDatabase=$db,cn=config"
echo "changetype: modify"
echo "$opt: olcAccess"
while read line
do
  echo -E "$line"
done

これを実行すると、LDIFファイルを出力します。 入力は”show_olcAccess.sh”で出力されたようなものです。

./gen_access_ldif.sh < access.ldif
dn: olcDatabase={1}bdb,cn=config
changetype: modify
replace: olcAccess
olcAccess: to dn.base="dc=example,dc=org" by * none
olcAccess: to attrs="userPassword" by anonymous auth by self read by * none
olcAccess: to dn.children="ou=accounts,dc=example,dc=org" by users read

もし既存の設定を消したければ、./gen_access_ldif.sh "" delete < access.ldif でできます。 複数のDBがあれば、第一引数に./gen_access_ldif.sh {2}hdbのように指定する事もできます。 次は、olcSuffixとolcDatabaseとの関連を一覧にできれば便利かなぁ。

まとめ

こういうスクリプトって本質的なものじゃないんですけれど、テンプレート+αな操作の場合は準備しておくと、 誰かに頼むとか、手順で置いておかなきゃいけない時に、作業が簡潔になり早くできたりして便利です。

ldapmodifyを実行する部分もスクリプトにしても良いですが、そこは本質的なところではないので。 また、これ以上作り込んでしまうと、トラブルシュートができない。

スクリプト化は勉強にならない、という批判もありそうですが、本物のマニュアル手順を"plan B"として載せておけば良いでしょう。

スクリプトの中で特殊な事はしていませんが、"$1"が未定義の場合に"{1}bdb"をセットするところはダブルクォートなしに書くと、そのまま展開されてしまいます。 ${1:-{1\}bdb}でも良さそうだけれど、ここら辺のドキュメントって見た事ないなぁ。

2009/10/29

LPIC Level3 301 Coreの試験を終えて

無事に試験を終えましたが、途中退室したり体調を崩してしまいました。 試験と名のつくものは苦手ですが、今回もみごとにやられました。 まだ胃の辺りがピクピクしています。

さて、結果はギリギリ合格でしたが、試験前の同意書には試験の具体的な内容について議論しない旨の一筆があり、試験問題について直接的なこと、どんな問題がでた、とかは言えない事になっています。

試験の印象

今回はEnglishのボタンを押す回数は少なくて、2,3回ぐらいでした。 理解できなくはないけれど、直訳っぽくて念のために見たというぐらい。
あとは問題文の意図を理解したり選択肢を選ぶために、実践経験の有無が明暗を分けると思います。

試験についてはこれぐらい。 実戦経験の豊富な人はうかるし、問題集の解説を暗記したような人はうからない。そんな試験でした。

ギリギリだったから偉そうな事はなにも言えない。 いったい自分は受かるべくして受かったのだろうか、いやそうじゃないよなぁ…。

2009/10/28

LDAP認証:CentOSでやってはいけない設定

CentOS 5.3, 5.4で試したのですが、nsswitch.confに以下の設定を入れてしまうと、事実上起動途中でシステムがハングアップしてしまいます。

group:          ldap files

"ldap"に登録されていない情報をローカルに見に行くというところが原因で、パフォーマンスの観点からもお勧めはできない設定です。

ただUbuntuでは、この設定でLDAPサーバーに接続できないエラーが大量に出力されますが、無事に起動します。 CentOSでは"bind_policy soft"にするとUbuntuと同じような挙動になり、起動はできるようになりました。Ubuntuはデフォルトの"bind_policy hard"で動くんですけどね…。

とりあえず復旧するためには、CentOSのインストールDVDから起動してboot:に続いてlinux rescueと打って復旧モードで起動してnsswitch.confファイルを元に戻すのがお勧めです。

インストールDVDを使わなくてもシングルユーザーモードで起動するようにして、udevの初期化途中でC-cを何回か連打すればシェルに落ちると思いますが、ファイルシステム壊しそうでお勧めできないですね。

Ubuntuで挙動が違う原因はlibnss-ldapのdebパッケージに適用されているパッチにあるようです。 リトライ回数などが変更されているので、おそらくその影響でしょう。これだとCentOSも時間をかければ起動しそうですが、一回つまずく毎に相当待たされるので確認するのは辞めておきます。

2009/10/27

LPIC Level3対策の勉強を引き続き

とりあえずOpenLDAPに触ったところは良いとして、いろいろ資料を漁っていたところLPI-Japanのページに辿り着きました。[参考資料ダウンロード]

その中にあった小田切さんの301対策セミナー資料の中に「TLSを使おう(SSLじゃないんだよ)」と書かれていて、SSLじゃない、という部分に「ああぁ、そうか、そうですね」とおもわずつぶやきました。

他にも資料が少ないから、Webの資料を鵜呑みにするなとか、いろいろ書かれてあって「ですよね〜」と同意せざるを得ません。そういう視点でみたらここにまとめた事は危険な香りがします…。

今度ちゃんとまとめなおそう。

2009/10/25

Ubuntu, CentOS管理コマンドに触れて思う事

LDAP認証の設定を終えて

2つのDistributionでは、そのデフォルト設定などが違うために、同じコードを使っていても、その設定方法やポリシーには違いがあります。Ubuntuでは”auth-client-config"コマンド、CentOSでは"authconfig"コマンドを使って、nsswitch.confやpam.d/以下のファイル群を操作します。

Ubuntuでは/etc/ldap.confは$ sudo dpkg-reconfigure ldap-auth-configで再設定はできて、"nss_base_passwd"などの手動で設定した項目はそのまま残っています。

CentOSでも/etc/ldap.confの状況は同じで、"authconfig"コマンドで設定できます。 authinfo.pyの中では条件にあった行だけを書き換えていて、手動で設定が必要な部分についてはやはり残す仕組みになっています。

何のためのツール群か

こういう管理ツールは必要なのか、時々疑問に思う事があります。 サポートのコストを軽減させたり、ファイルを直接編集する事で関係ないところまで無意識に書き換えてしまうといったケアレスミスの軽減に役に立つ場面はあると思います。

しかし実際には、その場しのぎのツールが生み出されて、そのバリエーションは多義に渡ります。 この分野ではUNIX系システムの特徴である”パイプ”や一つの処理を一つのコマンドに行なわせる簡潔さは継承されていないようです。

システム管理の自動化について考えると、AIXが持っている"ls*","mk*","ch*"系コマンドの一貫性はsmitの体系中で良く動いていると思います。 複雑なデバイスの管理になると崩れていく部分はありますが、それと比較してUbuntuやCentOSの持つ管理系コマンドの仕組みはpythonで書かれていたりして現代的で格好いいかもしれませんが、UNIX系の雰囲気は持っていません。

今後の予定

まだ認証の仕組みにSSLを使っていないので、現実的な応用を考えればLDAP認証やらレプリケーションやらにSSLまで設定をしてようやく最低限なのかなと思っています。

LPICの試験対策としては、まぁ必要ないところなので試験が終ってから、OpenLDAPを自宅LANに導入していこうと思います。まぁどんなOSを使ってもパッケージがhttpdグループやらを作ってくれるので、あらかじめUID, GIDを統一して準備しておく必要性は感じないですけどね。

ひょっとすると将来の仕事でLAN環境を作らなきゃかもしれないし、LDAPを使った応用については勉強しておこうと思っています。まぁ前の前の会社で散々やっていたけれど…。

OpenLDAP 2.4: CentOS 5.4でのLDAP認証設定

基本的にはUbuntuの時と同じで、バージョンは違うものの、使っている仕組みは同じなので /etc/ldap.conf をUbuntuからコピーしてきても動きます。

そこでCentOSで設定する時の注意点だけまとめます。

2009/10/24追記:
以下で説明している方法は、次のコマンドで代用できます。
$ sudo authconfig --enableldap --enableldapauth --ldapserver=10.0.0.2 --ldapbasedn="ou=accounts,dc=example,dc=org" --updateall

全体の流れ

CentOS 5.3のDVDから特にRPMを選択せずに導入し、yum updateで5.4相当にしています。 nss_ldapなどのモジュール類は既に入っているので、yumで取得する必要はありませんでした。

”/etc/ldap.conf"→"/etc/nsswitch.conf"→"/etc/pam.d/system-auth"と編集していくだけです。

/etc/pam.d/system-authの編集

"system-auth"ファイルはloginやsshdなどの設定からincludeされている、認証全般を管理するファイルです。 "pam_unix.so"が読み込まれている前に"sufficient pam_ldap.so"を追加していきます。

auth        required      pam_env.so
auth        sufficient    pam_ldap.so
auth        sufficient    pam_unix.so nullok try_first_pass
...
...
account     sufficient    pam_ldap.so
account     required      pam_unix.so
...

まとめ

実際のところPAMの設定で、最低限必要なのは”auth sufficient pam_ldap.so"ぐらいです。 accountセクションに"pam_ldap"を書かなくても、通常のログインに問題はありません。 まだ"shadowAccount"オブジェクトクラスの情報をLDAPに登録していないからです。

他にも”authorizedServiceObject”、"hostObject"オブジェクトクラスをユーザーIDに設定して、ldpa.confで"pam_check_service_attr yes"等を設定してチェックさせる事もできますが、OpenLDAPの標準的なschemaの中には含まれていませんね。

PAMの挙動を確認するためには、ある程度はソースコードの各定義を斜め読みするのが良さそうです。 ドキュメントから全ての動きを想像するのは、ちょっと難しいかもしれません。

さらに追記

CentOSでは"authconfig"コマンドがPAM, NSS等の各種サービスを設定してくれますが、細かいところまでは難しいようです。

system-authについてはsystem-auth-acへのシンボリックリンクになっていて、"authconfig"コマンドは実際にはsystem-auth-acファイルを編集します。そのためカスタマイズする場合にはsystem-authをファイルに置き換えて編集する事で、将来RPMが更新された際などに"authconfig"が実行されて編集内容をリセットしてしまう危険を回避する事ができます。

マニュアルに書いてあるとはいっても普通にファイルを編集してしまうと、意図しないタイミングで書き変わってしまう可能性があるので、そんな事件に遭遇すると嫌になるかもしれないですね…。

2009/10/24

OpenLDAP 2.4: Ubuntu 9.04クライアントでのログイン設定

さて作成した"e0001"ユーザーでログインするための設定をUbuntu 9.04に入れていきます。 Ubuntuは"ubuntu-9.04-server-amd64.iso"を使って、OpenSSH Serverが稼働している以外はデフォルトのままです。

モジュールの導入

Ubuntuを導入しただけでは、認証に必要なモジュールもldapsearchなどの確認用ユーティリティも準備されていないので必要なものを導入します。

$ sudo apt-get install libpam-ldap libnss-ldap ldap-utils

/etc/ldap.confの設定

ldap.confは複数あります。 OSが認証に使うものは/etc/ldap.conf、ldapsearchなどの標準的なユーティリティが参照するものは/etc/ldap/ldap.confといった具合です。 もしこの他にもLDAP接続を行なうコンポーネントを使えば、そのために別のldap.confに相当する設定を追加する必要がでてきます。

ログイン時のLDAP認証はPAM(Pluggable Authentication Modules)が行ないます。 ログイン時には参照されないUID, GID含めた/etc/passwd相当のユーザー情報の参照はNSS(Name Service Switch)が担当します。 /etc/ldap.confはこの二つのコンポーネントが共通に参照する事になっています。

libpam-ldapを導入する時にいくつか質問されldap.confに反映されますが、不十分なので後から修正が必要なようです。一応質問には次のように答えました。

  1. [入力] ldap://10.0.0.2:389/
  2. [入力] ou=accounts,dc=example,dc=org
  3. [入力] 3 (Ldap Version)
  4. [入力] no (local root database admin)
  5. [入力] no (LDAP database require login)

NSS用の設定を追加

足りない設定を修正していきます。 /etc/ldap.confでコメントアウトされている部分を修正します。

nss_base_passwd  ou=accounts,dc=example,dc=org?one
nss_base_shadow  ou=accoutns,dc=example,dc=org?one
nss_base_group  ou=groups,dc=example,dc=org?one

/etc/nsswitch.confの設定

ローカルに定義されていないアカウントはLDAPを参照します。

passwd:         files ldap
group:          files ldap
shadow:         files ldap

2009/10/26追記:
nsswitch.confについては、$ sudo auth-client-config -p lac_ldap -t nssで更新する事が可能です。

まとめ

一応、ここまでの設定で"e0001"ユーザーでログインする事ができます。 他に必要な設定として、/etc/pam.d/の下の"common-auth"、"common-account"で"sufficient pam_ldap.so"を"pam_unix.so"の手前に設定する必要があります。 この部分はUbuntuでは自動的にやってくれるようです。 もしファイルを手で修正していたりして、うまく追加されていない場合には確認する必要があるかもしれません。

後はローカルに/Users/e0001ディレクトリを作ったりしています。 実用的に使うにはまだまだ道程が長そうですが、確認という意味ではこんなものでしょうか。

OpenLDAP 2.4: 認証に使うIDの追加

UbuntuやCentOSにログインする時にLDAPを参照するようにしてみます。

通常はユーザーの情報の中に認証に使うエントリも追加するべきなのでしょうが、 実験用に別のコンテナを作成してIDを追加しました。

コンテナの追加

次のような内容の"add_account_group.ldif"を作成し、ldapaddで追加します。 $ ldapadd -x -W -D cn=Manager,dc=example,dc=org -f add_account_group.ldif

dn: ou=accounts,dc=example,dc=org
objectClass: organizationalUnit
ou: accounts

IDの追加

objectClassにはnis.schemaに定義されているposixAccountを使いました。 ここら辺の定義のベースになっているのは、rfc2307だと思います。

将来的にはautomountに関連した情報なども格納するような拡張が計画されているようで、rfc2307bisという文書もinternete-draftsの中から探す事ができます。 OpenLDAPに附属するschemaディレクトリには含まれていないようですが、389 DirectoryServer (a.k.a. Fedora Directory Server)には"10rfc2307bis.ldif"の名前で含まれています。

今回はログインするために必要な範囲の情報を入れていきます。 objectclassに指定している"inetOrgPerson"と"posixAccount"で必須とされているのは、それぞれ"cn sn"(PersonでMUST定義)と"cn uid uidNumber gidNumber homeDirectory"の6エントリです。

loginShellを追加して、次のような"add_user_e0001.ldif"を作成して、ou=accounts追加の時と同じように"-f"に指定します。 なおuserPasswordの文字列はslappasswdコマンドを使って生成しています。 $ slappasswd -h {SSHA} -s secretpassword

dn: cn=e0001,ou=accounts,dc=example,dc=org
objectclass: inetOrgPerson
objectclass: posixAccount
cn: e0001
sn: e0001 User
uid: e0001
uidNumber: 3001
gidNumber: 3001
homeDirectory: /Users/e0001
userPassword: {SSHA}gYeybCGMSjj+qIJd23CnNTYwBHK58gH6
loginShell: /bin/bash
mail: e0001@example.org

まとめ

とりあえずテスト用なので最小限のエントリを作成しましたが、実際にはポリシーを徹底させるためにshadowAccountオブジェクトクラスを使う必要もあるかもしれません。 それぐらいは固定的な値を設定すれば良いのかもしれませんが、パスワードを変更させるためにクライアントをマスターサーバーに直接接続させるのか、という考慮も必要に思えます。

複数マスター構成を取っても根本的な負荷分散は難しいので、マスターサーバーに対する更新処理はバッチ的に処理する仕組みが必要になるかもしれません。 ユーザーのエントリをログインID情報を保持する以外にもメールアドレスや、その他の情報を総合的に管理する時の台帳として使うのであれば、情報の更新などを複数のアプリから直接行なうと問題になりそうです。

また各クライアントからパスワードを変更させるために直接マスターサーバーにアクセスさせるのか、という根本的な構成について検討する必要もあるように思えます。

2009/10/21

OpenLDAP 2.4: 動的なスキーマの登録

bdbを使った時に消せなくなるコンテナエントリが出来てしまうところは、BerkeleyDBのマニュアルやら追いかけたのですが、LPICの試験とは関係ないのと、事務局からexpireの予告はがきが届いたこともあって、試験勉強を進める事にしました。

参考にしている問題集の「徹底攻略LPI Level3問題集」(中島能和:著)によれば、Active Directoryやらを使ってのLinuxアカウントの統合なども出るらしい。

そこで、とりあえず作ったサーバーを使って、VMWareに別VMを追加してPAMとNSSで認証をさせてみようと作業を進めました。

ここで新たな問題が…。

そこで"objectclass: posixAccount"を持つようなアカウント用のコンテナを作って…、と作業を進めてみたもののldapaddが失敗してしまう…。

adding new entry "cn=e0001,ou=accounts,dc=example,dc=org"
ldap_add: Invalid syntax (21)
 additional info: objectclass: value #0 invalid per syntax

あれ、っと思っていろいろ見回してみると、なんとcore.schemaしか登録されていませんでした。

$ ldapsearch -x -W -D cn=admin,cn=config -b cn=schema,cn=config | grep dn:
xxxxxxx
dn: cn=schema,cn=config
dn: cn={0}core,cn=schema,cn=config

システムの"schema"ディレクトリには"nis.ldif"や"cosine.ldif"はありますが、misc.ldifなどはありませんでした。

少し調べてみると"slaptest"コマンドにもslapd同様に"-f"、"-F"を両方指定してslapd.confを変換する事が判りました。 そこで適当なディレクトリに移動して、misc.ldifを作成してみました。

$ mkdir dummy_slapd.d
$ mkdir fake_schema
$ echo 'include "fake_schema/misc.schema"' > dummy_slapd.conf
$ cp /usr/local/etc/openldap/schema/misc.schema fake_schema/
$ slaptest -f dummy_slapd.conf -F dummy_slapd.d
config file testing succeeded
$ cp dummy_slapd.d/cn\=config/cn\=schema/cn\=\{0\}misc.ldif misc.ldif

これでmisc.ldifが手に入ったと…。
あとはldapaddでスキーマを登録していきます。

$ ldapadd -x -W -D cn=admin,cn=config -f /usr/local/etc/openldap/schema/cosine.ldif
$ ldapadd -x -W -D cn=admin,cn=config -f /usr/local/etc/openldap/schema/inetorgperson.ldif
$ ldapadd -x -W -D cn=admin,cn=config -f /usr/local/etc/openldap/schema/nis.ldif
$ ldapadd -x -W -D cn=admin,cn=config -f misc.ldif
Enter LDAP Password: xxxxxxx
adding new entry "cn={0}misc"
ldap_add: Server is unwilling to perform (53)
 additional info: no global superior knowledge

最後にエラーになってしまったのは、slaptestで生成したmisc.ldifが、DNとして"cn=misc,cn=schema,cn=config"ではなく、"cn={0}misc"となっているからでした。

変更前: misc.ldifの先頭3行

dn: cn={0}misc
objectClass: olcSchemaConfig
cn: {0}misc

変更後: misc.ldifの先頭3行

dn: cn=misc,cn=schema,cn=config
objectClass: olcSchemaConfig
cn: misc

さらにファイルの後ろも編集します。

変更前: misc.ldifの最後9行

structuralObjectClass: olcSchemaConfig
entryUUID: 5a6e1624-526d-102e-98e3-738f0cac427d
creatorsName: cn=config
createTimestamp: 20091021091042Z
entryCSN: 20091021091042.575517Z#000000#000#000000
modifiersName: cn=config
modifyTimestamp: 20091021091042Z

この部分をバッサリ削除します。なので変更後は"structuralObjectClass:"から"modifyTimestamp:"までのエントリがなくなります。

2009/10/22追記:
最初に投稿した時点ではmisc.ldifファイルの修正方法が間違っていました。削除していない行があると次のようなエラーがでます。 adding new entry "cn=misc,cn=schema,cn=config"
ldap_add: Constraint violation (19)
additional info: structuralObjectClass: no user modification allowed

あとはこれをldapaddして、終了。 さっさと先に進まないと…。

2009/10/17

OpenLDAP 2.4: 消せないエントリについて、まとめ

およそ12万件の郵便番号データを一斉に削除した時に、最後に残ったコンテナの"ou=address,dc=example,dc=org"エントリが削除できない問題を少し探っていました。

とりあえず状況からわかった事は"database hdb"にデータを格納した場合は、削除が問題なく完了するという事。Ubuntuで$ sudo apt-get install slapdした場合にはデフォルトが"hdb"になりますが、ソースから導入すると"bdb"がslapd.confに書かれています。

今回は自分でコンパイルしていたので気がついたというか、Ubuntu付属のslapdを使っていたら気がつかなかったかもしれないですね…。

場合分け

ldapdeleteコマンドの-fオプションを使うと複数のDNを記述したファイルを準備する事で、一気にエントリを削除する事ができます。

そこでスクリプトを準備して、122872件のエントリを削除してからou=addressエントリを削除してみます。

$ ./gen_delete_entries.rb > delete.ldif
$ ldapdelete -x -W -D cn=Manager,dc=example,dc=org -f delete.ldif

ここまではエラーも出ずに無事に完了します。ちなみに"gen_delete_entries.rb"スクリプトは次のようなものでした。

#!/usr/bin/ruby
for i in 0..122872
  printf "ou=%06d,ou=Address,dc=example,dc=org\n", i
end

エラーの内容

これから手動で"ou=address"エントリを削除しようとするとエラーがでます。

$ ldapdelete -x -W -D cn=Manager,dc=example,dc=org ou=Address,dc=example,dc=org
ldap_delete: Operation not allowed on non-leaf (66)
 additional info: subordinate objects must be deleted first

個別に削除せずに"ldapdelete"に"-r"オプションをつけて、いっきに12万件を削除した場合には、次のようなエラーになります。

$ ldapdelete -r -x -W -D cn=Manager,dc=example,dc=org ou=Address,dc=example,dc=org
ldap_delete: Other (e.g., implementation specific) error (80)
 additional info: DN index delete failed

"hdb"にすれば回避できるとはいっても、似たような現象はFAQの中でopenldap-dataディレクトリ以下のパーミッションの問題だ、とか今回の件には当てはまらないようなやりとりしか確認できていません。

ま、しばらくLPICの勉強から外れて原因を探ってみようと思います。

2009/10/15

OpenLDAP 2.4: 格納したUTF-8データの読み出し

さてOpenLDAPに登録されるデータについて、rfc2849でいうところの"SAFE-STRING"に収まらないものはBase64でエンコードされた上で格納される事になっています。 その時の目印はAttributeの区切りが':'から'::'になっているものです。

rfc2849をみると他にURLを使う':>'が記述されていますが、これは放っておきましょう。

郵便番号の県名などの日本語データはLDAP上では自動的にbase64エンコーディングされて格納されています。 そのためそのままldapsearchをすると、あまりうれしくない表示になります。

$ ldapsearch -x -b dc=example,dc=org postalCode=9650000
dn: ou=020258,ou=Address,dc=example,dc=org
objectClass: organizationalUnit
ou: 020258
st:: 56aP5bO255yM
l:: 5Lya5rSl6Iul5p2+5biC
street:: 5Lul5LiL44Gr5o6y6LyJ44GM44Gq44GE5aC05ZCI
postalCode: 9650000
description: 0,0,0,0,0

base64をデコードする簡単なフィルタを作る

そこでパイプに渡すと'::'を認識してbase64デコードするスクリプトを作ってみました。

#!/usr/bin/ruby
require 'base64'
$stdin.each do |line|
  if line !~ /^\w+::\s/
    print line
    next
  end
  (label, item) = line.split(/\s+/, 2)
  printf "%s %s\n", label, Base64.decode64(item)
end

例えばlsuf.rbとかいう名前のファイルに保存して、パイプでそのまま渡してみます。

$ ldapsearch -x -b dc=example,dc=org postalCode=9310000 | ./lsuf.rb 
dn: ou=020258,ou=Address,dc=example,dc=org
objectClass: organizationalUnit
ou: 020258
st:: 福島県
l:: 会津若松市
street:: 以下に掲載がない場合
postalCode: 9650000
description: 0,0,0,0,0

実際のところ、これぐらいして確認しないと、本当にデータが保存されているのか自信なくなりますね。

ldapsearchの引数にutf-8(日本語)を渡す

例えば"会津若松市"にある郵便番号を全て表示したい場合には、次のようにする事ができます。

$ ldapsearch -x -b dc=example,dc=org '(l=会津若松市)' postalCode street | ./lsuf.rb
# 020258, Address, example.org
dn: ou=020258,ou=Address,dc=example,dc=org
street:: 以下に掲載がない場合
postalCode: 9650000
...
...
# 020480, Address, example.org
dn: ou=020480,ou=Address,dc=example,dc=org
street:: 和田
postalCode: 9650811

とりあえずこれでだいたい使えるようになったかな…。

OpenLDAP 2.4: ダミーデータの作成

OpenLDAPでMaster-Server構成を作ってみたものの、データを入れてみないとおもしろくないので、 適当なデータをデッチ上げる事にしました。

データソースは昔から日本郵便が配布している郵便番号データダウンロードにある全国分のデータを使います。これで約12万2千件を越えるデータが手に入ります。

このままではLDAPに入れる事ができないので、加工する必要があります。 ずっと前にFedora Directory Serverを試した時のスクリプトに手を加えて、それっぽいLDIFを生成するrubyスクリプトを作りました。郵便番号データのデータ構造は郵便番号データの説明の中に詳しく解説されています。

データの作成

LDAPの内部データ構造はUTF-8となっているので、"ken_all.zip"をダウンロードして、UTF-8に変換します。

$ nkf -e ken_all.csv > ken_all.utf8.csv

続いてrubyスクリプトでLDIFを出力するスクリプトを書いて、これに渡してあげます。

$ ./postal2ldif.rb ken_all.utf8.csv > ken_all.utf8.ldif

スクリプトの中身は、こんな感じ。

#!/usr/bin/ruby

printf("dn: ou=Address,dc=example,dc=org\n")
printf("objectClass: organizationalUnit\n")
printf("ou: Address\n\n")

require 'csv'
id = 0
CSV.open(ARGV[0], 'r').each do |row|
  printf("dn: ou=%06d,ou=Address,dc=example,dc=org\n", id)
  printf("objectclass: organizationalUnit\n")
  printf("ou: %06d\n", id)
  printf("st: %s\n", row[6])
  printf("l: %s\n", row[7])
  printf("street: %s\n", row[8])
  printf("postalCode: %s\n", row[2])
  printf("description: %s,%s,%s,%s,%s\n", row[9],row[10],row[11],row[12],row[13],row[14])
  printf("\n")
  id += 1
end

データを入れてみる

こうやって作成した"ken_all.utf8.ldif"ファイルをldapaddを使って、一気に加えてみます。

$ ldapadd -x -W -D cn=Manager,dc=example,dc=org -f ken_all.utf8.ldif

だいたい待つこと1時間といったところでしょうか。 12万件のデータを一つのou=Addressコンテナに入れるのは、どうかと思ったり…。 まぁテストですし、気にしない事にしました。

データを削除してみる

さて12万件のデータを削除してみます。 $ ldapdelete -x -W -D cn=Manager,dc=example,dc=org ou=Address,dc=example,dc=org

さすがに30分以上かかって、最後にエラーを出してou=Address自体の削除はできなかったものの、表面上は無事にデータが消えました。

レプリカ側のデータは、まだ500件以上残っているけれど、この不整合がエラーの原因なのかなぁ…。 そのまましばらく放っておいたら、件数をみればコンシューマ側でも削除処理が終ったようでした。

しかし、どうやってもou=Address,dc=example,dc=orgが消せない…。 エントリの追加もできるのになぁ…。なんでだろう。

さいごに

LDIFは手に入ったし、作業自体はVMWare上にサーバーを置いているから、スナップショットから元に戻してまたデータを入れたり、消したりしてみようと思います。 もうちょっと条件を絞って、どういう挙動なのか確認しないとなぁ。

2009/10/13

OpenLDAP 2.4: slapd.dの再構成

昨日やって、なんとか動くところまでいった"slapd.d"を使う構成のやり直し。

slapd.confに最初から"database config"の設定をちゃんと入れていれば、何も問題はなかったです。 最初にこの設定をいれないままに"-f slapd.conf -F slapd.d"の設定で動かしてしまった事が問題でした。

最低限のconfig構成

database config
rootdn    "cn=admin,cn=config"
rootpw    yoursecretpassword

やっぱりLDAPはデータの入れ方の話しだから、空を掴むような感覚になるなぁ。 明日はデータをきちんと入れて、いろいろいじっていこう。

2009/10/12

OpenLDAP 2.4のslapd.d構成と少し格闘

backupを取ろうとした矢先に外付けHDDのVMWareイメージが全滅しました。 まぁWindowsの再導入とか面倒なだけで、重要な情報はなかったから良いのですが…。
そうはいっても、いままでの試行錯誤の経過を全部失なってしまって少し傷心気味です。

さてLPIC v3の対策とLDAPの復習を兼ねてOpenLDAP v2.4に手を出してみました。 まっさらになったvmwareディレクトリの中にUbuntu 8.04 LTS x86_64版のイメージを作って、 そこを元にTeamを組んでCloneでVMを増やしてみました。

OpenLDAPはapt-getではなく、最新版のopenldap-2.4.19.tgzを持ってきています。 v2.2の経験しかなかったので、いつの間にかslapd.confを使うのは時代遅れっぽいし、LDBMがabsoluteになってBDBがデフォルトになっていたり、戸惑う事ばかりです。JFにあるLDAP HOWTOは完全に古い情報になってしまいましたね…。

テスト対策という意味では、v2.3ぐらいで遊んだ方が良さそうでしたが、まぁそれはおもしろくないので、v2.4の世界を堪能してみる事にしてみました。 LDAPはDB同様に入れ物の話しだから、おもしろいデータをネタにしないと、昔のIBM Secureway Directory Serverのトラウマ再びという感じです。今はTivoli Directory Serverか…。
とりあえずデータの件は置いておくことにします。

LPI Level3の問題集をやってみた

OpenLDAPに手を出したきっかけは、LPICの問題集をやってみたところ微妙にわからないところがあったからでした。Sync LDAP構成って何ですか、と。

レプリカの構成自体は参考書の説明の通りで、すぐに動いたんですよね。

## producer側
overlay    syncprov
syncprov-sessionlog    1000
index    entryCSN,entryUUID  eq

## consumer側
syncrepl rid=1
  provider=ldap://10.0.0.2
  type=refreshAndPersist
  bindmethod=simple
  binddn="cn=Manager,dc=example,dc=org"
  credentials=hiddenpasswordstring
  searchbase="dc=example,dc=org"

でもLPIC日本支部のWebサイトにある問題例をみるとproducer側では"syncprov-checkpoint"を設定する事となっています。本家の説明を読むと次のように書かれています。

  • indexを付けたentryCSNはsyncprov-checkpoint
  • entryUUIDはsyncprov-sessionlog

問題集に載っていた例だとsyncprov-checkpointも付けないとindexでentryCSNを付けてる意味がないよね、とか、いろいろミスマッチが楽しめます。

やっぱり確実な資料は配布元の「OpenLDAP Software 2.4 Administrator's Guide」ですかね。

2009/11/10追記:ちなみに使っていた問題集はインプレスの「徹底攻略 LPI問題集 Level 3 [301/302] 対応」です。
正誤表があるかと思いましたが、ないようですね。

slapd.d構成

OpenLDAP Software v2.4 Administrator's Guideでは、中途半端な説明のままslapd.confは時代遅れになりつつあり、これからはslapd.dディレクトリに構成情報を入れるのだと解説が始まります。

実際にはどうやって使えばいいか、あまり説明はありません。
デフォルト構成では、最初に /usr/local/etc/openldap/slapd.conf を使う事になっているので、 いろいろ手順が必要になります。

  1. slapd.confに"database config"エントリを作成して、rootDN(cn=admin,cn=config),rootPWディレクティブを設定する
  2. /usr/local/etc/openldap/slapd.d ディレクトリを作成
  3. slapdのオプションで"-f slapd.conf -F slapd.d"を付けて、slapd.confの内容をslapd.d以下にコピーする
  4. $ sudo skill slapdなどでslapdを停止する
  5. $ sudo /usr/local/libexec/slapdなどで起動する

しかし問題はたくさん

これで slapd.d を使う事ができるかと思いきや、再起動前は$ ldapsearch -x -b cn=config -W -D cn=admin,cn=configが動いていたのに、オプションを除いて起動した後は、同じ事ができなくなってしまいました。

.../slapd.d/cn=config/olcDatabase={0}config.ldifを直接眺めていると、olcRootDN, olcRootPW設定が記録されていませんでした。うーーん、困ってしまった。

結局のところ、再びslapdを"-f slapd.conf -F slapd.d"を付きで起動して、次のようなldifを準備してみました。

dn: olcDatabase={0}config,cn=config
changetype: modify
replace: olcRootDN
olcRootDN: cn=admin,cn=config
-
replace: olcRootPW
olcRootPW: hiddenpasswordstring

これをldapmodifyを使って、サクっとアップデート。$ ldapmodify -x -W -D cn=admin,cn=config -f yourfilename.ldif ぐらいかな。

なんか途中で試行錯誤したのが悪かったのかな…。明日スナップショットを取ったところまで戻って最初から手順を遣り直してみよう…。