

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 使用 LDAP 身份验证
<a name="emr-jupyterhub-ldap-users"></a>

轻型目录访问协议 (LDAP) 是一种应用程序协议，用于查询和修改与 LDAP 兼容目录服务提供程序（如 Active Directory 或 OpenLDAP server）中存储的资源（如用户和计算机）对应的对象。您可以在 Amazon EMR JupyterHub 上使用的 [LDAP 身份验证器插件](https://github.com/jupyterhub/ldapauthenticator/)使用 LDAP 进行用户身份验证。 JupyterHub此插件处理 LDAP 用户的登录会话并为 Jupyter 提供用户信息。这允许用户使用存储在 JupyterHub 兼容 LDAP 的服务器中的身份凭证来连接和笔记本电脑。

本节中的步骤将引导您完成以下步骤，使用的 LDAP 身份验证器插件设置和启用 LDAP。 JupyterHub在连接到主节点命令行时执行这些步骤。有关更多信息，请参阅[连接到主节点和 Notebook 服务器](emr-jupyterhub-connect.md)。

1. 创建一个包含 LDAP 服务器相关信息（如主机 IP 地址、端口、绑定名称等）的 LDAP 配置文件。

1. 修改 `/etc/jupyter/conf/jupyterhub_config.py` 以启用适用于 JupyterHub 的 LDAP Authenticator 插件。

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
```

## 启用 LDAP 身份验证器插件 JupyterHub
<a name="emr-jupyterhub-ldap-plugin"></a>

使用文本编辑器修改 `/etc/jupyter/conf/jupyterhub_config.py` 文件并添加与下类似的 [ldapauthenticator](https://github.com/jupyterhub/ldapauthenticator) 属性。*host*替换为 LDAP 服务器的 IP 地址或可解析的主机名。该示例假设用户对象位于名为的组织单位 (ou) 中*people*，并使用您之前使用建立的可分辨名称组件`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>

使用文本编辑器创建包含以下内容的清除脚本：

```
#!/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 属性。有关更多信息，请参阅 “*既然 Unix 属性插件不再适用于 Active Directory 用户和计算机 MM GID/UID C 管理单元，如何继续编辑 RFC 2307 属性*？ 在《[澄清 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/)。
+ `homeDirectory`

  这是用户主目录的位置，通常是 `/home/username`。
+ `gidNumber`

  这是一个大于 60000 的值，尚未被其它用户使用。检查 `etc/passwd` 文件中是否有正在使用的 GID。
+ `uidNumber`

  这是一个大于 60000 的值，尚未被其它组使用。检查 `etc/group` 文件中是否有正在使用的 UID。
+ `uid`

  这与*username*.

## 创建用户主目录
<a name="emr-jupyterhub-ldap-directories"></a>

JupyterHub 需要容器内的主目录来对 LDAP 用户进行身份验证并存储实例数据。以下示例演示了 LDAP 目录中的两个用户 *shirley* 和 *diego*。

第一步是使用 [ldapsearch 向 LDAP 服务器查询每个用户的用户 ID 和组 ID 信息，如以下示例所示，*host*替换为 LD](http://manpages.ubuntu.com/manpages/xenial/man1/ldapsearch.1.html) AP 服务器的 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"
```

**注意**  
的 LDAP 身份验证器 JupyterHub 不支持创建本地用户。有关更多信息，请参阅[关于本地用户创建的 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
```