Linux伺服器 Linux伺服器

網站伺服器建置與管理上課補充教材

網站伺服器建置與管理 > 課程內容 > 第 7 堂課 - 身份識別伺服器與內部檔案系統伺服器

第 7 堂課 - 身份識別伺服器與內部檔案系統伺服器

上次更新日期 2017/11/21
如果你有一群員工大家彼此共用數台電腦,你應該會期望每個員工都可以使用自己的帳號與密碼登入系統,然後在每台電腦上面都能夠取得前一次登入時的工作環境。 這時你就需要一台統一管理帳密的伺服器,以及一台提供登入後取得家目錄的檔案伺服器,當然,這兩台也可以是同一部伺服器系統就是了。 然後讓所有的員工電腦以這兩個服務來管理帳號與檔案系統,那就可以達成你的願望了!這也是目前本單位電腦教室裡面的實做結果喔!
  • 7.1: 身份識別與檔案系統間的關係
  • 7.2: LDAP 簡介
  • 7.3: LDAP 的實際設定流程
  • 7.4: LDAP 資料庫簡易管理 (新增/刪除/修改用戶參數)
  • 7.5: 分享檔案系統的 NFS 伺服器
  • 7.6: 課後練習

7.1: 身份識別與檔案系統間的關係

以電腦教室為例,如果讓每個學生預設都以同一個帳號登入,那麼學生在座位上面的調整就會比較沒有彈性,如果課程是有延續性質的, 那學生就得要坐到前一次上課的座位,否則就無法取得上次操作的環境與檔案。因此,許多電腦教室或辦公室,可能都會提供一個檔案伺服器來給學生或員工掛載使用, 例如底下的圖示,就是以 NFS 服務來提供檔案系統的範例:

NFS 示意圖

不過檔案系統也是需要驗證的,否則所有人都可以讀取任何人的檔案資料,那就天下大亂了!因此就需要有身份驗證系統才行。 所以,我們也才能夠透過身份驗證系統登入每一部主機,這樣在出問題時,也比較好查詢到到底是那一位學生或員工惡意使用所造成的問題, 比較好釐清責任歸屬囉。

總結說明身份識別與檔案系統間的關係就是:在一組或一間伺服器機房內,所有的伺服器均需要使用同一組帳號與密碼來登入, 並取得相同家目錄時,就需要這樣的設備需求。此種狀況常見的環境有:

  • 在大型數值模式模擬中,經常需要跨不同的運算節點 (computing node) 來操作,以讓一個模擬的工作,可以透過多台高性能的系統共同運作, 以期待快速達成模式運算的結果。因為每台 node 都需要讀取相同的檔案系統 (連檔名都要相同),且操作的程序 (process) 也需要相同的帳號 (連同 UID/GID 最好都相同), 因此,在這些運算節點中,每部系統的帳號以及檔案系統,就都得要同步才行。
  • 在崑山資傳系操作電腦教室的電腦時,所有的電腦均可以使用你的學號登入,並且可以取得你的個人桌面與額外的三個檔案系統。 因此在資傳系上課時,你可以在五間電腦教室的任何一間,使用相同的帳密登入,並可取得前一次上課的桌面與工作家目錄。所以如果對當前的座位不滿意, 可以立刻換座位,也不會影響到你的正常操作。

再次強調該功能就得要有兩個元件:

  • 使用身份識別功能:就是 ID 認證的服務。常見的服務有: NIS, LDAP, AD(windows), Kerboros...
  • 使用者家目錄的取得:就是個人檔案資料。常見的服務有: NFS, SMB(網芳), AD(windows)...

以純粹 linux 的伺服器環境來說,最容易設定的其實是 NIS 與 NFS 兩者的搭配,不過 NIS 對於 windows 的支援較差,所以如果考量到未來的系統規劃, 建議是可以使用跨平台的 LDAP 來取代 NIS 作為身份識別系統較佳。至於檔案系統方面,雖然 SAMBA 才是預設可以提供跨平台的檔案系統, 不過在運作的效能方面,還是以 NFS 較為強大,因此作為 Server 的環境來說,當然首選還是使用 NFS 的。故底下將以 LDAP 搭配 NFS 來進行整體系統架構的設定。

7.2: LDAP 簡介

LDAP 全名: Lightweight Directory Access Protocol,主要的功能在於『目錄服務 (directory service)』的提供!什麼是『目錄服務』呢? 從 wiki 上的說明來看,目錄服務指的是:

目錄服務是一個儲存、組織和提供資訊存取服務的軟體系統,在軟體工程中,一個目錄是指一組名字和值的對映。它允許根據一個給出的名字來尋找對應的值,與詞典相似。 像詞典中每一個詞也許會有多個詞義,在一個目錄中,一個名字也許會與多個不同的資訊相關聯。 類似地,就像一個詞會有多個不同的發音和多個不同的詞義,目錄中的一個名字可能會有多個不同類型的值。

目錄也許只提供範圍非常小的節點類型和數值類型,也可能對任意的或可延伸的一組類型提供支援。在一個電話目錄中,節點就是姓名而數值項就是電話號碼。 在DNS中,節點是域名而數值項是IP位址(還有別名,郵件伺服器名等等)。 在一個網路作業系統的目錄中,節點是那些由作業系統所管理的資源,包括用戶、電腦、印表機和其它共享資源。

簡單的說,就是你可以提供一個查詢的資料對應的內容,舉例來說,你可以提供一個『帳號名稱』,而在這個帳號名稱底下給予對應了密碼、UID、GID、真實姓名等資訊, 若用戶端使用帳號名稱來查詢目錄服務,則可以得到該帳號的密碼、UID等等資訊就是了。而且目錄服務還不只提供這些資料,你想要額外增加什麼節點都可以! 所以用途相當廣泛。

  • LDAP 的組成

基本上,你就將 LDAP 想成是一個目錄,而每個目錄都有個目錄名稱,然後根據不同需求,可以給予更多的目錄節點。 至於目錄的內容,則根據目錄的定義來給予鄉對應的內容就是了。至於目錄的節點還是需要根據不同的層級給予不同的設定才行。 單純以節點的角度來看,以一個公司名稱為『 example.com 』的位置來說,該公司的相關部門位置節點有點像這樣:

LDAP
圖示來源:http://dbaontap.com/2016/07/20/oem-13c-ldap-authentication/

如上所示,公司底下有兩個部門 (organization unit),一個是伺服器部門 (Servers) 一個是人資部門 (People) ,其中人資部門底下管理著員工證號 (Person, udid), 大概就是這樣一層一層的分配下來~而每一個節點底下可以搭配不同的資料給予特別的任務就是了。而如果是不同部門的相似架構呢?則可以用底下圖示來說明:

LDAP
圖示來源:http://dbaontap.com/2016/07/20/oem-13c-ldap-authentication/

在公司 (company.com) 內部的兩大部門 (location1, location2) 個別提供了各自的帳號密碼管理機制之類的,可以再細分下去之意。 因此,只要找尋不同的 location 即可取得各自部門的人資訊息。

在比較學理的組成說明如下:

  1. 可以提供非關聯性的資料庫環境,而每一筆資料則透過判別名稱 (distinguished name, DN) 來提示定義。 例如上圖的 Organization unit 可以分別是兩者無關的部門 (People 與 Servers 明顯就是不同且無關的部門定義)
  2. 每一個組織均需要定義最頂層的判別名稱,就被稱為 baseDN,這也是整個 LDAP 系統最先要設定的項目。 例如上圖的『 dc=exmpale,dc=com 』以及底下的『 dc=company,dc=com 』都是所謂的 baseDN !你可以猜測在組織 (Organization) 那一層的名稱, 就是 baseDN 的意思了。
  3. 每一筆查詢資料稱為 DN (Distinguished Name),而 DN 就是呼叫出目錄節點的位置所在。例如上面提到的 baseDN 就是一例。 他的展現方式就是『 dc=exmaple,dc=com 』,從小範圍寫起直到最頂層 (dc=com) 為止。 事實上,DN 的展示方式其實有點像 DNS,不過需要使用 dc, ou, cn 等來進行名稱的指定。dc (domain component) 一般用在公司或最頂層 DN 的設定, ou (organization unit) 一般用在大部門的設定上, cn (common name) 一般用在非上述兩個用途的其他應用上。
  4. 每個 baseDN 底下還有附屬組織單位,那就是 organization unit 的概念。例如人事部門可以使用類似: 『 dn: ou=People,dc=example,dc=com 』之類的方式來命名。而該 DN 底下就會有多種屬性定義!這些屬性定義就牽涉到每一個 LDAP 的用途為何。
  5. 因為 LDAP 僅是一個『目錄服務』的提供者,但這些目錄底下資料的定義使用的功能為何,就是透過預先定義的綱要檔 (Schema) 來定義。 舉例來說, Linux 與 Windows 的帳號所需要的項目並不相同,因此使用 LDAP 作為 Linux 的帳號認證來源時,就得要使用 LDAP 提供的 Linux 帳號所需綱要檔 (schema)
  • LDAP 的架設流程簡介

如果確定要架設 LDAP 作為你的身份驗證來源,那麼你得要事先規劃好這部 LDAP 所提供的 baseDN、相關的管理者密碼、相關的帳號 UID 起始號碼、 相關的使用者家目錄 (最好不要跟系統預設的 /home 相同位置,否則容易造成本機帳號與網路帳號衝突的狀況)等等。至於一般的架設流程大概是這樣的:

  1. 安裝好 LDAP 伺服器軟體,並且提供登入 LDAP 功能的 RootDN 密碼
  2. 載入 LDAP 所需要的環境設定參數檔
  3. 啟動 LDAP 服務,並觀察 LDAP 服務的埠口,以啟用防火牆放行的功能
  4. 預先指定好自己公司即將使用的 baseDN 環境 (最好與 DNS 系統相同即可),同時規劃好即將要使用的用戶端作業系統有哪些
  5. 開始載入基本的 baseDN 功能
  6. 開始載入用戶端作業系統所需要的綱要檔 (schema)
  7. 嘗試取得用戶端所需要的帳號參數範例檔,變轉為 LDAP 所需要的格式 (LDAP Data Interchange Format, LDIF) ,然後載入到 LDAP 伺服器內
  8. 若需要加密環境,請前往 /etc/pki/tls/certs 目錄下進行所需要的 key 建制
例題 7.2.A 大致定義出你的 LDAP 頂層與基礎名稱判別:
  1. 依據你的主機名稱的網域名稱,定義你的 baseDN 為何?
  2. 依據上述 baseDN 的指定,定義出管理 RootDN 的管理員密碼為 cn=Manager,(baseDN) (Manager 為管理部份的意思)

7.3: LDAP 的實際設定流程

為了避免 Server/client 之間名稱解析產生的連線延遲,因此 IP 對應主機名稱最好還是寫入 /etc/hosts 較佳。所以,先檢查一下你的 Server/client 的設定是否已經正確設定在 /etc/hosts 了呢?基本上,相關的設定在前幾周都已經完成,我們還是來持續檢查一下:

[root@localhost ~]# cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.254.xxx pcxxx.dic.ksu   pcxxx
192.168.254.254 pc254.dic.ksu   pc254
10.255.xxx.254  server.lanxxx.dic.ksu   server   <==這個項目
10.255.xxx.1    client.lanxxx.dic.ksu   client   <==這個項目

上面的設定是相當重要的!這是因為如果我們想要使用加密過後的 LDAP 加密傳輸連線,那麼就得要建立金鑰系統,而金鑰系統裡面會建立一隻憑證, 該憑證就只能使用對應的主機名稱而已!因此,如果我們未來使用的主機名稱無法在這個檔案內找到正確的 IP,那就會無法連線成功的! 這裡請特別特別留意!否則會出大事情!

例題 7.3.A:請注意自己的主機名稱對應資訊
  • 再次使用 hostnamectl 查看自己的主機名稱
  • 再次分析 Server/Client 系統上,針對目前這部主機名稱都可以找到正確的 IP
  • Step 1、安裝 LDAP 相關軟體、啟動 slapd 服務以及了解 LDIF 格式與匯入 LDIF 檔案

要能夠執行 LDAP server 至少也需要 openldap-servers, openldap-clients, openldap 等軟體才行~不過,後續我們會用到 Linux 帳號轉成 LDAP 帳號的機制, 那就得要額外安裝 unix 帳號轉 ldap 帳號的轉換腳本 migrationtools 這個軟體才行!

安裝完畢之後,我們就可以啟動一個名為 slapd (standard alone ldap daemon) 的服務,啟動這個服務之後,系統會多出一個 port 389 的埠口喔! 你應該使用 netstat 去觀察一下該埠口是否順利啟動為宜。同時也要能夠處理防火牆才好。

例題 7.3.B:依據上述說明分別完成底下任務:
  1. 安裝所需要的四個軟體
  2. 啟動、開機啟動 slapd 服務,同時觀察一下該服務!
  3. 觀察埠口,是否有 port 389 的產生?
  4. 觀察防火牆,僅針對內部網路 (10.xxx) 來說,是否還需要額外放行防火牆規則?

軟體安裝完成之後,可以透過 openldap 提供的 slappasswd 來建立管理員密碼,並將加密過後的密碼寫入到設定檔中!那麼設定檔在哪裡呢? 大部分的設定檔放置在 /etc/openldap/slapd.d/cn=config/ 目錄下,你可以自行查閱相關資訊。跟整個系統運作比較有關係的僅有『 olcDatabase={2}hdb.ldif 』 『 olcDatabase={1}monitor.ldif 』而已!其他的檔案都暫時不要理他!

[root@localhost ~]# ll /etc/openldap/slapd.d/cn=config
drwxr-x---. 2 ldap ldap   29 11月 13 16:36 cn=schema
-rw-------. 1 ldap ldap  378 11月 13 16:36 cn=schema.ldif
-rw-------. 1 ldap ldap  513 11月 13 16:36 olcDatabase={0}config.ldif
-rw-------. 1 ldap ldap  443 11月 13 16:36 olcDatabase={-1}frontend.ldif
-rw-------. 1 ldap ldap  562 11月 13 16:36 olcDatabase={1}monitor.ldif   <==次重要,需要設定 baseDN
-rw-------. 1 ldap ldap  609 11月 13 16:36 olcDatabase={2}hdb.ldif       <==最重要!設定 RooDN 與密碼

我們可以先觀察一下 olcDatabase={2}hdb.ldif 這個檔案,這個檔案的內容有點像這樣:

[root@localhost ~]# cat /etc/openldap/slapd.d/cn\=config/olcDatabase\=\{2\}hdb.ldif
# AUTO-GENERATED FILE - DO NOT EDIT!! Use ldapmodify.  <==警告你不要亂動!
# CRC32 17dc8434
dn: olcDatabase={2}hdb                                 <==由 dn: 開始規範!
objectClass: olcDatabaseConfig
objectClass: olcHdbConfig
olcDatabase: {2}hdb
olcDbDirectory: /var/lib/ldap
olcSuffix: dc=my-domain,dc=com                         <==這個需要修改
olcRootDN: cn=Manager,dc=my-domain,dc=com              <==這個需要修改
olcDbIndex: objectClass eq,pres
olcDbIndex: ou,cn,mail,surname,givenname eq,pres,sub
structuralObjectClass: olcHdbConfig
entryUUID: 89a43254-5c99-1037-9195-4dd67b9a1981
creatorsName: cn=config
createTimestamp: 20171113083650Z
entryCSN: 20171113083650.307710Z#000000#000#000000
modifiersName: cn=config
modifyTimestamp: 20171113083650Z

上面的檔案格式我們稱為 LDAP 的資料交換格式檔 (LDAP Data Interchange Format, LDIF),基本上就是由一個 dn: 開頭, 撰寫出你想要影響的項目,然後底下加入所需要的動作或者是資料即可。如上所述,其實我們的 baseDN (就是那個 olcSuffix) 以及 RootDN 都需要改變! 因此:

  • 先設計出一個 LDIF 格式的檔案;
  • 再以 ldapmodify 來匯入該筆紀錄。

如上所述,我們要修改兩個項目,可以使用 basedn.ldif 這樣的檔名來處理即可!另外,請記得我們要改的檔案檔名: /etc/openldap/slapd.d/cn=config/olcDatabase={2}hdb.ldif 其中 cn=config 是上層目錄 (所以寫在後面),olcDatabase=(2)hdb.ldif 則寫在前面!因此可以這樣來設計:

[root@localhost ~]# mkdir ldap
[root@localhost ~]# cd ldap
[root@localhost ldap]# vim basedn.ldif
dn: olcDatabase={2}hdb,cn=config           <==就是這個 dn 的設計!
changetype: modify                         <==動作是修改!
replace: olcSuffix                         <==取代這個項目
olcSuffix: ${basedn}                       <==實際的值!

dn: olcDatabase={2}hdb,cn=config
changetype: modify
replace: olcRootDN
olcRootDN: ${rootdn}

dn: olcDatabase={2}hdb,cn=config
changetype: modify
replace: olcRootPW
olcRootPW: ${rootdn_password}

[root@localhost ldap]# ldapmodify -Y EXTERNAL  -H ldapi:/// -f basedn.ldif

當然!上述的 ${basedn} 與 ${rootdn} 是需要實際帶入你的設定值的。最後,因為 RootDN 的管理員最好是需要密碼的,我們可以使用 slappasswd 來設定好加密的密碼, 然後修改上面畫面中的 ${rootdn_password} 項目即可!

例題 7.3.C:設定好你的 LDAP 基礎設定如下:
  1. 建立 LDAP 的系統管理員操作密碼為 2727175,同時將密碼、RootDN, BaseDN 寫入於 basedn.ldif 檔案內
  2. 使用『 ldapmodify -Y EXTERNAL -H ldapi:/// -f basedn.ldif 』匯入 basedn.ldif 的內容,如果一切順利,應該會看到類似底下的輸出:
    SASL/EXTERNAL authentication started
    SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
    SASL SSF: 0
    modifying entry "olcDatabase={2}hdb,cn=config"
    modifying entry "olcDatabase={2}hdb,cn=config"
    modifying entry "olcDatabase={2}hdb,cn=config"
    
  3. 修改完成之後,再查詢一下 /etc/openldap/slapd.d/cn=config 內容是否順利修訂成功了。

設定好該項目後,接下來得要修改另一個檔案,那就是 cn=config/olcDatabase={1}monitor.ldif 囉!這個檔案的內容有點像這樣:

[root@localhost ldap]# cat /etc/openldap/slapd.d/cn\=config/olcDatabase\=\{1\}monitor.ldif
# AUTO-GENERATED FILE - DO NOT EDIT!! Use ldapmodify.
# CRC32 aa76501f
dn: olcDatabase={1}monitor
objectClass: olcDatabaseConfig
olcDatabase: {1}monitor
olcAccess: {0}to * by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=extern
 al,cn=auth" read by dn.base="cn=Manager,dc=my-domain,dc=com" read by * none
structuralObjectClass: olcDatabaseConfig
entryUUID: 89a42cc8-5c99-1037-9194-4dd67b9a1981
creatorsName: cn=config
createTimestamp: 20171113083650Z
entryCSN: 20171113083650.307568Z#000000#000#000000
modifiersName: cn=config
modifyTimestamp: 20171113083650Z

比較重要的就是有底線的那行字體而已~我們可以繼續修改 basedn.ldif 新增一個項目 (雖然如此一來,前面三個資訊會被重複覆蓋就是了!), 該項目內容有點像這樣:

dn: olcDatabase={1}monitor,cn=config
changetype: modify
replace: olcAccess
olcAccess: {0}to * by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=extern
 al,cn=auth" read by dn.base="${RootDN}" read by * none

然後重複匯入即可!

例題 7.3.D:持續設定好你的 LDAP 基礎設定如下:
  1. 修改 basedn.ldif 檔案,將上述的『 dn: olcDatabase={1}monitor,cn=config 』加入
  2. 使用『 ldapmodify -Y EXTERNAL -H ldapi:/// -f basedn.ldif 』匯入 basedn.ldif 的內容
  3. 修改完成之後,再查詢一下 /etc/openldap/slapd.d/cn=config 內容是否順利修訂成功了。
  • Step 2、修改資料庫,並載入 cosine, nis 等綱要檔

預設 /var/lib/ldap/ 目錄管理位置並沒有任何設定檔,所以管理員可以複製 OpenLDAP 提供的預設檔案來使用。

[root@localhost ~]# cp /usr/share/openldap-servers/DB_CONFIG.example /var/lib/ldap/DB_CONFIG
[root@localhost ~]# chown ldap:ldap /var/lib/ldap/DB_CONFIG

如前所述,LDAP 僅是一個提供目錄功能的服務,如果需要特定的帳號管理機制,可以透過系統預設提供的綱要檔 (schema) 來處理! 針對 Linux 帳號常用的綱要檔主要有:

  • cosine.ldif
  • nis.ldif
  • inetorgperson.ldif

這些檔案都放置在 /etc/openldap/schema/ 中,然後需要注意的是,剛剛我們是『修改 LDAP 資料庫』內容,所以使用的是 ldapmodify, 但現在是載入不存在 LDAP 內部的綱要檔 (schema),因此要改用 ldapadd 來處理才行!處理的方法跟 ldapmodify 很類似:

[root@localhost ~]# ldapadd -Y EXTERNAL -H ldapi:/// -f ${filename}
[root@localhost ~]# ldapadd -Y EXTERNAL -H ldapi:/// -f .../nis.ldif
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
adding new entry "cn=cosine,cn=schema,cn=config"  <==一定要看到這行,且沒有錯誤才對!
例題 7.3.E:完成底下的功能:
  1. 複製範本資料庫到 /var/lib/ldap 當中,且變更權限
  2. 匯入上述的三個綱要檔案,請務必小心,這三個綱要檔載入也有順序之分,要先載入 cosine 才行!

如果一切設定都順利搞定,那麼使用底下的指令查詢時,就會出現成功的樣式!

[root@localhost ~]# slaptest -u
config file testing succeeded
  • Step 3、建置 Linux 帳號系統所需要的節點

完成上述的 LDAP 基礎資訊之後,接下來要處理的就是建置 Linux 帳號所需要的基礎節點了。由於 Linux 帳號主要分為 1)帳號與 2)群組,所以我們需要在 LDAP 目錄設定內規範好這兩項資料! 基本上,我們需要在 base.ldif 這個檔案內宣告好我們所需要的帳號與密碼是在哪個節點上,一般來說,主要的節點會有:

  • dn: dc=dic,dc=ksu(最頂層設定)
    • dn: cn=Manager,dc=dic,dc=ksu(管理員節點)
    • dn: ou=People,dc=dic,dc=ksu(帳號與密碼)
    • dn: ou=Group,dc=dic,dc=ksu(群組項目)

了解了上述的節點功能之後,再來就是要寫成 LDIF 格式,好讓 LDAP server 能夠匯入這些資料。你可以寫一個名為 base.ldif 的檔案來處理:

[root@localhost ldap]# vim base.ldif
dn: dc=dic,dc=ksu
objectClass: top
objectClass: dcObject
objectclass: organization
o: dic ksu
dc: dic

dn: cn=Manager,dc=dic,dc=ksu
objectClass: organizationalRole
cn: Manager
description: Directory Manager

dn: ou=People,dc=dic,dc=ksu
objectClass: organizationalUnit
ou: People

dn: ou=Group,dc=dic,dc=ksu
objectClass: organizationalUnit
ou: Group 

依據你不同的設定項目,只要修改『 dc=dic,dc=ksu 』這一串數值即可!當然,也能用取代的方式處理掉~總之,最終你要將這個 base.ldif 匯入到你的 LDAP 才行。 但是此時我們需要的是 LDAP 的資料節點,而不是建置 LDAP 的資料庫欄位功能,因此我們得要使用 ldapadd 的方式來新增這些資料才可以喔! 基礎的指令是這樣的:

[root@localhost ~]# ldapadd -x -W -D "${RootDN}" -f LDIf_filename
[root@localhost ~]# ldapadd -x -W -D "cn=Manager,dc=dic,dc=ksu" -f /root/ldap/base.ldif
例題 7.3.F:完成底下的功能:
  1. 依據上面的說明,建置好你的 base.ldif 檔案內容
  2. 使用 ldapadd 的功能來匯入這個檔案的內容,若一切順利,應該會看到如下的狀態:
    [root@localhost ~]# ldapadd -x -W -D "cn=Manager,dc=dic,dc=ksu" -f base.ldif
    Enter LDAP Password:   <==這裡輸入你的 RootDN 密碼!
    adding new entry "dc=dic,dc=ksu"
    adding new entry "cn=Manager,dc=dic,dc=ksu"
    adding new entry "ou=People,dc=dic,dc=ksu"
    adding new entry "ou=Group,dc=dic,dc=ksu"
    
  • Step 4、設計好 Linux 帳號,並使用該預設帳號轉成範例資訊,以腳本大量建置 LDAP 帳號

如果要手動一個一個輸入 LDAP 帳號,確實有點麻煩!我們能不能將 Linux 帳號轉出來呢?當然可以!這就是重點項目啊! 我們在第一步驟安裝的 migrationtools 就是為了這個而存在的。不過,如前所述,為了擔心本地帳號與網路帳號相互重疊,因此我們可能會有幾個打算:

  • 假設使用者名稱為 ldapuser1 ~ ldap10
  • 預設使用者密碼為 mypassword123 這個密碼
  • 假設使用者的 UID 從 6001 開始編號
  • 假設使用者的 GID 也是從 6001 開始編號,且有對應的私有群組
  • 假設使用者的預設家目錄在 /home/rhome/ 底下

所以我們要先手動處理前兩個帳號來交互比對看看:

[root@localhost ~]# mkdir /home/rhome
[root@localhost ~]# useradd -d /home/rhome/ldapuser1 -u 6001 ldapuser1
[root@localhost ~]# useradd -d /home/rhome/ldapuser2 -u 6002 ldapuser2
[root@localhost ~]# echo "mypassword123" | passwd --stdin ldapuser1
[root@localhost ~]# echo "mypassword123" | passwd --stdin ldapuser2
[root@localhost ~]# id ldapuser1
uid=6001(ldapuser1) gid=6001(ldapuser1) groups=6001(ldapuser1)
[root@localhost ~]# id ldapuser2
uid=6002(ldapuser2) gid=6002(ldapuser2) groups=6002(ldapuser2)
[root@localhost ~]# ll /home/rhome
drwx------. 3 ldapuser1 ldapuser1 78 11月 13 22:39 ldapuser1
drwx------. 3 ldapuser2 ldapuser2 78 11月 13 22:40 ldapuser2

要開始進行 Linux 帳號轉成 LDAP 帳號的腳本之前,得要先修改一下系統預設的 baseDN 設定才行!所以你可能要修改一下底下的幾個位置:

[root@localhost ~]# vim /usr/share/migrationtools/migrate_common.ph
$DEFAULT_MAIL_DOMAIN = "dic.ksu";          # 71 行左右
$DEFAULT_BASE = "dc=dic,dc=ksu";           # 74 行左右
$EXTENDED_SCHEMA = 1;                      # 90 行左右

處理完畢之後,接下來我們得要將轉換的帳號清理一下~因為我們只想要轉換 ldap 的使用者與群組,因此先將重要資訊抽出來到 /root/ldap 目錄下, 簡易的動作如下:

[root@localhost ldap]# grep ldapuser /etc/passwd > user.txt
[root@localhost ldap]# grep ldapuser /etc/group > group.txt

最後使用 migrationtools 指令,將帳號與群組轉成 LDIF 格式如下:

[root@localhost ldap]# /usr/share/migrationtools/migrate_passwd.pl user.txt > user.ldif
[root@localhost ldap]# /usr/share/migrationtools/migrate_group.pl group.txt > group.ldif
[root@localhost ldap]# cat user.ldif
dn: uid=ldapuser1,ou=People,dc=dic,dc=ksu
uid: ldapuser1
cn: ldapuser1
sn: ldapuser1
mail: ldapuser1@dic.ksu
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: top
objectClass: shadowAccount
userPassword: {crypt}$6$.N5RlKpP$y0R8wngFH8X2wgzk3zh3yAc0zfa4iJsgXnljZfaBbTRL45br877DF4.w.FZsJfVePa/doErJFYe8JLovnvOVM0
shadowLastChange: 17484
shadowMin: 0
shadowMax: 99999
shadowWarning: 7
loginShell: /bin/bash
uidNumber: 6001
gidNumber: 6001
homeDirectory: /home/rhome/ldapuser1

[root@localhost ldap]# cat group.ldif
dn: cn=ldapuser1,ou=Group,dc=dic,dc=ksu
objectClass: posixGroup
objectClass: top
cn: ldapuser1
userPassword: {crypt}x
gidNumber: 6001

雖然接下來只要匯入這兩個檔案就可以建置好 LDAP 的資料,但是我們需要的帳號共有 100 個之多,因此上述的方式實在不太適合。因此, 先不要急著匯入~請改用底下的練習題來處理相關的任務!

例題 7.3.G:透過腳本大量建置 LDAP 帳號
  1. 先將剛剛建立的兩個測試帳號完整的刪除 (userdel -r ...)
  2. 寫一隻名為 /root/ldap/adduser.sh 的腳本,在這裡面以迴圈的方式來建置所有帳號所需要的資訊!因為密碼是相同的, 所以密碼可以複製。不過其他的項目請用變數來處理妥當。
    • 規範出最小 UID 與 GID 的號碼,變數定義為 minuid,依據上述設定,此數值應為 6000
    • 規範用戶家目錄為 home 變數,位於 /home/rhome 目錄下 (需要判定目錄存在否)
    • 規範用戶 LDIF 檔名為 /root/ldap/ldapuser.ldif, 群組檔名 /root/ldap/ldapgroup.ldif
    • 建立今日密碼日期,使用 $(( $(date +%s)/60/60/24 + 1 )) 決定
    • 建立迴圈,使用 for i in $( seq 1 100) 建置,內容為:
      • 使用者與群組名稱 username 為 ldapuser${i}
      • uid 與 guid 為 userid 數值為 minuid + i
      • 帶入上述轉換得來的兩個區段內容,將該內容變化,以變數處理之
      • 最終分別帶入兩個檔案中!
      • 複製由 /etc/skel 來的家目錄,請使用 chmod 修改權限為 700,再以 chown uid:uid 的方式以數值的方式來修改正規權限。
  3. 可以參考這裡的連結來參考,但請不要照抄!
  4. 記得執行完這個指令會產生 ldapuser.ldif, ldapgroup.ldif 檔案
  5. 最後再以『ldapadd -x -W -D "cn=Manager,dc=dic,dc=ksu" -f /root/ldap/ldap{user|group}.ldif』的方式來分別載入帳號、群組資訊。
  • Step 5、使用 ldapsearch 檢驗 LDAP 的查詢功能

如果一切順利,在上面的動作完成之後,基本上,我們的 LDAP 就已經完全設定好了。那麼如果我想要根據上述的設定查詢一下是否有問題, 該如何進行呢?簡單的處理方案,可以透過 ldapsearch 來處理。基本的 ldapsearch 語法有點像這樣:

# ldapsearch [-x] [-b baseDN] [-W -D "RootDN"] [-H ldap://hostname] [-ZZ] [查詢值] [-d1]

上述的選項與參數簡介如下:

  • -x :使用簡易認證,幾乎所有的 ldapsearch 都要使用到這個選項才能順利運作!
  • -b baseDN :如果有不同的幾個 ldapserver 的存在,那需要使用確切的 baseDN 時,才加這個項目。例如我們的環境為 dc=dic,dc=ksu, 則這個項目會是『 -b "dc=dic,dc=ksu" 』的操作情況。
  • -W -D "RootDN" :如果有需要增加 (ldapadd) 或者是操作資料庫等行為時,才需要使用這個項目,且需要輸入密碼才行。 以我們為例,那就是『 -W -D "cn=Manager,dc=dic,dc=ksu" 』的操作行為
  • -H ldap://hostname :指定到某個位置去搜尋 LDAP 資料,例如『 -H ldap://127.0.0.1 』這樣的操作。
  • -ZZ :目前用不到,後續步驟才會使用。這個是強迫 ldapsearch 使用加密的 TLS 來處理的意思。
  • -d1 :是偵錯模式,如果你搜尋出問題,加上這個項目,可以得到很多有用的資訊來解釋問題!
  • 查詢值 :例如想要找 ldapuser1 時,可以使用 cn=ldapuser1 之類的方式來處理!
# 以明碼方式查詢所有資料庫的內容
[root@localhost ~]# ldapsearch -x -H ldap://127.0.0.1 -b "dc=dic,dc=ksu"
# extended LDIF
#
# LDAPv3
# base <dc=dic,dc=ksu> with scope subtree
# filter: (objectclass=*)       <==這裡顯示所有的資料都要展示出來的意思!
# requesting: ALL
#

# dic.ksu
dn: dc=dic,dc=ksu
objectClass: top
objectClass: dcObject
objectClass: organization
o: dic ksu
dc: dic
....

# 只找出與 uid 為 ldapuser1 的資訊:
[root@localhost ~]# ldapsearch -x -H ldap://127.0.0.1 -b "dc=dic,dc=ksu" uid=ldapuser1
# extended LDIF
#
# LDAPv3
# base <dc=dic,dc=ksu< with scope subtree
# filter: uid=ldapuser1      <==顯示僅有 ldapuser1 的訊息!
# requesting: ALL
#

# ldapuser1, People, dic.ksu
dn: uid=ldapuser1,ou=People,dc=dic,dc=ksu
uid: ldapuser1
cn: ldapuser1
sn: ldapuser1
mail: ldapuser1@dic.ksu
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: top
objectClass: shadowAccount
userPassword:: e2NyeXB0fSQ2JC5ONVJsS3BQJHkwUjh3bmdGSDhYMndnemszemgzeUFjMHpmYTR
 pSnNnWG5salpmYUJiVFJMNDVicjg3N0RGNC53LkZac0pmVmVQYS9kb0VySkZZZThKTG92bnZPVk0w
shadowLastChange: 17486
shadowMin: 0
shadowMax: 99999
shadowWarning: 7
loginShell: /bin/bash
uidNumber: 6001
gidNumber: 6001
homeDirectory: /home/rhome/ldapuser1

# search result
search: 2
result: 0 Success

# numResponses: 2
# numEntries: 1

# 嘗試使用 TLS 的方式查詢
[root@localhost ~]# ldapsearch -x -H ldap://127.0.0.1 -b "dc=dic,dc=ksu" uid=ldapuser1 -ZZ
ldap_start_tls: Connect error (-11)
        additional info: TLS error -8172:Peer's certificate issuer has been marked as not trusted by the user.

你可以發現到,如果使用明碼查詢資料,一切都順暢!但是如果使用 TLS 加密機制查詢,那就出問題了! 顯示的結果是憑證系統出問題!這是因為我們尚未建置好所需要的憑證與私鑰的原因。如果想要進一步查出確實的問題點,那可以這樣進階顯示錯誤!

[root@localhost ~]# ldapsearch -x -H ldap://127.0.0.1 -b "dc=dic,dc=ksu" uid=ldapuser1 -ZZ -d1
ldap_url_parse_ext(ldap://127.0.0.1)
ldap_create
ldap_url_parse_ext(ldap://127.0.0.1:389/??base)
ldap_extended_operation_s
ldap_extended_operation
ldap_send_initial_request
ldap_new_connection 1 1 0
ldap_int_open_connection
ldap_connect_to_host: TCP 127.0.0.1:389
ldap_new_socket: 3
ldap_prepare_socket: 3
ldap_connect_to_host: Trying 127.0.0.1:389
ldap_pvt_connect: fd: 3 tm: -1 async: 0
attempting to connect:
connect success
ldap_open_defconn: successful
ldap_send_server_request
ber_scanf fmt ({it) ber:
ber_scanf fmt ({) ber:
ber_flush2: 31 bytes to sd 3
ldap_result ld 0x55d9b10a90d0 msgid 1
wait4msg ld 0x55d9b10a90d0 msgid 1 (infinite timeout)
wait4msg continue ld 0x55d9b10a90d0 msgid 1 all 1
** ld 0x55d9b10a90d0 Connections:
* host: 127.0.0.1  port: 389  (default)
  refcnt: 2  status: Connected
  last used: Wed Nov 15 11:20:11 2017


** ld 0x55d9b10a90d0 Outstanding Requests:
 * msgid 1,  origid 1, status InProgress
   outstanding referrals 0, parent count 0
  ld 0x55d9b10a90d0 request count 1 (abandoned 0)
** ld 0x55d9b10a90d0 Response Queue:
   Empty
  ld 0x55d9b10a90d0 response count 0
ldap_chkResponseList ld 0x55d9b10a90d0 msgid 1 all 1
ldap_chkResponseList returns ld 0x55d9b10a90d0 NULL
ldap_int_select
read1msg: ld 0x55d9b10a90d0 msgid 1 all 1
ber_get_next
ber_get_next: tag 0x30 len 12 contents:
read1msg: ld 0x55d9b10a90d0 msgid 1 message type extended-result
ber_scanf fmt ({eAA) ber:
read1msg: ld 0x55d9b10a90d0 0 new referrals
read1msg:  mark request completed, ld 0x55d9b10a90d0 msgid 1
request done: ld 0x55d9b10a90d0 msgid 1
res_errno: 0, res_error: <>, res_matched: <>
ldap_free_request (origid 1, msgid 1)
ldap_parse_extended_result
ber_scanf fmt ({eAA) ber:
ldap_parse_result
ber_scanf fmt ({iAA) ber:
ber_scanf fmt (}) ber:
ldap_msgfree
TLS: certdb config: configDir='/etc/openldap' tokenDescription='ldap(0)' certPrefix='cacerts' keyPrefix='cacerts' flags=readOnly
TLS: cannot open certdb '/etc/openldap', error -8018:Unknown PKCS #11 error.
TLS: could not get info about the CA certificate directory /etc/openldap/cacerts - error -5950:File not found.
TLS: certificate [CN=pc200.dic.ksu] is not valid - CA cert is not valid
TLS: certificate [CN=pc200.dic.ksu] is not valid - error -8172:Peer's certificate issuer has been marked as not trusted by the user..
TLS: error: connect - force handshake failure: errno 2 - moznss error -8172
TLS: can't connect: TLS error -8172:Peer's certificate issuer has been marked as not trusted by the user..
ldap_err2string
ldap_start_tls: Connect error (-11)
        additional info: TLS error -8172:Peer's certificate issuer has been marked as not trusted by the user.
ldap_free_connection 1 1
ldap_send_unbind
ber_flush2: 7 bytes to sd 3
ldap_free_connection: actually freed

有興趣的可以一行一行慢慢查,若要快速查詢,那你可以比較沒有 -d1 以及有 -d1 的差別,出現相同關鍵字 (上述資料) 的地方, 就是最嚴重的錯誤訊息。透過分析上述的訊息,我們會知道,原來正是 CA 錯誤的緣故!那就是憑證資訊!所以要來處理一下才好。而除了使用 ldapsearch -d1 來確認問題之外, 其實 LDAP 的傳輸也能夠查閱日誌分析的資料來查看的:

[root@localhost ~]# journalctl | grep slapd
...前面省略...
11月 15 11:17:55 pc200.dic.ksu slapd[32090]: conn=1023 fd=11 ACCEPT from IP=127.0.0.1:52810 (IP=0.0.0.0:389)
11月 15 11:17:55 pc200.dic.ksu slapd[32090]: conn=1023 op=0 EXT oid=1.3.6.1.4.1.1466.20037
11月 15 11:17:55 pc200.dic.ksu slapd[32090]: conn=1023 op=0 STARTTLS
11月 15 11:17:55 pc200.dic.ksu slapd[32090]: conn=1023 op=0 RESULT oid= err=0 text=
11月 15 11:17:55 pc200.dic.ksu slapd[32090]: conn=1023 fd=11 closed (TLS negotiation failure)
11月 15 11:20:11 pc200.dic.ksu slapd[32090]: conn=1024 fd=11 ACCEPT from IP=127.0.0.1:52812 (IP=0.0.0.0:389)
11月 15 11:20:11 pc200.dic.ksu slapd[32090]: conn=1024 op=0 EXT oid=1.3.6.1.4.1.1466.20037
11月 15 11:20:11 pc200.dic.ksu slapd[32090]: conn=1024 op=0 STARTTLS
11月 15 11:20:11 pc200.dic.ksu slapd[32090]: conn=1024 op=0 RESULT oid= err=0 text=
11月 15 11:20:11 pc200.dic.ksu slapd[32090]: conn=1024 fd=11 closed (TLS negotiation failure)
11月 15 11:23:23 pc200.dic.ksu slapd[32090]: conn=1025 fd=11 ACCEPT from IP=192.168.254.200:47566 (IP=0.0.0.0:389)
11月 15 11:23:23 pc200.dic.ksu slapd[32090]: conn=1025 op=0 EXT oid=1.3.6.1.4.1.1466.20037
11月 15 11:23:23 pc200.dic.ksu slapd[32090]: conn=1025 op=0 STARTTLS
11月 15 11:23:23 pc200.dic.ksu slapd[32090]: conn=1025 op=0 RESULT oid= err=0 text=
11月 15 11:23:23 pc200.dic.ksu slapd[32090]: conn=1025 fd=11 closed (TLS negotiation failure)

資料量挺龐大,我將他做個簡化了!你可以看到第 1025 次連線的資料,裡面有『 STARTTLS 』的字樣,那就是有嘗試使用 TLS 的意思~但是 TLS 的溝通失敗, 所以就顯示這個錯誤訊息給我們了。而錯誤訊息我們則是透過 ldapsearch -d1 查到原因為 CA 的憑證錯誤之故! 呵呵!現在知道如何查詢與分析了吧?

事實上,如果不需要加密的 LDAP 連線,那麼到目前這個步驟為止,整個 LDAP 就搞定了。但是我們知道 LDAP 的查詢甚至可以傳輸密碼! 所以當然最好在網路上傳輸得加密比較妥當的!而同時 LDAP server 是可以接受明碼與 TLS 加密傳輸的!因此,底下我們來處理,讓 LDAP 一定要使用加密傳輸才行!

  • Step 6、建立 LDAP Server / Client 連線時所需要的公私鑰檔案:

在第六章過後你應該知道什麼是公鑰與私鑰。因為你的 LDAP 會在 Server/client 之間傳送帳號參數與密碼參數,所以,兩者之間當然有加密的效果會比較妥當。 建立的方法可以使用 CentOS 預設提供的金鑰建置方式來處理,也能夠自己使用 openssl 這個指令來處理。不過,無論如何,一般建議你的公私鑰最好都放在 /etc/pki/tls/certs/ 裡面比較好!至於建置的方法如下:

[root@localhost ~]# cd /etc/pki/tls/certs
[root@localhost certs]# openssl req -new -x509 -nodes -out /etc/pki/tls/certs/{公鑰檔名}.crt \
> -keyout /etc/pki/tls/certs/{私鑰檔名}.key -days 3650
Generating a 2048 bit RSA private key
.................................................................+++
................+++
writing new private key to '{私鑰檔名}.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:TW
State or Province Name (full name) []:Tainan
Locality Name (eg, city) [Default City]:Tainan
Organization Name (eg, company) [Default Company Ltd]:ksu
Organizational Unit Name (eg, section) []:dic
Common Name (eg, your name or your server's hostname) []:pcxxx.dic.ksu (很重要,一定要與你的主機名稱相同)
Email Address []:root@pcxxx.dic.ksu 

[root@localhost certs]# chown ldap:ldap {公鑰檔名}.crt {私鑰檔名}.key

這會建置出一對以 RSA 加密且可以用 10 年不會過期的金鑰系統出來!然後記得這個檔名就是了!

例題 7.3.H:使用上述的方式,建立一對金鑰,檔名就指定為 dicksu.{crt|key} 來處理!因此最終你會有一對金鑰:
  • 憑證:/etc/pki/tls/certs/dicksu.crt
  • 私鑰:/etc/pki/tls/certs/dicksu.key
  • 這兩把鑰匙檔案的擁有者與群組都必須要是 ldap 比較好!

接下來繼續將上述兩個檔案加入 /etc/openldap/slapd.d/cn=config.ldif 檔案當中!同時請注意,我們預計讓 LDAP 只支援加密傳輸,而經過上面的 openssl 指令輸出, 我們知道了加密使用 RSA 的方式來處置的!因此就使用底下的 LDIF 格式檔案來修改設定囉!

dn: cn=config
changetype: modify
replace: olcTLSCertificateFile
olcTLSCertificateFile: /etc/pki/tls/certs/{公鑰憑證檔案}.crt

dn: cn=config
changetype: modify
replace: olcTLSCertificateKeyFile
olcTLSCertificateKeyFile: /etc/pki/tls/certs/{私鑰檔案}.key

dn: cn=config
changetype: modify
replace: olcTLSCipherSuite
olcTLSCipherSuite: TLSv1.2+RSA:!NULL

dn: cn=config
changetype: modify
replace: olcTLSVerifyClient
olcTLSVerifyClient: allow

接下來,因為 LDAP 可以支援有加密與未加密的連線,如果我們沒有指定,那麼不論有沒有加密,其連線都會出現在 389 這個埠口。 不過因為我們想要讓用戶不能使用明碼傳輸,因此建議可以讓加密與未加密的連線分開。處理的方式也挺簡單的,修改 /etc/sysconfig/slapd 即可!

[root@localhost ~]# vim /etc/sysconfig/slapd
SLAPD_URLS="ldapi:/// ldap:/// ldaps:///"

[root@localhost ~]# systemctl restart slapd
[root@localhost ~]# netstat -tlunp | grep slapd
tcp        0      0 0.0.0.0:636             0.0.0.0:*               LISTEN      753/slapd
tcp        0      0 0.0.0.0:389             0.0.0.0:*               LISTEN      753/slapd
tcp6       0      0 :::636                  :::*                    LISTEN      753/slapd
tcp6       0      0 :::389                  :::*                    LISTEN      753/slapd

這樣就出現了 636 這個需要連線加密的埠口囉。

例題 7.3.I:建立 certs.ldif ,以加入金鑰系統資訊
  1. 將金鑰憑證系統匯入 LDAP 設定當中:
    • 建立 certs.ldif 檔案,將上述的資訊複製進來,然後改寫完整的檔名;
    • 將該檔案匯入系統中 (ldapmodify -Y EXTERNAL -H ldapi:/// -f ...)
    • 查看 /etc/openldap/slapd.d/cn=config.ldif 是否修改成功。
    • 使用 slaptest -u 測試設定檔是否成功。
  2. 讓加密與不加密的 LDAP 連線分開,最終重新啟動 slapd 時,會有兩個不同的埠口在監聽。
  • Step 7、讓用戶端可以使用 TLS 連線通道進行查詢

預設 ldapsearch 是透過明碼來傳輸的,如果需要透過 TLS 加密的話,那就得要修改設定檔,讓 ldapsearch 的查詢可以支援憑證的檢查才行。 這個屬於用戶端功能的設定位於 /etc/openldap/ldap.conf 當中,在該檔案內加入這行:

[root@localhost ~]# vim /etc/openldap/ldap.conf
TLS_REQCERT allow

修改完成後儲存離開,接下來開始查詢一下 port 636 的功能!依舊查詢 ldapuser1 的資訊來看看:

[root@localhost ~]# ldapsearch -x -H ldaps://pc200.dic.ksu -b "dc=dic,dc=ksu" uid=ldapuser1
...輸出訊息要是正確的 ldapuser1 資訊才行!這邊我省略輸出!....

[root@localhost ~]# journalctl | grep slap | tail -n 20
11月 15 13:19:30 pc200.dic.ksu slapd[753]: conn=1002 fd=13 ACCEPT from IP=192.168.254.200:34294 (IP=0.0.0.0:636)
11月 15 13:19:30 pc200.dic.ksu slapd[753]: conn=1002 fd=13 TLS established tls_ssf=256 ssf=256
11月 15 13:19:30 pc200.dic.ksu slapd[753]: conn=1002 op=0 BIND dn="" method=128
11月 15 13:19:30 pc200.dic.ksu slapd[753]: conn=1002 op=0 RESULT tag=97 err=0 text=
11月 15 13:19:30 pc200.dic.ksu slapd[753]: conn=1002 op=1 SRCH base="dc=dic,dc=ksu" scope=2 deref=0 filter="(uid=ldapuser1)"
11月 15 13:19:30 pc200.dic.ksu slapd[753]: <= bdb_equality_candidates: (uid) not indexed
11月 15 13:19:30 pc200.dic.ksu slapd[753]: conn=1002 op=1 SEARCH RESULT tag=101 err=0 nentries=1 text=
11月 15 13:19:30 pc200.dic.ksu slapd[753]: conn=1002 op=2 UNBIND
11月 15 13:19:30 pc200.dic.ksu slapd[753]: conn=1002 fd=13 closed
11月 15 13:23:37 pc200.dic.ksu slapd[753]: conn=1003 fd=13 ACCEPT from IP=192.168.254.200:34296 (IP=0.0.0.0:636)
11月 15 13:23:37 pc200.dic.ksu slapd[753]: conn=1003 fd=13 TLS established tls_ssf=256 ssf=256
11月 15 13:23:37 pc200.dic.ksu slapd[753]: conn=1003 op=0 BIND dn="" method=128
11月 15 13:23:37 pc200.dic.ksu slapd[753]: conn=1003 op=0 RESULT tag=97 err=0 text=
11月 15 13:23:37 pc200.dic.ksu slapd[753]: conn=1003 op=1 SRCH base="dc=dic,dc=ksu" scope=2 deref=0 filter="(uid=ldapuser1)"
11月 15 13:23:37 pc200.dic.ksu slapd[753]: <= bdb_equality_candidates: (uid) not indexed
11月 15 13:23:37 pc200.dic.ksu slapd[753]: conn=1003 op=1 SEARCH RESULT tag=101 err=0 nentries=1 text=
11月 15 13:23:37 pc200.dic.ksu slapd[753]: conn=1003 op=2 UNBIND
11月 15 13:23:37 pc200.dic.ksu slapd[753]: conn=1003 fd=13 closed

記得查詢的時候使用 ldaps:// 喔!與 ldap:// 比較是多了個 s 的不同!加上 ldaps:// 之後,就不必使用 -ZZ 來強迫啟用 TLS 了! 因為預設就是會使用 TLS 之意。

  • Step 8、伺服器本機也使用 LDAP 作為帳號驗證

其實所有的系統要加載這個 LDAP 的身份驗證程序都差不多!現在我們以自己本機來設計一下,如果也需要使用 LDAP 時,該如何設計呢?

  1. 基本上,要先處理 LDAP 的驗證模組,請先安裝 nss-pam-ldapd 軟體。
  2. 之後,因為我們有使用連線加密,因此得要將憑證 (公鑰檔案) 複製到固定的目錄去,那就是 /etc/openldap/cacerts 這個目錄。 檔名倒是不這麼重要!記得將 /etc/pki/tls/certs/{公鑰檔案}.crt 複製過去即可!
  3. 因為驗證的實際動作是靠 nslcd 這個服務來處理,這個服務就是 nss-pam-ldapd 軟體所提供的。但是這個服務預設並沒有啟動加密連線的 TLS 功能! 所以請 vim /etc/nslcd.conf 檔案,加入『 tls_reqcert allow 』這個設定值才行!
  4. 最終使用 setup 或 authconfig-tui 這個指令來設定身份驗證!一開始進入設定畫面有點像這樣:
    LDAP
    如上,勾選了『 Use LDAP 』以及『 Use LDAP Authentication 』兩個項目,之後按下 Next。 在出現的畫面中,要注意有兩種基本上定方案:
    • LDAP 使用 port 389 強迫使用 TLS 的機制,此時需要勾選 TLS 但使用 ldap:// 網址;
    • LDAP 已分開 389, 636,因此直接不勾選 TLS 但使用 ldaps:// 網址即可。
    在這個章節當中建議的使用 ldaps:// 網址,因此不需要勾選 TLS 喔!最終畫面示意如下:
    LDAP
  5. 使用 ldapsearch 檢查一下憑證資料是否更新正確,並使用『 id username 』確認一下即可!
例題 7.3.J:請依據上述的說明,讓你的 Server 也能使用 LDAP 做身份判斷:
  1. 先安裝所需要的軟體
  2. 將 /etc/pki/tls/certs/dicksu.crt 複製到 /etc/openldap/cacerts 目錄下 (該目錄預設不存在,請自行建立他)
  3. 編輯 /etc/nslcd.conf ,加入 tls_reqcert allow 功能
  4. 因為 Server 沒有 setup 指令,請直接使用 authconfig-tui 來啟動身份驗證功能,並依據你的系統來設定好各個項目即可。 比較重要是那個 ldaps:// 項目!裡面的主機名稱要寫正確!亦即建立憑證時的那個主機名稱才行! 若順利的話,你會直接被丟回指令模式!
  5. 建議使用『 ldapsearch -x -H ldaps://127.0.0.1 -b "dc=dic,dc=ksu" uid=ldapuser1 -d1 』指令事先查詢一下,仔細觀察 TLS 的輸出訊息,如下所示:
    [root@localhost ~]# ldapsearch -x -H ldaps://127.0.0.1 -b "dc=dic,dc=ksu" uid=ldapuser1 -d1
    ldap_url_parse_ext(ldaps://127.0.0.1)
    ldap_create
    ldap_url_parse_ext(ldaps://127.0.0.1:636/??base)
    ldap_sasl_bind
    ldap_send_initial_request
    ldap_new_connection 1 1 0
    ldap_int_open_connection
    ldap_connect_to_host: TCP 127.0.0.1:636
    ldap_new_socket: 3
    ldap_prepare_socket: 3
    ldap_connect_to_host: Trying 127.0.0.1:636
    ldap_pvt_connect: fd: 3 tm: -1 async: 0
    attempting to connect:
    connect success
    TLS: certdb config: configDir='/etc/openldap/cacerts' tokenDescription='ldap(0)' certPrefix='' keyPrefix='' flags=readOnly
    TLS: cannot open certdb '/etc/openldap/cacerts', error -8018:Unknown PKCS #11 error.
    TLS: skipping 'dicksu.crt' - filename does not have expected format (certificate hash with numeric suffix)
    TLS: loaded CA certificate file /etc/openldap/cacerts/0165d0fb.0 from CA certificate directory /etc/openldap/cacerts.
    TLS: certificate [E=root@pc200.dic.ksu,CN=pc200.dic.ksu,OU=dic,O=ksu,L=Tainan,ST=Tainan,C=TW] is valid
    TLS certificate verification: subject: E=root@pc200.dic.ksu,CN=pc200.dic.ksu,OU=dic,O=ksu,L=Tainan,ST=Tainan,C=TW, issuer: 
      E=root@pc200.dic.ksu,CN=pc200.dic.ksu,OU=dic,O=ksu,L=Tainan,ST=Tainan,C=TW, cipher: AES-256-GCM, security level: high, secret key bits: 256, 
      total key bits: 256, cache hits: 0, cache misses: 0, cache not reusable: 0
    ldap_open_defconn: successful
    ldap_send_server_request
    ...
    
    最後出現那個『ldap_open_defconn: successful』還挺重要的!需要特別注意這個連線是否成功才行!
  6. 使用『 id ldapuser1 』之類的動作來確認一下系統能找到該帳號才可以!同時,查詢完畢後,最好也能使用 journalctl 確認一下是透過 TLS 通道才好
    [root@localhost ~]# id ldapuser1
    uid=6001(ldapuser1) gid=6001(ldapuser1) groups=6001(ldapuser1)
    
    [root@localhost ~]# journalctl | grep slap | tail -n 20
    11月 15 14:26:04 pc200.dic.ksu slapd[1089]: conn=1001 fd=20 ACCEPT from IP=192.168.254.200:34390 (IP=0.0.0.0:636)
    11月 15 14:26:04 pc200.dic.ksu slapd[1089]: conn=1001 fd=20 TLS established tls_ssf=256 ssf=256
    11月 15 14:26:04 pc200.dic.ksu slapd[1089]: conn=1001 op=0 BIND dn="" method=128
    11月 15 14:26:04 pc200.dic.ksu slapd[1089]: conn=1001 op=0 RESULT tag=97 err=0 text=
    11月 15 14:26:04 pc200.dic.ksu slapd[1089]: conn=1001 op=1 SRCH base="dc=dic,dc=ksu" scope=2 deref=0 filter="(&(objectClass=posixAccount)(uidNumber=6007))"
    11月 15 14:26:04 pc200.dic.ksu slapd[1089]: conn=1001 op=1 SRCH attr=loginShell cn gidNumber uidNumber objectClass homeDirectory gecos uid
    11月 15 14:26:04 pc200.dic.ksu slapd[1089]: <= bdb_equality_candidates: (uidNumber) not indexed
    11月 15 14:26:04 pc200.dic.ksu slapd[1089]: conn=1001 op=1 SEARCH RESULT tag=101 err=0 nentries=1 text=
    11月 15 14:26:04 pc200.dic.ksu slapd[1089]: conn=1001 op=2 SRCH base="dc=dic,dc=ksu" scope=2 deref=0 filter="(&(objectClass=posixAccount)(uidNumber=6007))"
    11月 15 14:26:04 pc200.dic.ksu slapd[1089]: conn=1001 op=2 SRCH attr=loginShell cn gidNumber uidNumber objectClass homeDirectory gecos uid
    11月 15 14:26:04 pc200.dic.ksu slapd[1089]: <= bdb_equality_candidates: (uidNumber) not indexed
    11月 15 14:26:04 pc200.dic.ksu slapd[1089]: conn=1001 op=2 SEARCH RESULT tag=101 err=0 nentries=1 text=
    11月 15 14:26:04 pc200.dic.ksu slapd[1089]: conn=1001 op=3 SRCH base="dc=dic,dc=ksu" scope=2 deref=0 filter="(&(objectClass=posixGroup)(gidNumber=6007))"
    11月 15 14:26:04 pc200.dic.ksu slapd[1089]: conn=1001 op=3 SRCH attr=memberUid cn gidNumber member
    11月 15 14:26:04 pc200.dic.ksu slapd[1089]: <= bdb_equality_candidates: (gidNumber) not indexed
    11月 15 14:26:04 pc200.dic.ksu slapd[1089]: conn=1001 op=3 SEARCH RESULT tag=101 err=0 nentries=1 text=
    11月 15 14:26:04 pc200.dic.ksu slapd[1089]: conn=1001 op=4 SRCH base="dc=dic,dc=ksu" scope=2 deref=0 filter="(&(objectClass=posixAccount)(uid=ldapuser7))"
    11月 15 14:26:04 pc200.dic.ksu slapd[1089]: conn=1001 op=4 SRCH attr=uid uidNumber
    11月 15 14:26:04 pc200.dic.ksu slapd[1089]: <= bdb_equality_candidates: (uid) not indexed
    11月 15 14:26:04 pc200.dic.ksu slapd[1089]: conn=1001 op=4 SEARCH RESULT tag=101 err=0 nentries=1 text=
    11月 15 14:26:04 pc200.dic.ksu slapd[1089]: conn=1001 op=5 SRCH base="dc=dic,dc=ksu" scope=2 deref=0 filter="(&(objectClass=posixGroup)(|(memberUid=ldapuser7)(member=uid=ldapuser7,ou=people,dc=dic,dc=ksu)))"
    11月 15 14:26:04 pc200.dic.ksu slapd[1089]: conn=1001 op=5 SRCH attr=memberUid cn gidNumber member
    11月 15 14:26:04 pc200.dic.ksu slapd[1089]: <= bdb_equality_candidates: (memberUid) not indexed
    11月 15 14:26:04 pc200.dic.ksu slapd[1089]: <= bdb_equality_candidates: (member) not indexed
    11月 15 14:26:04 pc200.dic.ksu slapd[1089]: conn=1001 op=5 SEARCH RESULT tag=101 err=0 nentries=0 text=
    11月 15 14:26:04 pc200.dic.ksu slapd[1089]: conn=1001 op=6 SRCH base="dc=dic,dc=ksu" scope=2 deref=0 filter="(&(objectClass=posixGroup)(gidNumber=6007))"
    11月 15 14:26:04 pc200.dic.ksu slapd[1089]: conn=1001 op=6 SRCH attr=memberUid cn gidNumber member
    11月 15 14:26:04 pc200.dic.ksu slapd[1089]: <= bdb_equality_candidates: (gidNumber) not indexed
    11月 15 14:26:04 pc200.dic.ksu slapd[1089]: conn=1001 op=6 SEARCH RESULT tag=101 err=0 nentries=1 text=
    
  • Step 9、讓用戶端使用 LDAP Server 作為帳號驗證來源之一

其實整個作法跟上個步驟一模一樣,你只需要知道,上述動作的 Server 得要使用 LDAP server 的實際 IP 而不是 127.0.0.1 即可。

例題 7.3.K:請參考例題 7.3.J 的流程,一步一步處理好你 Client 端的系統。
  • 再次確認在你的 /etc/hosts 裡面,是否有搭配 LDAP server 的主機名稱了!
  • 先安裝所需要的軟體,除了 nss-pam-ldapd 之外,最好也安裝上 openldap-clients 軟體
  • 用戶端要複製來自 Server 的憑證 (公鑰檔案),同樣放置在 /etc/openldap/cacerts 目錄下即可。
  • 在 /etc/nslcd.conf 加入 tls_reqcert allow
  • 在 /etc/openldap/ldap.conf 加入 TLS_REQCERT allow 設定
  • 使用 setup 來處理驗證,同樣的 (1)不勾選TLS (2)使用 ldaps://pcxxx.dic.ksu (3)輸入正確的 baseDN 項目
  • 使用『 ldapsearch -x -b "dc=dic,dc=ksu" -H ldaps://pcxxx.dic.ksu uid=ldapuser1 -d1 』來檢驗,除了要有正確的輸出訊息, 同樣記得查詢 TLS 的輸出資訊!
  • 最後『 id ldapuser1 』確認用戶存在即可!

透過這長長一大串的資料,你的 LDAP server 現在應該可以順暢的運作了!不論加密還是不加密,LDAP 的查詢應該都沒問題了才對喔!

7.4: LDAP 資料庫簡易管理 (新增/刪除/修改用戶參數)

  • 新增用戶

如果在建置好了 LDAP 系統後,若需要增加其他用戶或群組,那就直接修改 ldapuser.ldif 以及 ldapgroup.ldif 後,再以 ldapadd 加入即可! 如下的範例可以來持續進行:

# 先來建立 ldapuser11 這個帳號與群組的 LDIF 資料,假設檔名為 newuser.ldif
[root@localhost ldap]# vim newuser.ldif
dn: uid=ldapuser11,ou=People,dc=dic,dc=ksu
uid: ldapuser11
cn: ldapuser11
sn: ldapuser11
mail: ldapuser11@dic.ksu
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: top
objectClass: shadowAccount
userPassword: {crypt}$6$.N5RlKpP$y0R8wngFH8X2wgzk3zh3yAc0zfa4iJsgXnljZfaBbTRL45br877DF4.w.FZsJfVePa/doErJFYe8JLovnvOVM0
shadowLastChange: 17486
shadowMin: 0
shadowMax: 99999
shadowWarning: 7
loginShell: /bin/bash
uidNumber: 6011
gidNumber: 6011
homeDirectory: /home/rhome/ldapuser11

dn: cn=ldapuser11,ou=Group,dc=dic,dc=ksu
objectClass: posixGroup
objectClass: top
cn: ldapuser11
userPassword: {crypt}x
gidNumber: 6011

# 接著將這個資料匯入 LDAP 資料庫當中!
[root@localhost ldap]# ldapadd -H ldaps://127.0.0.1 -x -W -D "cn=Manager,dc=dic,dc=ksu" -f newuser.ldif
Enter LDAP Password:
adding new entry "uid=ldapuser11,ou=People,dc=dic,dc=ksu"
adding new entry "cn=ldapuser11,ou=Group,dc=dic,dc=ksu"

[root@localhost ldap]# id ldapuser11
uid=6011(ldapuser11) gid=6011(ldapuser11) groups=6011(ldapuser11)

# 當然還是得要建置用戶的家目錄與相關權限才行!
[root@localhost ldap]# cp -a /etc/skel /home/rhome/ldapuser11
[root@localhost ldap]# chown ldapuser11:ldapuser11 -R /home/rhome/ldapuser11
[root@localhost ldap]# chmod 700 /home/rhome/ldapuser11
  • 刪除用戶

如果是想要刪除用戶,那直接透過 ldapdelete 來處置即可!

# 假設刪除掉 ldapuser8 這個帳號,這個帳號的 dn 為 uid=ldapuser8,ou=People,dc=dic,dc=ksu
[root@localhost ldap]# ldapdelete -H ldaps://127.0.0.1 -x -W -D "cn=Manager,dc=dic,dc=ksu" uid=ldapuser8,ou=People,dc=dic,dc=ksu
Enter LDAP Password:

[root@localhost ldap]# id ldapuser8
id: ldapuser8: no such user

當然啦!那個 /home/rhome/ldapuser8 的使用者家目錄,就得要手動移除才行!

  • 修改用戶參數

那如果是想要修改參數呢?舉例來說,想要將 ldapuser1 的密碼由原先的密碼變更為新的密碼,假設密碼為 qqq123ddd 的話,那可以怎麼做呢?簡單的作法如下:

# 先取得加密過後的密碼樣式:
[root@localhost ldap]# slappasswd
New password:
Re-enter new password:
{SSHA}RbrP717EPR3XGOtGRMaVvhPiICd5Pi0E

# 開始建立一個名為 changepw.ldif 的檔案,內容如下:
[root@localhost ldap]# vim changepw.ldif
dn: uid=ldapuser1,ou=People,dc=dic,dc=ksu
changetype: modify
replace: userPassword
userPassword: {SSHA}RbrP717EPR3XGOtGRMaVvhPiICd5Pi0E

# 匯入上面這個 LDIF 檔案來更新!
[root@localhost ldap]# ldapmodify -H ldaps://127.0.0.1 -W -D "cn=Manager,dc=dic,dc=ksu" -f changepw.ldif
Enter LDAP Password:
modifying entry "uid=ldapuser1,ou=People,dc=dic,dc=ksu"

在 Server 上面想要確認這個密碼是否生效?可以到 tty2 去使用 ldapuser1 登入就知道了!

7.5: 分享檔案系統的 NFS 伺服器

  • 什麼是 NFS 與 RPC server

NFS 為 Network Filesystem 的縮寫,主要的目的在於分享伺服器的檔案系統給用戶端使用。但 NFS 主要是架構於 RPC server 底下的一個服務, 因此啟動 NFS 之前,需要啟動 RPC server。事實上檔案系統的運作是相當複雜的,因此過去有所謂的遠端程序呼叫在負責很多 Server/Client 的溝通與資訊傳遞,所以附掛在 RPC 之上的服務,我們就稱為 RPC service 了。

RPC (Remote Procedure Call) 最主要的功能就是在指定每個 NFS 功能所對應的 port number ,並且回報給用戶端,讓用戶端可以連結到正確的埠口上去。 那 RPC 又是如何知道每個 NFS 的埠口呢?這是因為當伺服器在啟動 NFS 時會隨機取用數個埠口,並主動的向 RPC 註冊,因此 RPC 可以知道每個埠口對應的 NFS 功能,然後 RPC 又是固定使用 port 111 來監聽用戶端的需求並回報用戶端正確的埠口, 所以當然可以讓 NFS 的啟動更為輕鬆愉快了!簡單的說:

  • NFS 會用到的服務很多,包括 rpc.mountd, rpc.nfsd, rpc.rquotad...,這些服務啟動時,預設為隨機啟動任意埠口。
  • 但是 NFS 用戶端是直接連線到上述服務的埠口,因此就需要有一隻總管程式來管理這些服務的埠口
  • 這個總管的角色就是 RPC 了!
  • CentOS 7 使用的 RPC server 為 rpcbind 這個服務
  • 用戶端會向伺服器端的 RPC (port 111) 發出 NFS 檔案存取功能的詢問要求;
  • 伺服器端找到對應的已註冊的 NFS daemon 埠口後,會回報給用戶端;
  • 用戶端瞭解正確的埠口後,就可以直接與 NFS daemon 來連線。

NFS 僅提供檔案系統的分享,本身並不理會帳號的驗證喔!基本上使用 NFS 會有底下的狀況:

由於 server/client 都是用『自己的帳號去看待檔案系統』,但是『檔案系統記載的是 UID/GID 資訊』,因此若 server/client 帳號不同步, 那可能會產生很大的問題。這也是本章前幾個小節要先介紹 LDAP 的主因!

  • 簡易的 NFS 設定

NFS 的設定相當簡單!設定檔位於 /etc/exports,該檔案的格式大致為:

/dir/path  IP(permission)  network/netmask(permission)

/dir/path 指的是你要分享出去的目錄

IP, Network/netmask 的寫法可以是:

  • 單獨的IP: 192.168.1.1
  • 一整個網段: 192.168.1.0/24
  • 可以找到 IP 的主機名稱: station100.dic.ksu

至於常見的權限則有底下幾種:

  • rw/ro:可讀寫或唯讀
  • sync/async:同步或非同步檔案系統。建議一定要 async !效能差很多!
  • no_root_squash/root_squash:是否壓縮 root 權限,預設為 root_squash
  • all_squash, anonuid, anongid:若身份全部壓縮,亦即讓登入者全部變某個匿名者之意。
  • insecure:使用非加密的傳輸方式,速度會比較快。

假設我想要分享出 /mnt 給 192.168.254.0/24 唯讀使用,基本寫法就會是: (務必記得, /mnt 得要先存在才行!)

/mnt  192.168.254.0/24(ro,async)
例題 7.5.A:完成如下的設定:
  • 讓 10.255.XXX.0/24 的整個網段都可以使用 /home/rhome 目錄,且為可讀寫,且為非加密的環境
  • 讓 10.255.XXX.0/24 的整個網段都可以使用 /srv/project 目錄,且為可讀寫,且為非加密的環境
  • 讓 10.255.XXX.0/24 的整個網段都可以使用 /srv/public 目錄,且為唯讀,且為非加密的環境
  • 讓 10.255.XXX.1 的這個 IP 可以使用 /srv/root 目錄,且為可讀寫,且 root 可保有權限,且為非加密的環境
  • NFS 服務的啟動與觀察

NFS 目前有兩種服務,一種要加密傳輸一種則是非加密傳輸。本章主要討論區網內使用的非加密傳輸機制~因此啟動的服務名稱就會是 nfs-server, 如果是加密傳輸,則是啟動 nfs-secure-server 才對。

例題 7.5.B:進行如下的處理流程:
  • NFS 提供者為 nfs-utils,請先安裝這軟體才行!
  • 啟動 nfs-server 服務,且該服務下次開機也會啟動
  • 另外,亦請使用 systemctl 觀察一下 nfs-server 的狀態,如果忘記建置目錄,該狀態會告知!
  • 使用 netstat 觀察 nfs 啟動的埠口在幾號?
  • 使用 rpcinfo -p 查閱一下各啟動的埠口是否已經跟 rpcbind 註冊了。
  • 使用 showmount -e localhost 可以查詢該 Server 分享的目錄與分享的用戶範圍。
  • 前往查看 /var/lib/nfs/etab 會得到更詳細的分享的權限參數!
  • NFS 用戶端的觀察與使用

用戶端設定很簡單,就只要去查閱伺服器端有沒有提供相對應的服務,然後掛載這樣而已。一般來說,常見的流程會是這樣:

  • 在用戶端嘗試使用 showmount -e ServerIP 來看伺服器有沒有提供相關的掛載服務
  • 使用 mount -t nfs IP:/share/mount /local/path 來將伺服器的目錄手動掛載到系統上,卸載同樣使用 umount
  • 若開機就需要掛載,直接寫入 /etc/fstab 當中,但要注意檔案系統參數 (第四欄位) 要加上『 _netdev,intr 』較佳!
例題 7.5.C :在用戶端電腦完成如下的設定:
  • 先用 su - ldapuser1 測試用戶能不能取得家目錄?然後 exit 回到 root 身份。
  • 嘗試使用 showmount 查詢 server 分享的目錄有哪些?
  • 手動嘗試將 Server:/home/rhome 掛載到本機的 /home/rhome 上,測試完畢請卸載
  • 將設定值寫入 /etc/fstab 當中,並使用 mount -a 測試
  • 使用 nfsstate -m 查閱掛載的詳細參數
  • 使用 su - ldapuser1 看看,是否可以取得正確的家目錄與權限。
  • 請使用 root 的身份進入 /home/rhome,測試能否建置/修改檔案在該目錄下?

在正規的設定行為中,我們有 LDAP 的 ID 認證,搭配 NFS 的掛載,這樣就已經完成了大部分的需求了!不過未來請注意,關機時, 一定要先關用戶端再關 server,否則擔心 NFS 檔案系統的卸載會影響到你的關機情況。因此,還是建議使用 autofs 來進行登入時的掛載較佳。

  • NFS 用戶端的檔案系統自動掛載

其實上學期的網路檔案系統內就有講過了!直接查閱 /etc/auto.master 就能夠想起來如何處理囉!

例題 7.5.D:處理用戶端的自動掛載行為
  • 先卸載 /home/rhome,同時取消 /etc/fstab 內的開機掛載項目
  • 先安裝 autofs 軟體,才會有自動掛載的功能!
  • 編輯 /etc/auto.master ,加入『 /home/rhome /etc/auto.rhome 』一行
  • 編輯 /etc/auto.rhome,加入『* -rw,soft,intr server:/home/rhome/& 』
  • 刪除 /home/rhome 目錄,讓該目錄變成系統自動偵測產生。
  • 啟動 autofs 服務,並且下次開機這個服務也會啟動
  • 再次使用 su - ldapuser1 看看能不能讓系統自動掛載相對的家目錄?
  • 使用 nfsstate -m 查詢更多掛載參數。
  • NFS 用戶端的 root 權限保留

我們知道 server 的 /srv/root 是可以使用 root 身份操作系統的。現在請實際實施看看結果為何!

例題 7.5.E:使用 root 身份登入 NFS 檔案系統
  • 建立 /srv/root
  • 以手動方式將 server:/srv/root 掛載到本地端的 /srv/root
  • 以 root 身份進入 /srv/root,是否可以順利的進行操作?

7.6: 課後練習

  1. (60%)實作題:啟動 Server 作業硬碟 - unit07
    1. 網路參數的設定,請依據底下的方式來設定好你的網路環境:
      1. 因為我們的系統是 clone 來的,因此裡面的網路卡連線會跑掉。所以,請先刪除所有的連線界面後, 再依據底下的要求逐次建立好你的網路環境:
      2. 建立 eth0 為外部的連線網卡 (相同的連線界面名稱),使用 ethernet 類型,且:
        • IPv4 的 IP位址: 172.18.255.*/24 ,其中 * 為老師規定的 IP 尾數
        • gateway 為 172.18.255.254
        • DNS 為 172.16.200.254 以及 168.95.1.1
      3. 使用 teamd 的機制建立內部區域網路的備援功能:
        • team 的界面使用 team0 卡號,且連線名稱請命名為 team0
        • team 使用 activebackup 備援功能,不要使用 loadbalance
        • team 的實體網卡 (team slave) 請使用 eth1 及 eth2 ,且其連線名稱名稱亦請命名為 eth1, eth2
        • 內部網路參數為: 172.19.*.254/24,不需要 gateway
      4. 主機名稱指定為: server*.example.dic
      5. 最終你的主機名稱與 IP 的對應為:
        server*.example.dic	172.18.255.*		別名為 server*
        server254.example.dic	172.18.255.254		別名為 server254
        server.lan*.example.dic	172.19.*.254		別名為 server
        client.lan*.example.dic	172.19.*.1		別名為 client
        
    2. 基本的伺服器作業系統設定行為:
      1. 使用崑山的 FTP 網站作為你的 YUM server 來源,並且清除一次 yum 清單快取
      2. 安裝相關的軟體,至少須安裝 vim-enhanced, bash-completion, net-tools, mailx, wget, links, bind-utils
      3. 全系統自動升級,且每天凌晨 3 點也會自動升級一次。(請寫入 /etc/crontab 為主)
      4. 將 SELinux 修改成為 Enforcing 模式,且未來每次開機都自動為 Enforcing 才行
    3. 實際設定好本機防火牆
      1. 請關閉 firewalld 服務,並且自行安裝、啟動 iptables 服務
      2. 將預設的規則轉存到 /root/firewall.sh 這個檔案內
      3. 首先將全部的規則刪除 (應該有三條指令)
      4. 設定好預設政策,讓 INPUT 成為 DROP 而 OUTPUT 與 FORWARD 成為 ACCEPT
      5. 針對 INPUT 前三條規則為 (1)回應封包 (2)放行 lo 界面 (3)放行 icmp 封包
      6. 放行你自己的內部區域網路那個網域的連線要求
      7. 讓 ssh 只對外部的區網放行,不會對 Internet 放行
      8. 讓 http 針對整個 Internet 放行
      9. 最後讓確定的規則轉存到 /etc/sysconfig/iptables 這個設定檔
      10. 重新啟動 iptables 服務,然後觀察規則是否正確
    4. 實際設定好 Server 的路由功能
      1. 讓核心支援 IP 轉遞的功能
      2. 修改 /root/firewall.sh ,增加刪除 nat 表格的規則與自訂鏈
      3. 增加讓來自內部網路的封包,並預計由 eth0 對外網卡出去的封包,全部偽裝成為 eth0 的 public IP
      4. 在 /etc/sysconfig/iptables-config 當中增加 nf_nat_ftp 及 nf_conntrack_ftp 模組功能
      5. 此功能在開機後依舊能夠順利啟動
    5. 建置專屬你區域網路的 LDAP 服務
      1. 建立你的 LDAP 相關節點如下:
        • baseDN 設定為: dc=example,dc=dic
        • RootDN 設定為: cn=Manager,dc=example,dc=dic
        • RootDN 的密碼設定為: 2727175
      2. 因為預計要作為 Linux 的帳號驗證功能,因此請載入與 Linux 帳號相關的三個主要綱要檔 (schema)
      3. 基礎 LDAP 資料庫節點設計中,至少應具有底下的節點存在,請將這些節點匯入到資料庫內:
        • dn: dc=example,dc=dic
        • dn: cn=Manager,dc=example,dc=dic
        • dn: ou=People,dc=example,dc=dic
        • dn: ou=Group,dc=example,dc=dic
      4. 建立 10 個 LDAP 所管理的相關帳號,帳號相關資訊如下,請將該資訊匯入 LDAP 資料庫中:
        • 假設使用者名稱為 webuser1 ~ webuser10
        • 預設使用者密碼為 webpasswd 這個密碼
        • 假設使用者的 UID 從 8001 開始編號
        • 假設使用者的 GID 也是從 8001 開始編號,且有對應的私有群組
        • 假設使用者的預設家目錄在 /rhome/ 底下
      5. 承上,這 10 個用戶的家目錄亦請自行設定好相關的位置與權限
      6. 使用非加密的 LDAP 傳輸行為,因此請完成底下工作:
        • 讓 server 自己可以使用 ldapsearch 查詢 ldap:// 的資料
        • 讓 server 自己可以使用 LDAP 的帳號登入 Server 本身的系統 (請使用 ldap:// 網址)
    6. 建置 NFS 檔案伺服器
      1. 讓你的 /rhome 針對你的區域網路分享,權限請設定為可讀寫。
  2. (30%)實作題:啟動 client 作業硬碟
    1. 網路參數的設定,請依據底下的方式來設定好:
      1. 因為我們的系統是 clone 來的,因此裡面的網路卡連線會跑掉。所以,請先刪除所有的連線界面後, 再依據底下的要求逐次建立好你的網路環境:
      2. 建立 eth0 的連線網卡 (相同的連線界面名稱),使用 ethernet 類型,且:
        • IPv4 的 IP位址: 172.19.*.1/24 ,其中 * 為老師規定的 IP 尾數
        • gateway 為 172.19.*.254
        • DNS 為 172.16.200.254 以及 168.95.1.1
      3. 主機名稱指定為: client.lan*.example.dic
      4. 最終你的主機名稱與 IP 的對應為:
        server*.example.dic	172.18.255.*		別名為 server*
        server254.example.dic	172.18.255.254		別名為 server254
        server.lan*.example.dic	172.19.*.254		別名為 server
        client.lan*.example.dic	172.19.*.1		別名為 client
        
    2. 實際設定好本機防火牆
      1. 預設請使用 firewalld 防火牆服務,不要使用 iptables 服務!
      2. 預計放行的服務主要有 ssh 與 http 兩個服務,其他還可能有預設會啟用的 dhcp 用戶端服務。
      3. 查詢 rich rule (man firewalld.richlanguage),確認來自本機同一個 LAN 網段的封包,通通給予放行。
      4. 上述放行的防火牆服務,在下次重新開機後,依舊會存在才行
    3. 讓你的用戶端主機也能夠支援 LDAP 的帳號驗證,並且使用的是 ldap:// 的網址功能
    4. 請使用 autofs 的機制,讓網路用戶登入時,能夠透過 NFS 取得自己的家目錄
  3. (10%)簡易問答題: 從具有 GUI 及中文的用戶端 Linux ,使用『 ssh root@172.19.*.254 』登入你的 Server ,之後建立 /root/ans.txt 的檔案,並將底下各題目的答案寫入你 server 當中!
    1. 請說明 LDAP 的 BaseDN, RootDN, RootPW, schema 的意義各為何?
    2. 在 Linux 帳號的 schema 當中,匯入 nis.ldif 之後,應該要有那兩個 ou (organization unit) 的存在。
    3. 在 CentOS 7 上面,架設 LDAP server 與 LDAP client 功能,各需要哪個軟體?
    4. slapd 啟動後,若將 TLS 的連線通道分開,則 ldap://, ldaps:// 各預設啟動在哪個埠口?
    5. NFS server 預設啟動在哪個埠口上?可以使用那一個指令觀察 (不是 netstat 喔!)?
  4. 上傳成績
    1. 請將 Server/Client 的硬碟通通啟動,並且確認兩者間的連線沒有問題;
    2. 在 Server 硬碟上面登入,然後用 root 的身份執行 vbird_server_check_unit ,並依據提示資料填寫你的學號與 IP 尾數
    3. 該程式會偵測你的系統,並且通知你哪個部份可能有問題,你需要持續觀察或者重新處理的部份會交代妥當。
    4. 若一切沒問題,螢幕就會出現如下的字樣,然後你就能夠使用 links 去檢查你的檔案是否有順利的上傳了!
    5. Please use links http://172.18.255.250/upload/unit07 to check your filename