

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 使用 LDAP 身分驗證
<a name="emr-jupyterhub-ldap-users"></a>

輕量型目錄存取協定 (LDAP) 是一種應用程式協定，用於查詢和修改對應到資源的物件，例如存放在相容 LDAP 的目錄服務供應商 (例如 Active Directory 或 OpenLDAP 伺服器) 的使用者和電腦。您可以透過 Amazon EMR 上的 JupyterHub 來使用[適用於 JupyterHub 的 LDAP 驗證器外掛程式](https://github.com/jupyterhub/ldapauthenticator/)，以使用 LDAP 進行使用者身分驗證。該外掛程式處理適用於 LDAP 使用者的登入工作階段，並提供使用者資訊給 Jupyter。這可讓使用者使用存放在 LDAP 相容伺服器中的身分登入資料連接到 JupyterHub 和筆記本。

本節中的步驟會逐步引導您完成以下步驟，以使用適用於 JupyterHub 的 LDAP Authenticator 外掛程式來設定並啟用 LDAP。您將在連接到主節點命令列的同時執行該步驟。如需詳細資訊，請參閱[連接至主節點和筆記本伺服器](emr-jupyterhub-connect.md)。

1. 以 LDAP 伺服器的資訊 (例如主機 IP 地址、連接埠、綁定名稱，以此類推) 建立 LDAP 組態檔案。

1. 修改 `/etc/jupyter/conf/jupyterhub_config.py`，以啟用適用於 JupyterHub 的 LDAP 驗證器外掛程式。

1. 在 `jupyterhub` 容器中建立和執行設定 LDAP 的指令碼。

1. 為使用者查詢 LDAP，然後在容器中為每個使用者建立主目錄。JupyterHub 需要主目錄以託管筆記本。

1. 執行重新啟動 JupyterHub 的指令碼

**重要**  
在您設定 LDAP 前，請測試您的網路基礎設施，以確保 LDAP 伺服器和叢集主節點可以視需要進行通訊。TLS 通常會對純 TCP 連接使用連接埠 389。如果您的 LDAP 連線使用 SSL，熟知的 SSL TCP 連接埠是 636。

## 建立 LDAP 組態檔案
<a name="emr-jupyterhub-ldap-config"></a>

以下範例使用以下預留位置組態值。將這些取代為符合您實作的參數。
+ 該 LDAP 伺服器執行版本 3 並可在連接埠 389 上使用。此為標準的 LDAP 非 SSL 連接埠。
+ 該基本辨別名稱 (DN) 為 `dc=example, dc=org`。

使用文字編輯器來建立 [ldap.conf](http://manpages.ubuntu.com/manpages/bionic/man5/ldap.conf.5.html) 檔案，此檔案具有類似於下列的內容。使用適用於您 LDAP 實作的值。將 *host (主機)* 換成您 LDAP 伺服器的 IP 地址或可解析主機名稱。

```
base dc=example,dc=org
uri ldap://host
ldap_version 3
binddn cn=admin,dc=example,dc=org
bindpw admin
```

## 啟用適用於 JupyterHub 的 LDAP 驗證器外掛程式
<a name="emr-jupyterhub-ldap-plugin"></a>

使用文字編輯器來修改 `/etc/jupyter/conf/jupyterhub_config.py` 檔案，並新增類似於下列的 [ldapauthenticator](https://github.com/jupyterhub/ldapauthenticator) 屬性。將 *host (主機)* 換成 LDAP 伺服器的 IP 地址或可解析主機名稱。此範例假設該使用者物件在名為 *people (人員) *的組織單位 (ou) 中，並使用您之前使用 `ldap.conf` 所建立的辨別名稱元件。

```
c.JupyterHub.authenticator_class = 'ldapauthenticator.LDAPAuthenticator'
c.LDAPAuthenticator.use_ssl = False
c.LDAPAuthenticator.server_address = 'host' 
c.LDAPAuthenticator.bind_dn_template = 'cn={username},ou=people,dc=example,dc=org'
```

## 使用容器設定 LDAP
<a name="emr-jupyterhub-ldap-container"></a>

使用文字編輯器以使用下列內容建立 bash 程式碼：

```
#!/bin/bash

# Uncomment the following lines to install LDAP client libraries only if
# using Amazon EMR release version 5.14.0. Later versions install libraries by default.
# sudo docker exec jupyterhub bash -c "sudo apt-get update"
# sudo docker exec jupyterhub bash -c "sudo apt-get -y install libnss-ldap libpam-ldap ldap-utils nscd"
 
# Copy ldap.conf
sudo docker cp ldap.conf jupyterhub:/etc/ldap/
sudo docker exec jupyterhub bash -c "cat /etc/ldap/ldap.conf"
 
# configure nss switch
sudo docker exec jupyterhub bash -c "sed -i 's/\(^passwd.*\)/\1 ldap/g' /etc/nsswitch.conf"
sudo docker exec jupyterhub bash -c "sed -i 's/\(^group.*\)/\1 ldap/g' /etc/nsswitch.conf"
sudo docker exec jupyterhub bash -c "sed -i 's/\(^shadow.*\)/\1 ldap/g' /etc/nsswitch.conf"
sudo docker exec jupyterhub bash -c "cat /etc/nsswitch.conf"
 
# configure PAM to create home directories
sudo docker exec jupyterhub bash -c "echo 'session required        pam_mkhomedir.so skel=/etc/skel umask=077' >> /etc/pam.d/common-session"
sudo docker exec jupyterhub bash -c "cat /etc/pam.d/common-session"
 
# restart nscd service
sudo docker exec jupyterhub bash -c "sudo service nscd restart"
 
# Test
sudo docker exec jupyterhub bash -c "getent passwd"

# Install ldap plugin
sudo docker exec jupyterhub bash -c "pip install jupyterhub-ldapauthenticator"
```

在主節點上儲存該指令碼，然後在主節點命令列執行。例如，將指令碼儲存為 `configure_ldap_client.sh`，使檔案可執行：

```
chmod +x configure_ldap_client.sh
```

並執行該指令碼：

```
./configure_ldap_client.sh
```

## 將屬性新增至 Active Directory
<a name="emr-jupyterhub-ldap-adproperties"></a>

若要在資料庫中尋找每位使用者並建立適當的項目，則 JupyterHub Docker 容器會要求 Active Directory 中對應的使用者物件皆具備下列 UNIX 屬性：如需詳細資訊，請參閱文章[關於 Windows Server 2016 技術預覽版及更高版本中 Unix 身分管理 (IDMU) 和 NIS 伺服器角色的狀態的澄清](https://blogs.technet.microsoft.com/activedirectoryua/2016/02/09/identity-management-for-unix-idmu-is-deprecated-in-windows-server/)中的*既然 Unix 屬性外掛程式不再可用於 Active Directory 使用者和電腦 MMC 嵌入式管理單元，我該如何繼續編輯 GID/UID RFC 2307 屬性？*。
+ `homeDirectory`

  此為使用者的主目錄位置，通常是 `/home/username`。
+ `gidNumber`

  此為大於 60000 且尚未有其他使用者使用過的數值。請檢查使用中 GID 的 `etc/passwd` 檔案。
+ `uidNumber`

  此為大於 60000 且尚未有其他群組使用過的數值。請檢查使用中 UID 的 `etc/group` 檔案。
+ `uid`

  此數值與 *username* 相同。

## 建立使用者主目錄
<a name="emr-jupyterhub-ldap-directories"></a>

JupyterHub 需要容器中的主目錄來驗證 LDAP 使用者並儲存執行個體資料。下列的範例示範 LDAP 目錄中的兩個使用者，*shirley* 和 *diego*。

第一個步驟是使用 [ldapsearch](http://manpages.ubuntu.com/manpages/xenial/man1/ldapsearch.1.html)，來查詢 LDAP 伺服器，以取得每個使用者的使用者 id 和群組 id 資訊，如下列範例所示；請將 *host (主機)* 換成您 LDAP 伺服器的 IP 地址或可解析主機名稱：

```
ldapsearch -x -H ldap://host \
 -D "cn=admin,dc=example,dc=org" \
 -w admin \
 -b "ou=people,dc=example,dc=org" \
 -s sub \
 "(objectclass=*)" uidNumber gidNumber
```

`ldapsearch` 指令會針對使用者 *shirley* 和 *diego*，傳回 LDIF 格式的回應 (類似於下列的內容)。

```
# extended LDIF

# LDAPv3
# base <ou=people,dc=example,dc=org> with scope subtree
# filter: (objectclass=*)
# requesting: uidNumber gidNumber sn 

# people, example.org
dn: ou=people,dc=example,dc=org

# diego, people, example.org
dn: cn=diego,ou=people,dc=example,dc=org
sn: B
uidNumber: 1001
gidNumber: 100

# shirley, people, example.org
dn: cn=shirley,ou=people,dc=example,dc=org
sn: A
uidNumber: 1002
gidNumber: 100

# search result
search: 2
result: 0 Success

# numResponses: 4
# numEntries: 3
```

使用來自回應的資訊，在容器內執行命令，以為每個使用者的常見名稱 (`cn`) 建立主目錄。使用 `uidNumber` 和 `gidNumber` 以修正該使用者主目錄的擁有權。下列的範例指令會為使用者 *shirley* 執行此動作。

```
sudo docker container exec jupyterhub bash -c "mkdir /home/shirley"
sudo docker container exec jupyterhub bash -c "chown -R $uidNumber /home/shirley"
sudo docker container exec jupyterhub bash -c "sudo chgrp -R $gidNumber /home/shirley"
```

**注意**  
適用於 JupyterHub 的 LDAP 驗證器不支援建立本機使用者。如需詳細資訊，請參閱[本機使用者建立的 LDAP 驗證器組態注意事項](https://github.com/jupyterhub/ldapauthenticator#configuration-note-on-local-user-creation)。  
若要手動建立本機使用者，請使用下列命令。  

```
sudo docker exec jupyterhub bash -c "echo 'shirley:x:$uidNumber:$gidNumber::/home/shirley:/bin/bash' >> /etc/passwd"
```

## 重新啟動 Jupyterhub 容器
<a name="emr-jupyterhub-ldap-restart"></a>

若要重新啟動 `jupyterhub` 容器，請執行下列命令：

```
sudo docker stop jupyterhub
sudo docker start jupyterhub
```