歡迎您光臨本站 註冊首頁

理解與應用LDAP伺服器

←手機掃碼閱讀     火星人 @ 2014-03-04 , reply:0

理解與應用LDAP伺服器

(前段時間一直在做LDAP+POSTFIX相關項目,先把關於LDAP的一些經驗寫出來,一來可能會幫助一些人,二來對我自己所學知識也是一個鞏固。)

先聲明:我寫的只是我對LDAP的一些理解,如果我的理解錯誤,那就是對兄弟們的誤導。所以你可以直接看文章的結尾提供的幾個網址。

關於LDAP的概念隨便網上有很多,我不想重複,這裡只是說一下我自己的理解。
都說它是「輕量級目錄協議」,太專業,我不懂,我只把它想象成「簡單」的目錄協議。

幾個很重要的概念,以後會用到:
---------------------------------------------
dn :一條記錄的位置
dc :一條記錄所屬區域
ou :一條記錄所屬組織
cn/uid:一條記錄的名字/ID
---------------------------------------------

實際上更多時候我只把它看成資料庫。我把它和我非常熟悉的MYSQL資料庫做比較,通常會得到更好的理解:

MYSQL用「表」儲存數據,LDAP用「樹」
MYSQL指定一條記錄要3個條件:DB、TABLE、ROW。
LDAP卻更自由,為什麼呢?因為LDAP數據是「樹」狀的,而且這棵樹是可以無限延伸的,假設你要樹上的一個蘋果(一條記錄),你怎麼告訴園丁它的位置呢?當然首先要說明是哪一棵樹(dc,相當於MYSQL的DB),然後是從樹根到那個蘋果所經過的所有「分叉」(ou,呵呵MYSQL裡面好象沒有這DD),最後就是這個蘋果的名字(uid,記得我們設計MYSQL或其它資料庫表時,通常為了方便管理而加上一個『id』欄位嗎?)。 好了!這時我們可以清晰的指明這個蘋果的位置了,就是那棵「歪脖樹」的東邊那個分叉上的靠西邊那個分叉的再靠北邊的分叉上的半紅半綠的……,暈了!你直接爬上去吧!我還是說說LDAP里要怎麼定義一個欄位的位置吧,樹(dc=waibo,dc=com),分叉(ou=bei,ou=xi,ou=dong),蘋果(cn=honglv),好了!位置出來了:
dn:cn=honglv,ou=bei,ou=xi,ou=dong,dc=waibo,dc=com

一個有名的畫家說過:「世上沒有相同的2個雞蛋」。當然也沒有相同的2個蘋果……,同樣,在LDAP里也不可能存在2個相同的dn。


LDAP數據填充原理:
一棵樹的生長,要循序漸進,如果還沒有長出某個分叉,就不可能在那個分叉里長出蘋果(問:FT!蘋果是長在分叉上的嗎?答:為了便於理解,你就當它是吧),同樣,LDAP資料庫也要一步步的充實,舉一個學校資料庫的例子,我們將要把一個龐大的學生檔案放到LDAP里,大致需要這麼做:
---------------------------------------------
1、建立「樹根」,這是通過修改「slapd.conf」來實現的,由於現在的目的是理解,所以具體步驟就不說了,反正就是在這一步建立了一個「dc=ourschool,dc=org」這樣一個「樹根」。 注意:我把它理解成「目錄」,或者「容器」,甚至它本身也是文件(蘋果)的特殊形式,熟悉LINUX文件系統的朋友會更容易理解。
2、建立18個系,分別是「dn:ou=computer,dc=ourschool,dc=org」、「dn:ou=film,dc=ourschool,dc=org」……
3、當然是在每個系裡面建立專業,比如「dn:ou=linux,ou=computer,dc=ourschool,dc=org」……
4、(開始長蘋果吧!)加學生嘍——「dn:cn=stan,ou=linux,ou=computer,dc=ourschool,dc=org」……
5、已經完成了嗎?對了!學生的詳細信息還沒有吶!不過先這樣吧,反正記錄是可以編輯的。
---------------------------------------------


LDAP記錄的詳細信息
dn:cn=stan,ou=linux,ou=computer,dc=ourschool,dc=org
objectClass:organizationalPerson
cn:stan
cn:小刀
sn:小刀
description:a good boy
(以上是一條記錄的信息,如果把他保存成LDIF文件,可以導入到LDAP資料庫中)
上面不是說沒有學生詳細信息嗎?怕你著急,就馬上寫出來了,只是還沒有導入到LDAP里,那是以後的事。這裡我先就你可能會產生的疑問做回答。
---------------------------------------------
Q1:「cn」不是在「dn」里定義了嗎,怎麼又在後面重新定義了? 答:你要把「cn=stan,ou=linux,ou=computer,dc=ourschool,dc=org」看成是一個整體,它只是屬性dn的值。
Q2:怎麼後面有2個「cn」,我以哪個為準? 答:區別於普通資料庫,LDAP每個屬性一般可以具有多個值,這樣不好嗎?你在學校資料庫里找我的時候,只要記得我的一個cn就可以了,用「cn=stan」或「cn=小刀」都可以找到我!
Q3:就這些屬性了嗎?我都不知道你是男是女。 答:先聲明,偶是男地。 LDAP對記錄的屬性做了嚴格的限制(這一點我不太喜歡),也就是說,你可以用哪些屬性,哪些屬性不能為空,哪些屬性最多只能有一個值等,他們都給你規定好了。 幸好你有選擇的權利,比如這次我們是儲存學生信息,那麼我們就定義一個「objectClass:organizationalPerson」,這樣「organizationalPerson」這個類所規定的所有屬性我們都可以用了,而且確實很適合我們。 雖然這個類中沒有「sex」這個屬性,不過你完全可以用一個「空閑」的屬性來頂替。 如果我們能自己建立「類」就更好了,但目前我還沒有時間去研究這個東西,我也期望高手指點啊 :)
---------------------------------------------


好了!看到我貼的圖了嗎?那是我偷別人的,差不多能用我就不自己畫了 :)

##############################################################

關於安裝配置LDAP,使之儲存系統用戶,這裡有一個非常好的網址,如果你的英文不是很差,都應該做的來,我偷個懶,就先不寫這方面的東西嘍:
http://www.mandrakesecure.net/en/docs/ldap-auth.php
上面的方法我已經試過,是可行的,如果兄弟們配置的時候出現問題我們可以討論討論。

關於LDAP+POSTFIX,POSTFIX里的「LDAP_README」中介紹的很詳細,我再說就是重複了。
##############################################################
其它相關資源:
yala (很實用的資料庫操作工具,簡單的說,他就是MYSQL的phpmyadmin,自己找下載地址吧~)
http://www.openldap.org/ (說實話,我一直沒用上它,不過它是官方網站,不提也不好)
http://ldap.akbkhome.com/ (什麼『類』下面有什麼『屬性』,在這裡找)
《解決方案》

理解與應用LDAP伺服器

LDAP_README

--------------------------------------------------------------------------------


LDAP SUPPORT IN POSTFIX
=======================

Postfix can use an LDAP directory as a source for any of its lookups:
aliases, virtual, canonical, etc. This allows you to keep information
for your mail service in a replicated network database with fine-grained
access controls. By not storing it locally on the mail server, the
administrators can maintain it from anywhere, and the users can control
whatever bits of it you think appropriate. You can have multiple mail
servers using the same information, without the hassle and delay of
having to copy it to each.

BUILDING WITH LDAP SUPPORT
==========================

Note: Postfix no longer supports the LDAP version 1 interface.

You need to have LDAP libraries and include files installed somewhere
on your system, and you need to configure the Postfix Makefiles
accordingly.

For example, to build the OpenLDAP libraries for use with Postfix
(i.e. LDAP client code only), you could use the following command:

% ./configure --without-kerberos --without-cyrus-sasl --without-tls \
--without-threads --disable-slapd --disable-slurpd \
--disable-debug --disable-shared

If you're using the libraries from the UM distribution
(http://www.umich.edu/~dirsvcs/ldap/ldap.html) or OpenLDAP
(http://www.openldap.org), something like this in the top level of your
Postfix source tree should work:

% make tidy
% make makefiles CCARGS="-I/usr/local/include -DHAS_LDAP" \
AUXLIBS="-L/usr/local/lib -lldap -L/usr/local/lib -llber"

On Solaris 2.x you may have to specify run-time link information,
otherwise ld.so will not find some of the shared libraries:

% make tidy
% make makefiles CCARGS="-I/usr/local/include -DHAS_LDAP" \
AUXLIBS="-L/usr/local/lib -R/usr/local/lib -lldap \
-L/usr/local/lib -R/usr/local/lib -llber"

The 'make tidy' command is needed only if you have previously built
Postfix without LDAP support.

Instead of '/usr/local' specify the actual locations of your LDAP
include files and libraries. Be sure to not mix LDAP include files
and LDAP libraries of different versions!!

If your LDAP libraries were built with Kerberos support, you'll also
need to include your Kerberos libraries in this line. Note that the KTH
Kerberos IV libraries might conflict with Postfix's lib/libdns.a, which
defines dns_lookup. If that happens, you'll probably want to link with
LDAP libraries that lack Kerberos support just to build Postfix, as it
doesn't support Kerberos binds to the LDAP server anyway. Sorry about
the bother.

If you're using one of the Netscape LDAP SDKs, you'll need to change the
AUXLIBS line to point to libldap10.so or libldapssl30.so or whatever you
have, and you may need to use the appropriate linker option (e.g. '-R')
so the executables can find it at runtime.

CONFIGURING LDAP LOOKUPS
========================

In order to use LDAP lookups, define at least one LDAP source as a table
lookup in main.cf, for example:

alias_maps = hash:/etc/aliases, ldap:ldapsource

Each LDAP source can have the following parameters, which should be
prefixed in main.cf with the name you've given the source in its
definition and an underscore. To continue the example, the first
parameter below, "server_host", would be defined in main.cf as
"ldapsource_server_host". Defaults are given in parentheses:

server_host (localhost)
The name of the host running the LDAP server, e.g.
ldapsource_server_host = ldap.your.com
It should be possible with all the libraries mentioned above to
specify multiple servers separated by spaces, with the libraries
trying them in order should the first one fail. It should also
be possible to give each server in the list a different port, by
naming them like "ldap.your.com:1444".

server_port (389)
The port the LDAP server listens on, e.g.
ldapsource_server_port = 778

search_base (No default; you must configure this.)
The base at which to conduct the search, e.g.
ldapsource_search_base = dc=your, dc=com

timeout (10 seconds)
The number of seconds a search can take before timing out, e.g.
ldapsource_timeout = 5

query_filter (mailacceptinggeneralid=%s)
The RFC2254 filter used to search the directory, where %s is a
substitute for the address Postfix is trying to resolve, e.g.
ldapsource_query_filter = (&(mail=%s)(paid_up=true))

result_filter (%s)
Filter applied to result attributes. Supports the same expansions
as the query_filter, and can be easily used to append (or prepend)
text.

domain (Default is to ignore this.)
This is a list of domain names, paths to files, or dictionaries.
If specified, only lookups for the domains on this list will be
performed. This means that the LDAP map won't get searched for
'user', nor will it get searched for any domain not listed. This
can significantly reduce the query load on the LDAP server.
ldapsource_domain = postfix.org, hash:/etc/postfix/searchdomains

result_attribute (maildrop)
The attribute(s) Postfix will read from any directory entries
returned by the lookup, to be resolved to an email address.
ldapsource_result_attribute = mailbox,maildrop

special_result_attribute (No default)
The attribute(s) of directory entries that can contain DNs or URLs.
If found, a recursive subsequent search is done using their values.
ldapsource_special_result_attribute = member

scope (sub)
The LDAP search scope: sub, base, or one. These translate into
LDAP_SCOPE_SUBTREE, LDAP_SCOPE_BASE, and LDAP_SCOPE_ONELEVEL.

bind (yes)
Whether or not to bind to the LDAP server. Newer LDAP
implementations don't require clients to bind, which saves
time. Example:
ldapsource_bind = no

If you do need to bind, you might consider configuring Postfix
to connect to the local machine on a port that's an SSL tunnel
to your LDAP server. If your LDAP server doesn't natively
support SSL, put a tunnel (wrapper, proxy, whatever you want to
call it) on that system too. This should prevent the password
from traversing the network in the clear.

bind_dn ("")
If you do have to bind, do it with this distinguished name.
Example:
ldapsource_bind_dn = uid=postfix, dc=your, dc=com

bind_pw ("")
The password for the distinguished name above. If you have to
use this, you probably want to make main.cf readable only by
the Postfix user. Example:
ldapsource_bind_pw = postfixpw

cache (no)
Whether to use a client-side cache for the LDAP connection. See
ldap_enable_cache(3). It's off by default.

cache_expiry (30 seconds)
If the client-side cache is enabled, cached results will expire
after this many seconds.

cache_size (32768 bytes)
If the client-side cache is enabled, this is its size in bytes.

dereference (0)
When to dereference LDAP aliases. (Note that this has nothing
do with Postfix aliases.) The permitted values are those
legal for the OpenLDAP/UM LDAP implementations:

0 never
1 when searching
2 when locating the base object for the search
3 always

See ldap.h or the ldap_open(3) or ldapsearch(1) man pages for
more information. And if you're using an LDAP package that has
other possible values, please bring it to the attention of the
[email protected] mailing list.

chase_referrals (0)
Sets (or clears) LDAP_OPT_REFERRALS (requires LDAP version 3
support.

version (2)
Specifies the LDAP protocol version to use.

debuglevel (0)
What level to set for debugging in the OpenLDAP libraries.

Don't use quotes in these variables; at least, not until the Postfix
configuration routines understand how to deal with quoted strings.

EXAMPLES
========

ALIASES
-------

Here's a basic example for using LDAP to look up aliases. Assume that in
main.cf, you have these configuration parameters defined:

alias_maps = hash:/etc/aliases, ldap:ldapsource
ldapsource_server_host = ldap.my.com
ldapsource_search_base = dc=my, dc=com

Upon receiving mail for a local address "ldapuser" that isn't found in
the /etc/aliases database, Postfix will search the LDAP server listening
at port 389 on ldap.my.com. It will bind anonymously, search for any
directory entries whose mailacceptinggeneralid attribute is "ldapuser",
read the "maildrop" attributes of those found, and build a list of their
maildrops, which will be treated as RFC822 addresses to which the
message will be delivered.

VIRTUAL DOMAINS/ADDRESSES
-------------------------

If you want to keep information for virtual lookups in your directory,
it's only a little more complicated. First you need to make sure Postfix
knows about the virtual domain. An easy way to do that is to add the
domain to the mailacceptinggeneralid attribute of some entry in the
directory. Next you'll want to make sure all of your virtual recipients'
mailacceptinggeneralid attributes are fully qualified with their virtual
domains. Finally, if you want to designate a directory entry as the
default user for a virtual domain, just give it an additional
mailacceptinggeneralid (or the equivalent in your directory) of
"@virtual.dom". That's right, no user part. If you don't want a catchall
user, omit this step and mail to unknown users in the domain will simply
bounce.

If you're using a version of Postfix newer than 19991226, that should do
it. If not, you also need to add your virtual domains to relay_domains.
Simply add "$virtual_maps" to your relay_domains line. Then you can use
the same map you use to find virtual recipients to determine if a domain
is a valid virtual domain and should be allowed to relay.

In summary, you might have a catchall user for a virtual domain that
looks like this:

dn: cn=defaultrecipient, dc=fake, dc=dom
objectclass: top
objectclass: virtualaccount
cn: defaultrecipient
owner: uid=root, dc=someserver, dc=isp, dc=dom
1 ->; mailacceptinggeneralid: fake.dom
2 ->; mailacceptinggeneralid: @fake.dom
3 ->; maildrop: [email protected]

1: Postfix knows fake.dom is a valid virtual domain when it looks for
this and gets something (the maildrop) back.

2: This causes any mail for unknown users in fake.dom to go to this entry ...

3: ... and then to its maildrop.

Normal users might simply have one mailacceptinggeneralid and maildrop,
e.g. "[email protected]" and "[email protected]".

OTHER USES
----------

Other common uses for LDAP lookups include rewriting senders and
recipients with Postfix' canonical lookups, for example in order to make
mail leaving your site appear to be coming from "[email protected]"
instead of "[email protected]".

NOTES AND THINGS TO THINK ABOUT
===============================

- The bits of schema and attribute names used in this document are just
examples. There's nothing special about them, other than that some are
the defaults in the LDAP configuration parameters. You can use
whatever schema you like, and configure Postfix accordingly.

- You probably want to make sure that mailacceptinggeneralids are
unique, and that not just anyone can specify theirs as postmaster or
root, say.

- An entry can have an arbitrary number of mailacceptinggeneralids or
maildrops. Maildrops can also be comma-separated lists of addresses.
They will all be found and returned by the lookups. For example, you
could define an entry intended for use as a mailing list that looks
like this (Warning! Schema made up just for this example):

dn: cn=Accounting Staff List, dc=my, dc=com
cn: Accounting Staff List
o: my.com
objectclass: maillist
mailacceptinggeneralid: accountingstaff
mailacceptinggeneralid: accounting-staff
maildrop: mylist-owner
maildrop: an-accountant
maildrop: some-other-accountant
maildrop: this, that, theother

- If you use an LDAP map for lookups other than aliases, you may have to
make sure the lookup makes sense. In the case of virtual lookups,
maildrops other than mail addresses are pretty useless, because
Postfix can't know how to set the ownership for program or file
delivery. Your query_filter should probably look something like this:

virtual_query_filter = (&(mailacceptinggeneralid=%s)(!(|(maildrop="*|*")(maildrop="*:*")(maildrop="*/*"))))

- And for that matter, even for aliases, you may not want users able to
specify their maildrops as programs, includes, etc. This might be
particularly pertinent on a "sealed" server where they don't have
local UNIX accounts, but exist only in LDAP and Cyrus. You might allow
the fun stuff only for directory entries owned by an administrative
account:

local_query_filter = (&(mailacceptinggeneralid=%s)(|(!(maildrop="*|*")(maildrop="*:*")(maildrop="*/*"))(owner=cn=root, dc=your, dc=com)))

So that if the object had a program as its maildrop and weren't owned
by "cn=root" it wouldn't be returned as a valid local user. This will
require some thought on your part to implement safely, considering the
ramifications of this type of delivery. You may decide it's not worth
the bother to allow any of that nonsense in LDAP lookups, ban it in
the query_filter, and keep things like majordomo lists in local alias
databases.

- LDAP lookups are slower than local DB or DBM lookups. For most sites
they won't be a bottleneck, but it's a good idea to know how to tune
your directory service.

FEEDBACK
========

If you have questions, send them to [email protected] Please
include relevant information about your Postfix setup: LDAP-related
output from postconf, which LDAP libraries you built with, and which
directory server you're using. If your question involves your directory
contents, please include the applicable bits of some directory entries.

CREDITS
=======

Manuel Guesdon: Spotted a bug with the ldapsource_timeout attribute.
John Hensley: Multiple LDAP sources with more configurable attributes.
Carsten Hoeger: Search scope handling.
LaMont Jones: Domain restriction, URL and DN searches, multiple result
attributes.
Mike Mattice: Alias dereferencing control.
Hery Rakotoarisoa: Patches for LDAPv3 updating.
Prabhat K Singh: Wrote the initial Postfix LDAP lookups and connection caching.
Keith Stevenson: RFC 2254 escaping in queries.
Samuel Tardieu: Noticed that searches could include wildcards, prompting
the work on RFC 2254 escaping in queries. Spotted a bug
in binding.
Sami Haahtinen: Referral chasing and v3 support.

And of course Wietse.
《解決方案》

理解與應用LDAP伺服器

關於LDAP的補充

--------------------------------------------------------------------------------


LDAP就是 light DAP, 輕量級目錄訪問協議, 可以想象 還有一個DAP,
70年代誕生的DAP協議基於 X.400目錄訪問協議。主要用於 大型主機,因為有大量不常用的功能而且這些不用的功能消耗了過多的系統資源,雖然極強大,但是應用不廣, 所以出現了LDAP.

這是一個開放的協議, 具體的實現有 Netscape LDAP, Novell NDS, MS AD等等,這3個是使用最廣,影響最大的。
Netscape LDAP server主要使用在unix或類unix系統上, MS AD自然只能在windows上, NDS是唯一一個跨平台的產品。注意: LDAP本身是平台無關的。

工作原因,比較熟悉NDS, AD最熟。我個人最喜歡NDS,AD當然最簡單,但是最不穩定,最亂,而且比較耗資源。

樓主說的類似資料庫,完全正確,因為它原本就是資料庫,只是不是關係型的資料庫,它是鏈式資料庫,詳細細節可以找本資料庫原理,很詳細的。

和關係資料庫一樣, LDAP內能夠定義哪些對象,每個對象可以有什麼屬性,每個屬性可以取什麼樣的值,這樣一個框架結構被稱為Schema,它是類,對象,屬性的集合。類又分為抽象類(只能做父類,不能實例化)和結構類(可以實例化),編程的朋友會發現和面向對象的編程的概念完全一樣。

舉例: LDAP內必須先有user類, 然後用user類創建user對象(一般預設有的),我們才能創建具體的用戶賬號(實例化), schema中user對象被指定了有哪些屬性,我們創建賬號的時候才能給賬號哪些屬性,例如 schema中user對象沒有別名屬性,我們就不能給賬號起別名。

Schema的擴展:
預設的schema一般預先創建有足夠的類,對象和屬性,例如 MS 的AD 預設有 170個類和833個對象和屬性。但是如果不能滿足需要的話,我們就可以擴展Schema, 一般是使用 LDAP API, 例如 MS的 ADSI, NDS有專門的工具,當然也可以直接使用LDAP查詢語言,來直接操作整個LDAP目錄樹。
《解決方案》

理解與應用LDAP伺服器

好文,淺顯易懂
《解決方案》

理解與應用LDAP伺服器

謝謝yanyp      
精靈王
兄弟

希望和CU兄弟共享
《解決方案》

理解與應用LDAP伺服器

確實好文!
樓主能不能對syntax '1.3.6.1.4.1.1466.115.121.1.5'做一個解釋呢?
我定義了一個attribute,讓它具有這個binary syntax。
可是,為什麼我在JNDI中看到的是String呢?
《解決方案》

理解與應用LDAP伺服器

你是怎麼定義的
《解決方案》

理解與應用LDAP伺服器

好文章,加精:-)
《解決方案》

理解與應用LDAP伺服器

謝謝樓主支持
《解決方案》

理解與應用LDAP伺服器

good!

[火星人 ] 理解與應用LDAP伺服器已經有915次圍觀

http://coctec.com/docs/service/show-post-13986.html