RADIUS 第一回
LDAPにユーザ情報を追加し、apacheへのアクセス時に参照させる
前回までの話
ou=People,dc=shonbori,dc=net ou=Group,dc=shonbori,dc=net
というディレクトリを作った。
これはdc=netをルートとし、その下位にdc=shonboriディレクトリがあり、
さらにその配下にou=Peopleとou=Groupディレクトリが並列して存在するデータ構造であった。
LDAPに追加登録するデータ
このシリーズの目的は、LDAPのデータツリーに、認証対象となるユーザとパスワードを格納し、
apacheと連携させることである。
これを実現する上でさらに必要なデータは、ユーザとパスワードの対である。
これまでの設定でちょうどPeopleというディレクトリを作ったので、
この配下にユーザIDやパスワードのエントリ(LDAP的にはattribute(属性)らしい)を追加していこう。
具体的には、次のようなldifファイルを新たに用意し、
ldapaddでdn(distinguished name)を追加してやる。
# cat user.hoge.ldif dn: uid=hoge,ou=People,dc=shonbori,dc=net # hogeというユーザIDに相当するdnを定義 uid: hoge # 相対dn的な表記 objectclass: account # *よくわからないが objectclass: posixAccount # *POSIXに準拠した #objectclass: shadowAccount # *データをここに書くことで cn: hoge # *既存のschemaを利用できるらしい uidNumber: 1001 # * gidNumber: 1001 # * userPassword: {SSHA}smFKBYZoO403X9ay+3wpcg5oLQ8uXPSb # * # hogehoge homeDirectory: /home/hoge # * loginShell: /bin/bash # *
POSIXにおけるAccountとは、最低限
cn,uid,uidNumber,gidNumber,homeDirectory
の属性を持っているものらしい。
userPassword属性は、先のエントリで述べた、
# slappasswd -h {SSHA}
このコマンドで暗号化したパスワードである。
ここまでやった後、以下を実行する。
# ldapadd -x -W -D "cn=Manager,dc=shonbori,dc=net" -f user.hoge.ldif adding new entry "uid=hoge,ou=People,dc=shonbori,dc=net"
これで、uid=hoge,ou=People,dc=shonbori,dc=netというdnについての情報が追加されたはず。
ためしにldapsearchで見てみると・・・
# ldapsearch -x -W -D "cn=Manager,dc=shonbori,dc=net" '(uid=hoge)' # extended LDIF # # LDAPv3 # base <> with scope subtree # filter: (uid=hoge) # requesting: ALL # # hoge, People, shonbori.net dn: uid=hoge,ou=People,dc=shonbori,dc=net uid: hoge objectClass: account objectClass: posixAccount cn: hoge uidNumber: 1001 gidNumber: 1001 userPassword:: e1NTSEF9c21GS0JZWm9PNDAzWDlheSszd3BjZzVvTFE4dVhQU2I= homeDirectory: /home/hoge loginShell: /bin/bash # search result search: 2 result: 0 Success # numResponses: 2 # numEntries: 1
このように無事参照できるはずである。
ちなみに余談だが、FreeBSD/Linux等の/etc/passwdもPOSIX準拠のposixAccountのリストであり、
これをそのままLDAPに乗せ換えて、サーバへのログインをLDAP認証に切り替えてしまうこともできるようだ。
apache側の設定
apacheモジュール
LoadModule ldap_module modules/mod_ldap.so LoadModule authnz_ldap_module modules/mod_authnz_ldap.so
以上の2つがおそらく必要になるだろう。
.htaccessの記述
AuthType Basic AuthName "LDAP Auth" AuthBasicProvider ldap AuthzLDAPAuthoritative off # よくわからなかった AuthLDAPURL ldap://localhost/ou=People,dc=shonbori,dc=net?uid Require valid-user
.htpasswdファイルを使う場合はAuthBasicProvider,AuthzLDAPAuthoritative,AuthLDAPURLの代わりにAuthFileディレクティブを使っていた。
AuthLDAPURLの書式はapache.orgのマニュアルに詳しく記述されているのでぜひ参照されたい。
ともかくこれで、この.htaccessを設置したディレクトリにhttpでアクセスした場合は、
ldapaddで追加したユーザ(valid-user)のIDとパスワードを入力して認証されなければコンテンツを参照できなくなった。
あとは、LDAPの初期化やユーザの追加を自動化するスクリプトを書いたりすれば、
LDAPサーバのアドミニストレータを名乗れるのではなかろうか。
・・・・だめ?
httpの応答コード ( status code )
apache関連で何か作業するたびに毎回覚えていないhttpのstatus code一覧
http://www.studyinghttp.net/status_code
とてもよくまとまっていてかゆいところに手が届くうれしいリスト
ldapdelete
コマンド実行例
# ldapdelete -x -W -D 'cn=Manager,dc=shonbori,dc=net' 'dc=shonbori,dc=net'
-xで簡易認証、-Wでパスワードをプロンプト、-D 'hogehoge'でどのdistinguished nameでアクセスするか指定、
そして最後の
'dc=shonbori,dc=net'
↑これで、どのクラスに対してldapdeleteを実施するかを指定している。
前述のldapaddで、dc=shonbori,dc=netより下層のツリーまで追加してしまっているため、
このまま実行すると
ldap_delete: Operation not allowed on non-leaf (66) additional info: subordinate objects must be deleted first
というエラーが帰ってくる。
ある階層のクラスから下を全部まとめて消したい場合は、
-r
をつけて、recursive deleteしてやる必要がある。
# ldapdelete -x -W -r -D 'cn=Manager,dc=shonbori,dc=net' 'dc=shonbori,dc=net' Enter LDAP Password:
これで、最初のldapaddコマンドで追加したデータが全部消えた。
ldapmodify
未着手
ldapsearch
# ldapsearch -x -W -D 'cn=Manager,dc=shonbori,dc=net' -H ldap://localhost/389 Enter LDAP Password: *******以下、出力結果******* # extended LDIF # # LDAPv3 # base <> with scope subtree # filter: (objectclass=*) # requesting: ALL # # shonbori.net dn: dc=shonbori,dc=net objectClass: dcObject objectClass: organization o: VPDCP dc: shonbori # Manager, shonbori.net dn: cn=Manager,dc=shonbori,dc=net objectClass: organizationalRole cn: Manager # People, shonbori.net dn: ou=People,dc=shonbori,dc=net objectClass: organizationalUnit ou: People # Group, shonbori.net dn: ou=Group,dc=shonbori,dc=net objectClass: organizationalUnit ou: Group # search result search: 2 result: 0 Success # numResponses: 5 # numEntries: 4
オプションなどは先ほどのldapaddとほぼ同じ。
あえて違う使い方をしてみた点は以下のとおり。
# ldapsearch -x -W -D 'cn=Manager,dc=shonbori,dc=net' -H ldap://localhost/389 -H ldapuri : データを読みに行くLDAPサーバを、URI形式で指定する。 ldap://ホストネーム/ポート番号 ldaps://ホストネーム/ポート番号 のように書く。 比較的新しい記述の仕方のようだ。 昔から使われていたのは -h hostname -p port のような書き方らしいが、今ではURI形式の書式が主流になっているらしい。 -Hや-hを省略するとlocalhostに聞きに行くようだ。 どこかにデフォルトを設定できそう。
この例では、より下層のディレクトリにあるクラス/オブジェクトの情報も表示されている。
これは、ldapsearchの引数に下記のものがあるからである。
-b base|one|sub : baseがベースオブジェクト検索(ってなんだ?) oneは、指定したクラスのみ検索。 subは、指定したクラスを含め、その配下も検索する。(たぶん)←これがデフォルト
デフォルトがsubとなっているので、dc=shonbori,dc=netだけでなく、
その配下にあるou=People,dc=shonbori,dc=netやou=Group,dc=shonbori,dc=netも検索に引っかかっている。
また、フィルタ条件を書いてやることにより、より厳密な参照が可能になる。
# ldapsearch -x -W -D 'cn=Manager,dc=shonbori,dc=net' '(ou=People)'
こうすると、ouがPeopleとなっているオブジェクトが検索にひっかかる。デフォルトは'(objectClass=*)'。
# extended LDIF # # LDAPv3 # base <> with scope subtree # filter: (ou=People) # requesting: ALL # # People, shonbori.net dn: ou=People,dc=shonbori,dc=net objectClass: organizationalUnit ou: People # search result search: 2 result: 0 Success # numResponses: 2 # numEntries: 1
ldapadd
例として、下記のようなldifファイルを用意する。
example.ldif
dn: dc=shonbori,dc=net objectclass: dcObject objectclass: organization o: VPDCP dc: shonbori dn: cn=Manager,dc=shonbori,dc=net objectclass: organizationalRole cn: Manager dn: ou=People,dc=shonbori,dc=net objectclass: organizationalUnit ou: People dn: ou=Group,dc=shonbori,dc=net objectclass: organizationalUnit ou: Group
ローカルDITのトップレベルをdc=netとし、その1階層下にdc=shonboriがあり、
その下に
- cn=Manager
- ou=People
- ou=Group
の3つのクラスが並んでいる構造をテキストであらわしているようだ。
o=VPDCPはorganizationの名前をVPDCPとしてみたけど、DITのどの位置に来るのかが良くわからない。
いろいろと疑問点は残しつつも、とりあえずldapaddコマンドでデータを追加してみる。
# ldapadd -x -D 'cn=Manager,dc=shonbori,dc=net' -W -f example.ldif Enter LDAP Password: adding new entry "dc=shonbori,dc=net" adding new entry "cn=Manager,dc=shonbori,dc=net" adding new entry "ou=People,dc=shonbori,dc=net" adding new entry "ou=Group,dc=shonbori,dc=net"
コマンドと結果を細かく分析すると、
# ldapadd -x -D 'cn=Manager,dc=shonbori,dc=net' -W -f example.ldif -x : ldap通信時の認証は、本来はSASLなどの優れた暗号化を通してやるべきだけど、 今は何の設定もしてないので、このオプションをつけることで簡易な認証で いけるようにする。これをつけないとSASL等を勝手に使おうとしてエラーになる。 -D binddn : ありていに言うとおそらく、どんな権限を持ったユーザとして このLDAPデータにアクセスするかの指定だと思う。 sshでいうところの-l usernameみたいなものとして考えておけばよいのだろうか。 -W : パスワードをたずねるプロンプトを出す。 -w ****** というふうにパスワードをコマンドに埋め込むやり方もつかえる。 どちらを使うべきかはシチュエーションによる。 -f ldiffile : DITに追加したいデータが書かれたLDIFファイルを指定し、 そこに書いてあるとおりに情報を追加する。 LDAP Passwordとは、昨日までのエントリでがんばって設定した、 /etc/openldap/slapd.confのグローバル設定部分の管理者パスワード。