そろそろLDAPにしてみないか?

第7回 ApacheのBasic認証をLDAPで

この記事を読むのに必要な時間:およそ 4.5 分

LDAPデータ登録

今回Basic認証に必要なユーザ名やパスワードはFTPログインに使用するものをそのまま流用するものとします。検証に際してリスト4のようなエントリを使用しました。特殊な設定はなく,/etc/passwdや/etc/shadowと同等の意味を持ちます。

リスト4 user.ldif

dn: dc=example,dc=com
objectClass: dcObject
objectClass: organization
dc: example
o: example

dn: ou=People,dc=example,dc=com
objectClass: organizationalUnit
ou: People

dn: ou=Group,dc=example,dc=com
objectClass: organizationalUnit
ou: Group

dn: cn=users,ou=Group,dc=example,dc=com
objectClass: posixGroup
objectClass: top
cn: users
userPassword: {crypt}x
gidNumber: 1000

dn: uid=suzuki,ou=People,dc=example,dc=com
objectClass: account
objectClass: posixAccount
uid: suzuki
cn: suzuki
userPassword: suzuki
loginShell: /bin/bash
uidNumber: 1001
gidNumber: 1000
homeDirectory: /home/suzuki

dn: uid=tanaka,ou=People,dc=example,dc=com
objectClass: account
objectClass: posixAccount
uid: tanaka
cn: tanaka 
userPassword: tanaka
loginShell: /bin/bash
uidNumber: 1002
gidNumber: 1000
homeDirectory: /home/tanaka

このような環境下で,たとえば認証画面でUser: tanaka,パスワード: tanakaと入力すれば認証済みになるとします。Apache側の設定としてはリスト5のようになります。いつもと違うオプションはAuthBasicProvider,AuthzLDAPAuthoritative,AuthLDAPURLです。

リスト5 httpd.conf(一部)

# 認証モジュールとLDAP接続モジュールをロード
LoadModule authnz_ldap_module modules/mod_authnz_ldap.so
LoadModule ldap_module modules/mod_ldap.so
Alias /logs/ /home/support/logs/
<Directory "/home/support/logs/*/">
    AuthName "User/Password"
    AuthType Basic
    AuthBasicProvider ldap
    AuthzLDAPAuthoritative  off
    AuthLDAPURL  ldap://10.0.100.10/ou=People,dc=example,dc=com?cn?sub?(objectClass=account)
    Require valid-user
</Directory>

ここでmod_authnz_ldapの各オプションについて解説しておきます。それ以外のオプションに関しては,Apacheのドキュメントで確認してください。ちなみに筆者が普段使用するオプションはAuthLDAPBindDN,AuthLDAPBindPassword,AuthLDAPUrl,AuthzLDAPAuthoritativeくらいです。Require valid-userを使用しているため,それに伴いAuthzLDAPAuthoritative offを定義しています。

そのほか,認証時に入力させるユーザ名ではない値を環境変数REMOTE_USERに保存するためのAuthLDAPRemoteUserAttributeというオプションなどもありますが,使用する機会は少ないように思います。

AuthLDAPBindDNLDAPサーバへバインドするためのバインドDN
AuthLDAPBindPassword上記パスワード
AuthLDAPUrlLDAP URLの指定
AuthzLDAPAuthoritative認証が失敗したときに他の認証モジュールが認証を行うのを防ぐ

認証と課金

場合によっては,今回のようなアクセスログ解析サービスを有料オプションとして提供したい場合もあるでしょう。その場合,FTP用にIDやパスワードを参照させますが,WebのBasic認証をパスさせない,という対策が必要になります。今までの連載でも触れてきましたように,LDAPでは検索フィルタを用いることでこのような機能を簡単に実装することができます。

たとえば検索フィルタが(&(objectClass=account)(servicetype=1))となっていれば,利用者の中でもservicetypeという属性が1であるユーザのみが検索対象となります。言い換えれば,有料オプション利用者のエントリではserviceType=1と定義しておき,それ以外のユーザではserviceType=0と定義しておけば良いのです。

もちろんserviceTypeという属性は筆者が勝手に決めたものであり,標準スキーマに含まれているわけではありませんので,次のようにして組み込んでおく必要があります。

リスト6 /etc/openldap/schema/webaccount.schema

attributetype (1.3.6.1.4.1.12461.1.1.1 NAME 'serviceType'
        DESC 'serviceType'
        EQUALITY integerMatch
        ORDERING integerOrderingMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE)

objectclass (1.3.6.1.4.1.12461.1.2.1 NAME 'webAccount'
        DESC 'web Account'
        SUP  account
        MAY ( serviceType ) )

リスト7 /etc/openldap/slapd.confの一部

include  /etc/openldap/schema/webaccount.schema

これに合わせたユーザ用のLDIFはリスト8のようになります。

リスト8 ユーザデータ

# このユーザは有料オプションを契約しているのでserviceType=1としておく
dn: uid=suzuki,ou=People,dc=example,dc=com
objectClass: account
objectClass: posixAccount
objectClass: webAccount
uid: suzuki
cn: suzuki
userPassword: suzuki
loginShell: /bin/bash
uidNumber: 1001
gidNumber: 1000
homeDirectory: /home/suzuki
serviceType: 1

# このユーザは有料オプションを契約していないのでserviceType=0としておく
dn: uid=tanaka,ou=People,dc=example,dc=com
objectClass: account
objectClass: posixAccount
objectClass: webAccount
uid: tanaka
cn: tanaka 
userPassword: tanaka
loginShell: /bin/bash
uidNumber: 1002
gidNumber: 1000
homeDirectory: /home/tanaka
serviceType: 0

あとは検索フィルタを有効にしたhttpd.confを準備するだけですリスト9⁠。AuthLDAPURLオプションをうまく設定します。

リスト9 httpd.confの一部

<Directory "/home/support/logs/*/">
    AuthName "User/Password"
    AuthType Basic
    AuthBasicProvider ldap
    AuthzLDAPAuthoritative  off
    AuthLDAPURL  ldap://10.0.100.10/ou=People,dc=example,dc=com?cn?sub?(&(objectClass=account)(serviceType=1))
    Require valid-user
</Directory>

まとめ

今回はBasic認証用にLDAPを活用することで,冒頭に述べたとおり

  • パスワードファイルの置き場所に悩まない
  • パスワードを一元管理
  • 検索フィルタを活用してサービス制限

といったことを実現することができました。また,LDAP URLを用いて検索フィルタや条件などを追加することができることもわかりました。2007年最後の記事となりましたが,来年も少しずつLDAPの使い道を紹介していく予定です。それではまた。

著者プロフィール

中満英生(なかみつひでお)

大学時代に出会ったSolarisがきっかけでUNIXの世界へ。その後ホスティングプロバイダ,データセンターで実務経験を積む傍ら,雑誌記事の執筆や技術セミナーの講師を務める。サーバ設定の他,セキュリティに関する著作や技術者エッセイも執筆経験あり。