OpenLDAP:用ACL控制訪問許可權
用ACL控制授權
我們在LDAP中建立目錄樹後,最感興趣的就是如何控制使用者在目錄樹中的許可權(讀寫)。誰在什麼條件下有記錄許可權,我們有許可權看到哪些資訊。ACL(Access Control List)訪問控制列表就是解決使用者許可權問題的。
我們要把ACL寫在哪裡?
ACL寫在OpenLDAP的服務端全域性配置檔案slapd.conf中,如下這段即為其指令:
# access to dn.base="" by * read
# access to dn.base="cn=Subschema" by * read
# access to *
# by self write
# by users read
# by anonymous auth
也可以寫在一個單獨的檔案中,如access.conf,然後在全域性配置檔案slapd.conf中
呼叫,在配置檔案中引入這個檔案即可,如下:
include /etc/openldap/access.conf
include後面的路徑為該檔案的放置地址。
ACL語法基礎
怎麼看懂ACL指令?
首先看下ACL訪問指令的格式:
################################################
access to [resources]
by [who] [type of access granted] [control]
by [who] [type of access granted] [control]
# More 'by' clauses, if necessary....
################################################
指令中包含1個to語句,多個by語句。
這個指令的大體意思是,通過access to約束我們訪問的範圍(resources),
通過by設定哪個使用者(who)獲取對這個約束範圍有什麼許可權(type of access granted),
並控制(control)這個by語句完成後是否繼續執行下一個by語句或者下一個ACL指令。
如果對ACL指令很熟悉的話,可以不必繼續往下看,因為以下為詳細的指令基礎介紹。
現在對ACL指令分解成兩大部分進行詳細說明,一個是access to指令, 一個是 by指令。
先看看access to吧。
以上內容意思是,
dn.base: 約束這個特定DN的訪問。他和dn.exact和dn.baselevel是相同的意思。
dn.one: 約束這個特定的DN第一級子樹的訪問。dn.onelevel是同義詞。
dn.children: 這個和dn.subtree類似,都是對其以下的子樹訪問權的約束。不同點在於,
這個的約束是不包含自己本身DN。而subtree包含了本身的DN。
#######################################################################
對於dn的約束條件還可以利用模糊約束,如下:
access to dn.regex="uid=[^,]+,ou=Users,dc=example,dc=com"
by * none
dn.regex是用來做匹配(match)用的。
這個指令將約束所有uid=(任何值),ou=Users,dc=example,dc=com的DN,其中的任何值是用 [^,]+ 這個符號組合來表示的,他可以代表任何至少有1個字元,且字元當中沒有逗號(,)的值。
更明確點說,意思就是在ou=Users,dc=example,dc=com這個DN下的所有以uid為屬性的一級子樹都屬於這個約束的範圍。
2. 通過約束attrs訪問
對於DN的約束大多用在對某個層級的約束,而用attrs的話,就可以跨層級(或者說跨越父類樹),通過屬性來約束訪問的範圍。
access to attrs=homePhone
by * none
這個例子意思是,任何人都沒有許可權訪問屬性為homePhone的資訊。
在attrs後面的值可以多個,如
access to attrs=homePhone,homePostalAddress
如果想約束某個物件類(Object class)的所有屬性,我們或許可以有這樣的形式:
access to attrs = title, registeredAddress, destinationIndicator,……
但這個方法太耗時,也難以閱讀,顯得笨重,以下給出一個好的方法:
access to [email protected]
by * none
用@的方法必須謹慎,這段指令不僅僅約束了organizationalPerson裡的屬性,也約束
了person物件類的屬性。為什麼?因為organizationalPerson物件類是person的子類,
因此,所有person中的屬性就當然也是organizationalPerson的屬性了。
如果想做除了organizationalPerson的其他物件類的約束,可以用!來表示:
access to attrs=!organizationalPerson
也可以加入屬性的值,具體約束某個值:
access to attrs=givenName val="Matt"
這個指令也可以用模糊約束的方法,如下:
access to attrs=givenName val.regex="M.*"
最後給個一般情況下用到的利用屬性約束的例子:
access to attrs=member val.children="ou=Users,dc=example,dc=com"
by * none
1. 通過Filters訪問
Filters提供一種支援條目記錄匹配的方法,如下:
access to filter="(objectClass=simpleSecurityObject)"
by * none
這表示我們可以約束所有記錄中包含物件類為simpleSecurityObject的資訊。
與程式語言類似, ACL指令也有類似與或的條件判斷,如下:
access to
filter="(|(|(givenName=Matt)(givenName=Barbara))(sn=Kant))"
by * none
這段程式碼過濾出givenName為Matt或者Barbara,或者surname為Kant的資訊。
Access to [resources]
resources可以有多種形式,如DN,attrs, Filters.
以下即詳細說明。
1. 通過約束DN進行訪問
如下所示,
access to dn="uid=matt,ou=Users,dc=example,dc=com"
by * none
這個指令是指訪問uid=matt,ou=Users,dc=example,dc=com這個DN,即把訪問的
範圍約束在這個DN中。
by * none是指對於任何人的訪問都是拒絕的。
總體的意思就是,任何人都沒有許可權訪問uid=matt,ou=Users,dc=example,dc=com這個DN,當然,伺服器管理員是可以訪問的,不然它無法維護這個OpenLDAP中的使用者資訊。
再來看一個,
access to dn.subtree="ou=Users,dc=example,dc=com"
by * none
在這個例子中,我們用了dn.subtree。在我們的目錄資訊樹中,在ou=Users子樹下可能有多個使用者。舉例來說,DN為uid=matt,ou=Users,dc=example,dc=com就是ou=Users, dc=example,dc=com的子樹,當要試圖訪問他時,這個ACL指令就起了作用。
總體的意思是,任何人都沒有許可權訪問ou=Users,dc=example,dc=com以及其子樹的資訊。
#######################################################################
※此處插播1個知識點
dn.base: Restrict access to this particular DN. This is the default, and
dn.exact and dn.baselevel are synonyms of dn.base.
dn.one: Restrict access to any entries immediately below this DN.
dn.onelevel is a synonym.
dn.children: Restrict access to the children (subordinate) entries of this DN.
This is similar to subtree, except that the given DN itself is not restricted by the rule.