搞懂OpenLDAP

<strong>輕型目錄訪問協議</strong>(英文:<code>Lightweight Directory Access Protocol</code>,縮寫:<code>LDAP</code>)是一個開放的,中立的,工業標準的應用協議,通過IP協議提供訪問控制和維護分佈式信息的目錄信息。<p><code>OpenLDAP</code>是輕型目錄訪問協議(<code>Lightweight Directory Access Protocol</code>,<code>LDAP</code>)的自由和開源的實現,在其<code>OpenLDAP</code>許可證下發行,並已經被包含在衆多流行的<code>Linux</code>發行版中。</p>
<p>可以這樣講:市面上只要你能夠想像得到的所有工具軟件,全部都支持<code>LDAP</code>協議。比如說你公司要安裝一個項目管理工具,那麼這個工具幾乎必然支持<code>LDAP</code>協議,你公司要安裝一個<code>bug</code>管理工具,這工具必然也支持<code>LDAP</code>協議,你公司要安裝一套軟件版本管理工具,這工具也必然支持<code>LDAP</code>協議。<code>LDAP</code>協議的好處就是你公司的所有員工在所有這些工具裏共享同一套用戶名和密碼,來人的時候新增一個用戶就能自動訪問所有系統,走人的時候一鍵刪除就取消了他對所有系統的訪問權限,這就是<code>LDAP</code>。</p>
</blockquote>
<p>有些領域並不像前端世界那麼潮那麼性感,但是缺了這個環節又總覺得很彆扭。如果深入到運維的世界,你會發現大部分工具還活在上個世紀,產品設計完全反人類,比如<code>cn</code>, <code>dc</code>, <code>dn</code>, <code>ou</code>這樣的命名方式,如果不鑽研個一天兩天,鬼知道它在說什麼,比如說<code>dns</code>,<code>dns</code>是什麼鬼?域名嗎?不是,它只是某個懶惰的工程師起了<code>dn</code>這麼一個縮寫,再加一個複數,就成了<code>dns</code>,和域名服務器沒有任何關係;<code>cn</code>是什麼?中國的縮寫?你想多了,這和中國沒有任何關係。經過一系列這樣瘋狂的洗腦之後,你才能逐漸明白<code>LDAP</code>到底想幹什麼。拋棄你所有的認知,把自己當成一個什麼都不懂的幼兒園孩子,然後我們從頭學起<code>LDAP</code>。</p>
<p>如果你搜索<code>OpenLDAP</code>的安裝指南,很不幸地告訴你,網上不管中文的英文的,<code>90%</code>都是錯的,它們都還活在上個世紀,它們會告訴你要去修改一個叫做<code>slapd.conf</code>的文件,基本上看到這裏,你就不用往下看了,這個文件早就被拋棄,新版的<code>OpenLDAP</code>里根本就沒有這個文件!取而代之的是<code>slapd.d</code>的文件夾,然後另一部分教程會告訴你,讓你修改這個文件夾下的某一個<code>ldif</code>文件,看到這裏,你也不用往下看了,你又看到了僞教程,因爲這個文件夾下的所有文件的第一行都明確地寫着:『<code>這是一個自動生成的文件,不要修改它!</code>』你修改了它之後,它的<code>md5</code>校驗值會匹配不上,造成更多的問題。你應該用<code>ldapmodify</code>來修改這個文件,而關於<code>ldapmodify</code>的教程,可以說幾乎就沒有!我一開始不知道面臨這樣荒謬的處境,很多運維人員是怎麼活下來的,不過等我自己配通了以後,真的是累到連寫教程的精力都沒有了,好吧,我已經配通了,你們各人自求多福吧。</p>
<h1>架構</h1>
<p>實際上,我的操作步驟很多都是反的,架構這部分是最後才意識到的,但實際上從最一開始就應該先想到。實際上整個<code>OpenLDAP</code>的架構大致包含<code>3</code>個部分,而網上沒有教材提到這塊。</p>
<h2>OpenLDAP</h2>
<p>首先,是<code>OpenLDAP</code>的服務器本身,這個東西其實只相當於是一個<code>mysql</code>數據庫,它是沒有酷炫的圖形界面的,如果你願意每次都手敲一大堆代碼,也可以用它,但這種反人類的設計真的不是給人用的。</p>
<h2>phpLDAPadmin</h2>
<p>所以,你需要安裝一個叫作<code>phpLDAPadmin</code>的工具,好歹這是一個圖形界面,雖然奇醜無比,並且配置起來也並不容易。</p>
<h2>PWM</h2>
<p>光裝管理工具還不夠,你總要給用戶提供一個修改密碼的地方。</p>
<h2>客戶端</h2>
<p>最後,你還需要配置各種工具。</p>
<h2>架構圖</h2>
<p>我畫了一個簡單的架構圖如下:</p>
<p><span class="img-wrap"><img data-src="/img/bV9YDb?w=1278&h=869" src="https://cdn.segmentfault.com/v-5c03a88e/global/img/squares.svg" alt="圖片描述" title="圖片描述"></span></p>
<h1>安裝</h1>
<h2>安裝OpenLDAP</h2>
<p>安裝<code>OpenLDAP</code>非常簡單,直接安裝這<code>3</code>個東西就夠了,甚至運氣好的話,也許你的操作系統已經自帶安裝好了:</p>
<pre><code>yum install openldap openldap-clients openldap-servers</code></pre>
<p>安裝完了之後可以直接啓動<code>OpenLDAP</code>服務,不需要做任何配置,我一開始還有顧慮,後來發現完全不用多想直接啓動即可:</p>
<pre><code>service slapd start</code></pre>
<h2>配置OpenLDAP</h2>
<p>這一塊在最一開始是最麻煩的部分,網上所有教程講的都不對。因爲現在是<code>2018</code>年了,而很多教程還停留在<code>2008</code>年甚至<code>1998</code>年。配置<code>OpenLDAP</code>最正確的姿勢是通過<code>ldapmodify</code>命令執行<strong>一系列自己寫好的</strong>ldif文件,而<strong>不要修改任何OpenLDAP裝好的配置文件</strong>。</p>
<p>舉個例子來說,你要想修改<code>RootDN</code>,那麼你就自己寫這麼一個<code>ldif</code>文件,假設給它起名叫<code>a.ldif</code>,然後執行它就可以了:</p>
<pre><code>dn: olcDatabase={2}bdb,cn=config
changetype: modify
replace: olcRootDN
olcRootDN: cn=admin,dc=qiban,dc=com

replace: olcSuffix
olcSuffix: dc=qiban,dc=com</code></pre>
<p>怎麼執行呢?</p>
<pre><code>ldapmodify -Q -Y EXTERNAL -H ldapi:/// -f a.ldif</code></pre>
<p>這麼長的命令是什麼意思?<code>-Q</code>表示安靜執行,<code>-Y</code>和後面的<code>EXTERNAL</code>表示,好吧,我也不知道什麼意思,總之需要這樣配合,然後<code>-H</code>表示地址,<code>-f</code>表示文件名。幾乎所有的<code>ldapmodify</code>命令都這麼執行就好了。</p>
<p>再來講解一下上面的<code>ldif</code>文件的內容,你不要問爲什麼叫<code>ldif</code>這麼一個破後綴,總之你記住它就是這個後綴就好了。<code>dn</code>表示你要修改什麼東西,在這裏我們用的是<code>{2}bdb</code>,你的系統不一定是<code>{2}bdb</code>,不管是幾,總之你去查一下目錄裏的內容就好了:</p>
<pre><code>ls /etc/openldap/slapd.d/cn=config/</code></pre>
<p>得到的結果大概如下,不一樣也不要害怕:</p>
<pre><code>cn=module{0}.ldif cn=schema/ cn=schema.ldif olcDatabase={0}config.ldif olcDatabase={-1}frontend.ldif olcDatabase={1}monitor.ldif olcDatabase={2}bdb/ olcDatabase={2}bdb.ldif</code></pre>
<p>這裏面有一大堆奇奇怪怪的數字,不要擔心,其中有一個帶什麼<code>db.ldif</code>的就是你最終需要修改的數據庫文件,我這裏是<code>bdb.ldif</code>,你的可能是<code>mdb.ldif</code>,還有人是<code>hdb.ldif</code>,不管什麼<code>db</code>,總之你要改的是一個叫<code>db</code>的文件就對了,你可以<code>cat</code>打開看一看,但是不要用<code>vi</code>去修改它。</p>
<p><code>changetype</code>就是<code>modify</code>,表示我們要修改這個文件。第<code>3</code>行是<code>replace</code>,表示我們要替換裏面的某個值,你可以把這個操作理解爲<code>mysql</code>數據庫的<code>update</code>操作,如果你把第<code>3</code>行改成<code>add</code>,那就是<code>mysql</code>的<code>insert</code>操作了。不過這裏我們操作的只是配置文件本身,還牽涉不到添加用戶或者更改用戶,如果你以爲事情就這麼簡單,那就是你太天真了。</p>
<p><code>RootDN</code>在這裏就表示你整個<code>OpenLDAP</code>系統的管理員用戶名是什麼,不要奇怪,後面這一砣都是用戶名<code>cn=admin,dc=qiban,dc=com</code>,長的有點像<code>email</code>地址,實際意思也差不多,但總之就不是<code>email</code>就行了。不要問爲什麼,總之<code>cn</code>就是<code>email</code>前面的那個名字,後面帶<code>dc</code>的都是域名。</p>
<p>真實情況是你還需要給這個用戶設置一個密碼,具體怎麼設自行<code>Google</code>,但還是那句話:不要修改系統文件,要用ldapmodify來執行。</p>
<h2>添加memberOf模塊</h2>
<p>這個工作應該一開始就做好,要不然後面要做的話,還得把建好的組全刪掉再重建。這個模塊的作用是當你建一個組的時候,把一些用戶添加到這個組裏去,它會自動給這些用戶添加一個<code>memberOf</code>屬性,有很多應用需要檢查這個屬性。</p>
<p>添加的時候比較麻煩,需要建<code>3</code>個<code>ldif</code>文件,然後<code>1</code>個執行<code>ldapmodify</code>,<code>2</code>個執行<code>ldapadd</code>,錯一點都不行:</p>
<h3>memberof_config.ldif</h3>
<p>再一次重申:文件名叫做什麼根本無所謂,只要後綴名爲<code>ldif</code>即可。</p>
<pre><code>dn: cn=module,cn=config
cn: module
objectClass: olcModuleList
olcModuleLoad: memberof
olcModulePath: /usr/lib64/openldap

dn: olcOverlay={0}memberof,olcDatabase={2}bdb,cn=config
objectClass: olcConfig
objectClass: olcMemberOf
objectClass: olcOverlayConfig
objectClass: top
olcOverlay: memberof
olcMemberOfDangling: ignore
olcMemberOfRefInt: TRUE
olcMemberOfGroupOC: groupOfNames
olcMemberOfMemberAD: member
olcMemberOfMemberOfAD: memberOf</code></pre>
<p>小心第<code>5</code>行和第<code>7</code>行,先找到你的模塊目錄是不是在<code>/usr/lib64</code>下面,然後看清楚你的數據庫類型和數字,不要瞎複製。</p>
<p>對於這個文件,我們需要執行<code>ldapadd</code>:</p>
<pre><code>ldapadd -Q -Y EXTERNAL -H ldapi:/// -f memberof_config.ldif</code></pre>
<p>執行完之後,檢查你的<code>/etc/openldap/slapd.d/cn=config/</code>,看是不是多了一個模塊,這個模塊的數字編號直接影響下一步操作。</p>
<h3>refint1.ldif</h3>
<pre><code>dn: cn=module{0},cn=config
add: olcmoduleload
olcmoduleload: refint</code></pre>
<p>這個文件裏我的<code>memberOf</code>是第一個模塊,所以編號是<code>0</code>,你的不一定,要看清楚到底第幾號模塊是<code>memberof</code>,然後就改成幾就可以了,對於這個文件,我們要執行<code>ldapmodify</code>操作:</p>
<pre><code>ldapmodify -Q -Y EXTERNAL -H ldapi:/// -f refint1.ldif</code></pre>
<p>你如果能看懂它的意思的話,它的大意是說要修改我們剛剛添加的那個模塊文件的內容。</p>
<h3>refint2.ldif</h3>
<pre><code>dn: olcOverlay={1}refint,olcDatabase={2}bdb,cn=config
objectClass: olcConfig
objectClass: olcOverlayConfig
objectClass: olcRefintConfig
objectClass: top
olcOverlay: {1}refint
olcRefintAttribute: memberof member manager owner</code></pre>
<p>對這個文件執行<code>ldapadd</code>操作:</p>
<pre><code>ldapadd -Q -Y EXTERNAL -H ldapi:/// -f refint2.ldif</code></pre>
<p>還是要注意檢查<code>db</code>類型,否則你一定不能成功。</p>
<h2>安裝phpLDAPadmin</h2>
<p>好吧,幹完了上面這些囉裏巴嗦的事情,你可以先給自己泡杯咖啡,接下來還有很多工作要做,不過難度已經沒有剛纔那麼大了。</p>
<p>我們開始安裝<code>phpLDAPadmin</code>。</p>
<pre><code>yum install phpldapadmin</code></pre>
<p><code>CentOS</code>的<code>yum</code>安裝總是這麼令人賞心悅目。</p>
<h2>配置phpLDAPadmin</h2>
<p>接下來讓我們在<code>nginx</code>裏配置好它,以便讓我們的管理員能夠看到它。</p>
<pre><code> location /htdocs {
alias /usr/share/phpldapadmin/htdocs;
index index.php;
location ~ .php$ {
alias /usr/share/phpldapadmin;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}</code></pre>
<p>缺省文件安裝在<code>/usr/share/phpldapadmin/htdocs</code>下,我們必得要在這裏配置一個<code>alias</code>才能訪問到它,但在<code>php-fpm</code>時又要配置另外一個<code>alias</code>,這也是比較坑人的一個地方。</p>
<p>接下來你需要修改<code>/etc/phpldapadmin/config.php</code>這個文件,裏面有大段大段的註釋,看到人頭暈,注意這麼<code>2</code>點就夠了,其它的都不要改:</p>
<ul>
<li>把<code>$servers->setValue('login','anon_bind',false);</code>改成<code>false</code>,因爲我們不想讓人匿名訪問;</li>
<li>把<code>$servers->setValue('login','allowed_dns',array('cn=admin,dc=qiban,dc=com'));</code>,我們只允許管理員訪問,其他任何人不得訪問。</li>
</ul>
<h2>使用phpLDAPadmin</h2>
<p>你現在可以通過<code>URL</code>地址訪問<code>phpLDAPadmin</code>了,登錄的時候輸入你那一坨用戶名:<code>cn=admin,dc=qiban,dc=com</code>,然後輸入密碼,如果你前面一切都設置對了,那麼這裏就可以登錄進去了。</p>
<p><span class="img-wrap"><img data-src="/img/bV9YDo?w=1251&h=821" src="https://cdn.segmentfault.com/v-5c03a88e/global/img/squares.svg" alt="clipboard.png" title="clipboard.png"></span></p>
<p>界面裏透出一股濃濃的上世紀九十年代風格,不過好歹我們終於可以脫離純手寫代碼管理的窘境了。</p>
<p>這時候你首先要建立兩個<code>organizationalUnit</code>,一個叫作<code>groups</code>,一個叫作<code>users</code>。不要問爲什麼。</p>
<p>然後在<code>users</code>下面建幾個<code>inetOrgPerson</code>,這些就是你的用戶了。注意,在創建新條目時,一定要選擇<code>默認</code>,不要選擇什麼<code>Posix</code>或者<code>Generic User Account</code>,那隻會幫你建出一堆沒用的<code>Linux</code>賬號出來,我們只想要<code>web</code>用戶,不想建什麼<code>Linux</code>用戶。<strong>注意:密碼這個地方一定要選<code>md5</code>,否則你後面和其它系統連接會出問題。</strong></p>
<p>然後在<code>groups</code>下面建幾個組吧,比如<code>admins</code>, <code>users</code>等等,注意選擇<code>objectClass</code>爲<code>groupOfNames</code>就行了。然後把你剛剛建好的幾個用戶分門別類的給他們加到組裏去。</p>
<p>在這一步上,如果你前面配置<code>memberOf</code>模塊配置正確的話,你會在<code>user</code>的<code>顯示內部屬性</code>裏看到它的<code>memberOf</code>屬性,如果看不到,說明你沒有配對。</p>
<h2>配置第三方應用</h2>
<p>到此爲止,似乎真沒有什麼好說的了,<code>Phabricator</code>, <code>Confluence</code>, <code>Zabbix</code>, <code>Grafana</code>, <code>禪道</code>等等,幾乎你能想到的任何一個第三方應用都會有說明書教你怎麼配置<code>dc</code>, <code>cn</code>, <code>ou</code>這些東西,經過了上面這一番折騰,你怎麼着也應該對<code>LDAP</code>的一些術語有所瞭解了,如果還是不行,說明你玩它的時間還是不夠長,再多玩兩天,也就明白了。</p>
<p>配置好之後的好處就是你再也不用東一塊西一塊地建用戶了,而可以在一個統一的地方集中管理你的用戶和羣組授權。</p>
<h1>結語</h1>
<p>總之,配置<code>OpenLDAP</code>不是一個輕鬆的活,但是考慮到有那麼多第三方應用都支持這個鬼東西,花點代價把它配通還是值得的。希望你一切順利。</p>

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章