数据迁移:索引重建_主题305:集成与迁移

这篇教程介绍了如何将Linux系统从传统的NIS身份验证迁移到LDAP,以提高安全性和扩展性。内容涵盖在开始前的准备、配置NSS和PAM使用LDAP、NIS到LDAP的迁移方法以及与多种服务的集成,如SSH、FTP、HTTP和邮件服务。通过这一过程,你可以实现统一的身份验证和权限管理,并为LPI 301考试做好准备。
摘要由CSDN通过智能技术生成

数据迁移:索引重建

在你开始前

了解这些教程可以教给您什么以及如何从中获得最大收益。

关于本系列

Linux Professional Institute (LPI)在三个级别上对Linux系统管理员进行认证: 初级 (也称为“认证级别1”), 高级 (也称为“认证级别2”)和高级 (也称为“认证级别3”) )。 要获得认证1级,您必须通过考试101和102。要达到认证2级,您必须通过考试201和202。要达到认证3级,您必须具有有效的高级认证并通过考试301(“核心”)。 您还可以通过其他高级专业考试。

developerWorks提供了教程,以帮助您准备五个初级,高级和高级认证考试。 每个考试涵盖几个主题,并且每个主题在developerWorks上都有一个相应的自学教程。 表1列出了LPI 301考试的六个主题和相应的developerWorks教程。

表1. LPI 301考试:教程和主题
LPI 301考试主题 developerWorks教程 教程总结
主题301 LPI 301考试准备:
概念,体系结构和设计
了解有关LDAP概念和体系结构,如何设计和实现LDAP目录以及架构的信息。
主题302 LPI 301考试准备:
安装与开发
了解如何安装,配置和使用OpenLDAP软件。
主题303 LPI 301考试准备:
组态
详细了解如何配置OpenLDAP软件。
主题304 LPI 301考试准备:
用法
了解如何搜索目录并使用OpenLDAP工具。
主题305 LPI 301考试准备:
整合与迁移
(本教程)了解如何使用LDAP作为系统和应用程序的数据源。 请参阅详细目标
主题306 LPI 301考试准备:
容量规划
快来了。

要通过301考试(并达到3级认证),必须满足以下条件:

  • 您应具有多年在各种用途的计算机上安装和维护Linux的经验。
  • 您应该具有与各种技术和操作系统的集成经验。
  • 您应该具有作为企业级Linux专业人员的专业经验或接受过培训(包括作为其他角色的一部分的经验)。
  • 您应该了解Linux管理的高级和企业级别,包括安装,管理,安全性,故障排除和维护。
  • 您应该能够使用开源工具来衡量容量计划并解决资源问题。
  • 您应该具有使用LDAP与UNIX®服务和Microsoft®Windows®服务(包括Samba,可插拔身份验证模块(PAM),电子邮件和Active Directory)集成的专业经验。
  • 您应该能够使用Samba和LDAP进行规划,架构,设计,构建和实施完整的环境,以及衡量服务的容量规划和安全性
  • 您应该能够使用Bash或Perl创建脚本,或者至少了解一种系统编程语言(例如C)。

要继续为3级认证做准备,请参阅LPI 301考试系列的developerWorks教程 ,以及整套developerWorks LPI教程

Linux Professional Institute不特别认可任何第三方考试准备材料或技术。

关于本教程

欢迎使用“集成和迁移”,这是为您准备LPI 301考试而设计的六个教程中的第五个。在本教程中,您将学习有关LDAP与身份验证和其他UNIX服务集成的所有信息。

本教程根据该主题的LPI目标进行组织。 粗略地说,对于权重较高的目标,应在考试中遇到更多问题。

目标

表2提供了本教程的详细目标。

表2.集成和迁移:本教程涵盖的考试目标
LPI考试目标 客观体重 客观总结
305.1
LDAP与PAM和NSS集成
2 将核心系统身份验证与LDAP集成在一起。
305.2
NIS到LDAP的迁移
1个 计划并实施NIS迁移策略,包括将NIS部署到LDAP网关。
305.3
将LDAP与UNIX服务集成
1个 使用LDAP服务器作为SSH,FTP,HTTP和其他服务的数据源。
305.4
将LDAP与Samba集成
1个 使用您的LDAP服务器作为Samba的数据源。
305.5
将LDAP与Active Directory集成
2 将您的LDAP服务器与Active Directory服务一起使用。
305.6
将LDAP与电子邮件服务集成
1个 将您的电子邮件服务与LDAP目录集成。

先决条件

为了从本教程中获得最大收益,您应该具有Linux的高级知识以及可以在其上实践所涵盖命令的Linux系统。

如果您的基本Linux技能有点生锈,那么您可能需要先阅读LPIC-1和LPIC-2考试教程

程序的不同版本可能会不同地格式化输出,因此您的结果可能看起来与本教程中的清单和图不完全相同。

系统要求

要按照这些教程中的示例进行操作,您将需要具有OpenLDAP软件包并支持PAM的Linux工作站。 大多数现代发行版都满足这些要求。

LDAP与PAM和NSS集成

本节介绍了高级Linux专业人员(LPIC-3)考试301的主题305.1的材料。此主题的权重为2。

在本节中,学习如何:

  • 配置NSS以从LDAP检索信息
  • 配置PAM以使用LDAP进行身份验证
  • 在各种UNIX环境中配置PAM模块

PAM和名称服务交换(NSS)功能以传统的UNIX方式从其实现中抽象出身份验证和查找的各种组件,这使管理员可以更改后端数据存储而无需重新编译任何应用程序。 例如,由于NSS是作为C库的一部分实现的,因此从传统的基于/ etc / passwd的身份验证转移到网络信息服务(NIS)是透明的。 应用程序使用诸如getpwent(3)之类的标准库调用来查找用户,但是通过一些配置魔术,数据被重定向到另一个存储,例如NIS。

PAM稍有不同,因为在编写应用程序时必须牢记PAM。 管理员可以使用一组丰富的库来自定义PAM感知应用程序的行为,例如需要特定的组成员身份和登录时间才能成功进行身份验证。

PAM和NSS可以协同工作以进行用户身份验证。 支持PAM的应用程序指示PAM检查用户的凭据。 除其他限制外,管理员还可以配置PAM通过NSS工具检查密码。 PAM仅用于密码和影子数据库,不用于组和主机之类的其他数据库。

来自PADL软件的开源软件包提供了对PAM和NSS的LDAP支持。

配置NSS以使用LDAP

NSS功能在C库中实现,作为对获取信息的传统库调用的钩子。 C库提供了诸如getpwent功能来获取用户信息和gethostbyname(3)用于主机信息的功能,这些功能通常分别实现为对/ etc / passwd和/ etc / hosts的查找。 管理员可以通过配置NSS来强制主机名查找也使用域名服务(DNS),这意味着应用程序不知道更改。

了解NSS

表3概述了NSS处理的数据库。 大多数数据库在/ etc中都有一个对应的文件,传统上是在其中存储数据。

表3. NSS数据库
数据库名称 描述
aliases sendmail的邮件别名,用于将一个本地地址转发(别名)到另一个地址。
ethers 将以太网地址映射到IP地址。 由于地址解析协议(ARP)的可用性,再也很少见了。
group 包含组列表和属于它们的用户。
hosts 将IP地址映射到主机名。
netgroup 用于将服务器分组在一起。 最常用于NIS和网络文件系统(NFS)安全。
networks 网络名称到数字的映射。 很少使用,因为知道网络名称几乎没有价值。
passwd 存储用户帐户信息,例如名称,用户标识,描述,主要组,主目录,有时还包括密码。
protocols 将IP协议映射到其名称。
publickey 用于分发NFS和NIS +的密钥。
rpc 将远程过程调用(RPC)函数名称映射为数字。
services 将TCP和UDP服务名称映射到端口号。
shadow 受保护的加密密码文件。 通常,/ etc / passwd中的密码字段存储在此文件中,以确保安全。

NSS在/ etc / nsswitchconf中配置,并且在表3中每个数据库包含一行。清单1显示了一个示例nsswitch.conf。

清单1.样例nsswitch.conf
passwd: files nis shadow: files nis group: files nis hosts: files nis dns

清单1配置了四个映射:passwd,shadow,group和host。 映射的名称后跟一个冒号(:),然后是访问数据的方式的有序列表。 清单1中的前三行都是相同的:它们首先检查文件中所请求的信息,然后检查NIS,有时也称为黄页 。 仅在文件中未找到任何内容时,才检查NIS。 该示例的最后一行检查文件(/ etc / hosts),NIS,然后检查DNS是否有任何主机请求。

nsswitch.conf中可用的方法在/ lib中有一个对应的库,以libnss_ 。 例如,文件功能可在/lib/libnss_files-2.5.so中找到(版本号并不重要,因为它由动态链接器ld-linux.so解析)。

将LDAP引入NSS

在前面讨论了动态库和nsswitch.conf的格式之后,毫不奇怪,与NSS的LDAP集成是通过名为libnss_ldap的共享库处理的,并通过/etc/nsswitch.conf中的ldap关键字进行引用。 此共享库从/etc/ldap.conf中获取其配置(不要与命令行客户端/etc/openldap/ldap.conf的OpenLDAP配置文件相混淆)。 清单2显示了一个示例ldap.conf。

清单2.用于配置libnss_ldap的示例ldap.conf
# Server IP address (or space-separated addresses) host 192.168.1.138 # Search base base dc=ertw,dc=com # optional: bind credentials binddn: cn=nssldap,dc=ertw,dc=com bindpw: letmein # If root is making the request, use this dn instead # The password is stored in /etc/ldap.secret and only readable by root rootbinddn cn=root,dc=ertw,dc=com # Point the passwd, shadow, and group databases at a DN # the ?one defines the scope nss_base_passwd ou=People,dc=ertw,dc=com?one nss_base_shadow ou=People,dc=ertw,dc=com?one nss_base_group ou=Group,dc=ertw,dc=com?one # Don't look for secondary groups for any of these users nss_initgroups_ignoreusers root,ldap,named,avahi,haldaemon,dbus,radvd,tomcat,radiusd

除了清单2中显示的/etc/ldap.conf的内容外,还需要在/etc/nsswitch.conf中的passwd,shadow和group行中添加关键字ldap 。 始终确保将files作为第一个条目。 否则,您可能会发现自己正在等待关闭的服务器超时-甚至可能被锁定在系统之外。 (如果由于nsswitch.conf问题而被锁定,请引导至单用户模式,将nsswitch.conf重置为files ,然后重新启动。)

可以对所有数据库使用LDAP,但是这里列出的三个是有用的。 其他地图很少更改,应单独管理。 hosts数据库除外,它可以使用LDAP,尽管DNS是更好的选择。

测试一下

如果已正确配置了nsswitch.conf和ldap.conf,则只要具有以下属性,就应该能够使用LDAP用户登录:

  • uid :登录名
  • uidNumber :数字用户ID
  • gidNumber :主要组编号
  • homeDirectory :用户的主目录
  • userPassword :用{crypt}例程加密的用户密码(使用slappasswd生成此密码)

这些属性以及更多属性是通过posixAccount objectClass添加的。

要进行测试,请尝试以LDAP树中的用户身份登录,而不要以本地密码文件中的用户身份登录。 您也可以使用getent passwd命令查看NSS知道的所有用户条目。 如果getent有效但登录无效,则您的userPassword属性可能不正确。

如果您已经在客户端上验证了配置,并且NSS和LDAP仍然无法一起使用,请在OpenLDAP服务器上启用stats级别的日志记录,并查看服务器是否正在查看您的查询,以及是否允许查询。

配置PAM以使用LDAP

PAM与NSS非常相似,它从实际实现中抽象出一组库调用。 与NSS不同,PAM不会替换现有的UNIX调用。 相反,它提供了一组可供应用程序使用的新调用。

了解PAM

PAM被实现为应用程序使用的库。 应用程序调用此库以使用PAM管理功能,以检查身份验证,帐户管理,会话管理和密码管理。

检查身份验证是PAM的主要目的。 该应用程序询问PAM库是否对用户进行了身份验证。 PAM库依次遵循系统管理员制定的规则,以提示用户输入密码或执行许多其他检查。

在用户提供有效的凭据之后运行帐户管理,并负责检查是否允许登录。 某些时候或某些应用程序可能不允许登录。

会话管理使应用程序有机会在成功登录后设置环境。 通常需要给登录到控制台的用户一些额外的权限,例如使用本地CDROM或其他设备。 这是在会话管理级别完成的。

最后,密码管理提供了一种灵活的方式来更改密码。 您将很快看到,该功能使用户可以通过熟悉的passwd(1)程序更改其LDAP密码。 PAM密码管理还允许您指定独立于密码后端运行的密码强度策略。

要为服务配置PAM,必须在/etc/pam.d中创建以该服务命名的文件,例如sshd服务的/etc/pam.d/sshd。 这不是一成不变的规则,因为应用程序指定了自己的PAM服务名称。 如有疑问,请使用二进制文件的名称,并检查日志中是否有错误。

/etc/pam.d中的每个配置文件都为每个PAM管理功能指定了指令的有序列表。 文件中的每一行都是function control module arguments形式。 该功能是管理功能,使用关键字authaccountsessionpassword

该控件指定如何使用要评估的指令的返回值,并且是以下关键字之一:

  • required -如果功能成功,则此检查必须成功。 如果此检查失败,则PAM将继续检查给定功能的其余指令,但结果毫无意义。
  • requisite -如果功能成功,则此检查必须成功。 如果此检查失败,则PAM将停止检查其余说明,并返回失败信息。
  • sufficient -如果此检查成功,则假定先前的“必需”元素均未失败,则处理将停止并且函数将成功返回。 如果此检查失败,则忽略该失败并继续处理。
  • optional -检查结果将被忽略。

模块和参数本身实现检查。 同一模块可以实现所描述的一个或多个功能,因此您可能会多次看到同一模块。 您将经常使用的一个模块是pam_stack ,它使您可以从其他文件调用指令堆栈。 清单3显示了使用pam_stack的PAM文件。

清单3.使用pam_stack调用其他指令栈
auth required pam_nologin.so auth required pam_stack.so service=system-auth account required pam_stack.so service=system-auth session required pam_stack.so service=system-auth password required pam_stack.so service=system-auth

清单3显示了PAM文件的格式。 auth函数有两行,这两项都是必需的,因此必须成功才能成功进行身份验证。 第一行auth调用pam_nologin ,如果/ etc / nologin文件存在时非root用户尝试登录,其工作将失败。 下一条auth行调用pam_stack模块,并将其传递给service=system-auth 。 然后,pam_stack.so读取/etc/pam.d/system-auth的内容,并检查auth函数下的所有指令。 如果返回成功,则pam_stack将成功结果返回到清单3中的文件。

其他三个功能( accountsessionpassword仅引用pam_stacksystem-auth服务。 如果system-auth的各个功能成功返回,则结果被视为成功。

许多系统具有一组通用的身份验证例程,因此pam_stack用于大多数文件中,而system-auth(或等效文件)包含所有有趣的部分。 在本节的其余部分中,system-auth文件将是用于将LDAP注入PAM进程的文件。

将LDAP引入PAM

NSS和PAM模块都使用/etc/ldap.conf进行配置,因此,如果您按照以下说明进行操作,则意味着PAM-LDAP系统可以正常工作了。 可以将NSS和PAM一起使用,以便支持PAM的应用程序和旧版应用程序都可以通过LDAP进行身份验证。 PAM在NSS之上提供了一些新功能,其中包括:

  • 用户密码更改
  • 身份验证要求的更精细配置
  • 支持更多密码加密类型
  • 集中管理用户帐户

确保pam_password md5在/etc/ldap.conf中,并删除任何其他pam_password行(如果存在)。 这告诉pam_ldap库在更改密码时,先在本地使用Message Digest 5(MD5)对密码进行哈希处理,然后再将其发送到LDAP服务器。

编辑/etc/pam.d/system-auth(或等效文件)以添加对pam_ldap的引用,如清单4所示。该行应在对pam_unix任何引用之后(以便本地帐户优先于LDAP帐户),但是在任何对pam_allowpam_deny引用(提供默认允许或拒绝)之前。

清单4.使用pam_ldap新system-auth
auth sufficient pam_unix.so nullok try_first_pass auth sufficient pam_ldap.so use_first_pass auth required pam_deny.so account required pam_unix.so broken_shadowaccount sufficient pam_ldap.so account required pam_permit.so password requisite pam_cracklib.so try_first_pass retry=3 password sufficient pam_unix.so md5 shadow nullok try_first_pass use_authtok password sufficient pam_ldap.so use_authtok password required pam_deny.so session required pam_limits.so session required pam_unix.so session optional pam_ldap.so

粗线显示了对PAM配置文件的补充。 请注意pam_unixaccount功能中增加了broken_shadow 。 这样可以确保pam_unix.so在用户没有影子条目的情况下不会返回失败(由于帐户位于LDAP中,所以没有)。

pam_ldapauth模块的use_first_pass选项强制pam_ldap.so使用从pam_unix.so获得的密码,而不是要求输入新密码。 use_authtokpassword功能做类似的事情。

为了进行授权,新配置使UNIX密码和LDAP密码都足以登录:即,第一个成功的密码将允许用户登录。如果两个都不返回成功(失败或“无此用户”),然后pam_deny导致失败。

测试一下

尝试通过passwd命令更改用户密码,然后验证LDAP目录中的密码是否已更改。 最后,确保用户仍然可以登录。

如果您能够使NSS工作,则PAM也应该工作。 错误的最大机会是将PAM配置中的条目弄混,将条目放入错误的文件中,或将其放置在文件中的错误位置。

NIS到LDAP的迁移

本节介绍了高级Linux专业人员(LPIC-3)考试301的主题305.2的材料。此主题的权重为1。

在本节中,学习如何:

  • 在迁移到LDAP之前分析NIS结构
  • 与LDAP集成之前分析NIS结构
  • 自动化NIS到LDAP的迁移
  • 创建NIS到LDAP网关

NIS是用于UNIX计算机的中央身份验证的传统方法。 NIS易于设置且运行良好。 尽管更为复杂,但LDAP身份验证在几个方面优于NIS:

  • LDAP比NIS更安全,因为您可以加密流量并锁定数据库。
  • LDAP不仅可以存储身份验证数据,而NIS受限制。
  • 与NIS相比,更多的客户端可以访问LDAP。

您可以选择用LDAP替换NIS或同时使用两者。 当它们一起使用时,LDAP是规范数据源,NIS服务器使用LDAP中的数据而不是本地文件。 这是长期迁移或支持无法与LDAP一起使用的旧版操作系统的好方法。

方法1:迁移到LDAP

从NIS迁移到LDAP的一般方法如下:

  1. 确定需要替换哪些NIS数据库。
  2. 将NIS数据加载到LDAP中。
  3. 重新配置客户端以使用LDAP而不是NIS。

在步骤2开始到步骤3结束之间的时间内,您有两个没有连接的活动数据库。 任何更改,例如添加用户或更改用户密码,都必须在两个数据库上都进行; 否则,您的数据可能会变得不一致。 您可以选择冻结所有更改,也可以选择集成策略,如下一节所示。

分析您现有的NIS结构

在执行任何迁移之前,您必须确定NIS托管哪些数据库。 登录NIS主服务器,并查看数据库目录。 在大多数系统上,文件存储在/ var / yp /中,以域名命名。 清单5显示了典型NIS服务器的数据库目录中的文件。

清单5.确定NIS服务的数据库
# ls /var/yp/`domainname` group.bygid group.byname hosts.byaddr hosts.byname mail.aliases netid.byname passwd.byname passwdbyuid protocols.byname protocols.bynumber rpc.byname rpc.bynumber services.byname services.byservicename ypservers

清单5使用domainname命令显示域名。 当放在反引号(`)内时,此命令的结果将插入命令行中。 除了ypservers文件之外,此目录中的所有其他文件均表示NIS数据库。 收集唯一数据库名称的列表,以确定哪些数据库需要移动到LDAP。 NIS使用不同的查找关键字来存储相同的数据,例如对于密码文件,使用名称和UID。 在这种情况下,它们都代表密码数据库。 有些并不明显:例如,mail.aliases是别名表。 如有疑问,请查看/ var / yp / Makefile以确定数据库的来源。

查看服务器后,您可能希望检查一些NIS客户端,以确定它们正在使用哪些映射。 为此,请在/etc/nsswitch.conf中查找nis关键字。 您可能会发现您的服务器存储的地图超过了正在使用的地图。

使用迁移工具

PADL软件, pam_ldapnss_ldap的制造商以及稍后讨​​论的NIS-LDAP网关提供了将NIS数据迁移到LDAP的最受欢迎的工具。 您的发行版中可能包含文件; 否则,您可以在“ 相关主题”部分中找到这些工具的链接。 PADL迁移工具可以从本地文件,NIS或NIS +中获取数据,并将其转储到LDAP服务器中。

在使用PADL工具之前,您必须先启动LDAP服务器并使其不运行任何数据。 该工具将生成所有必需的条目,并且您要避免重复。

迁移工具由一组Shell和Perl脚本组成。 在RedHat系统上,这些脚本是openldap-servers软件包的一部分,位于/ usr / share / openldap / migration目录中。 Debian用户将需要migrationtools软件包。 查找名为migration_base.pl的文件,或从PADL下载最新版本。

这些脚本从各种来源获取数据,将其转换为LDIF,然后将其添加到您的服务器。 数据是在联机模式下通过ldapadd命令添加的,而在脱机模式下是通过slapadd ,因此前者需要管理凭据,而后者则需要停止LDAP进程。

在开始之前,您会发现设置一些环境变量来设置树的基本域名(DN)和您的根DN很有帮助。 清单6显示了bash命令,以为ertw.com域的迁移做准备。

清单6.设置环境变量以准备进行LDAP迁移
export LDAP_BASEDN="dc=ertw,dc=com" export LDAP_BINDDN="cn=root,dc=ertw,dc=com" export LDAP_DEFAULT_MAIL_DOMAIN=ertw.com

清单6中的第一行是LDAP树的基本DN,稍后将用于生成所有DN。 第二行是您的根DN。 仅在使用在线模式时才需要密码。 清单6的最后一行设置了电子邮件地址的默认域名。 有些工具不会提示您输入此信息,因此,现在进行设置可以防止以后的情况恶化。

这些工具分为两类。 第一个类别中的文件的名称以migrate_all_开头。 第二类包括其余文件,这些文件的名称以migrate_开头,后跟文件或数据库的名称。 第一类中的脚本用于将数据收集在一起。 第二类用于将本机格式转换为LDIF。

您现在有两个选择。 您可以使用migrate_all_脚本之一,它将自动从您选择的位置(NIS,文件,NIS + m等)中获取所有通用数据库。 或者您可以自己仅获取相关数据,然后使用各个迁移脚本将数据转换为LDIF。 第一种方法在可行时更容易。 清单7显示了使用migration_all_nis_online.sh以在线模式将所有数据从NIS迁移到LDAP的过程。

清单7.使用migrate_all_nis_online.sh脚本将数据从NIS迁移到LDAP
[root@server1 migration]# ./migrate_all_nis_online.sh Enter the NIS domain to import from (optional): No such map networks.byaddr. Reason: Internal NIS error Enter the hostname of your LDAP server [ldap]: localhost Enter the credentials to bind with: mypassword Do you wish to generate a DUAConfigProfile [yes|no]? no Importing into dc=ertw,dc=com... Creating naming context entries... Migrating groups... Migrating hosts... Migrating networks... Migrating users... Migrating protocols... Migrating rpcs... Migrating services... Migrating netgroups... Migrating netgroups (by user)... sh: /etc/netgroup: No such file or directory Migrating netgroups (by host)... sh: /etc/netgroup: No such file or directory adding new entry "dc=ertw,dc=com" Importing into LDAP... adding new entry "ou=Hosts,dc=ertw,dc=com" ..... output omitted ... adding new entry "cn=rquotad,ou=Rpc,dc=ertw,dc=com" adding new entry "cn=rquotad,ou=Rpc,dc=ertw,dc=com" ldap_add: Already exists (68) /usr/bin/ldapadd: returned non-zero exit status: saving failed LDIF to /tmp/nis.ldif.X17515

清单7首先运行migration_all_nis_onlinesh脚本,该脚本从NIS获取数据,将其转换为LDIF,然后使用ldapadd导入数据。 脚本中的第一个查询是NIS域。 您可以按Enter键以获取系统上的默认NIS域。 然后,脚本将导入NIS数据(在此系统上,由于未使用网络映射,因此会显示非致命错误)。 该脚本提示有关LDAP服务器的信息,例如主机名和密码(绑定DN和基本DN是通过您在清单6中输入的环境变量来学习的)。 您应该选择不导入DUAConfigProfile除非您有支持它的模式(这不太可能)。

如果此时开始出现有关无效DN语法的错误,请确保已将nis.schema文件导入slapd.conf中。

如果您的架构正确,则脚本会将数据导入到LDAP树中。 该脚本可能会死于错误,如清单7末尾所示。由于数据存储在NIS中的方式,您在某些数据库中可能会有重复的条目。 这在NIS中很好,但在LDAP中则不行。 根据您的需求,有几种解决方案:

  • 编辑LDIF文件(在这种情况下为/tmp/nis.ldif.X17515)以删除重复项,然后删除LDAP数据库并导入该文件。
  • 使用-c选项告诉ldapadd忽略错误。 export LDAPADD="/usr/bin/ldapadd -c"将执行此操作。 (请注意,脚本仍将报告错误,但数据已被导入。)
  • 编辑migrate_all_nis_online.sh以将ETC_SERVICESETC_PROTOCOLSETC_RPC的值设置为/ dev / null而不是临时文件。 这样做会跳过对数据库的处理。 (请注意,某些migration_all_脚本可以被环境变量而不是NIS变体覆盖。)
  • 跳过migrate_all_nis_online.sh,然后手动迁移。

只要您对结果满意(例如第三个选项中没有LDAP中的协议,RPC和服务),前三个选项就可以自我解释并有效。 第四个选项需要一些解释。

如果您要做的只是将组和用户移至LDAP,则可以轻松地自己复制文件并使用提供的其他脚本并使用ypcat从NIS中获取数据来生成LDIF。 清单8显示了该过程。

清单8.手动迁移组和用户
[root@server1 migration]# ypcat passwd > /tmp/passwd.tmp [root@server1 migration]# ypcat group > /tmp/group.tmp [root@server1 migration]# ./migrate_base.pl > /tmp/ldif [root@server1 migration]# ./migrate_passwd.pl /tmp/passwd.tmp >> /tmp/ldif [root@server1 migration]# ./migrate_group.pl /tmp/group.tmp >> /tmp/ldif [root@server1 migration]# ldapadd -x -D "cn=root,dc=ertw,dc=com" \ -w "mypassword" -f /tmp/ldif adding new entry "dc=ertw,dc=com" adding new entry "ou=Hosts,dc=ertw,dc=com" ..... output omitted ...

清单8的前两行使用ypcat将来自NIS的数据获取到/ tmp中的文件中。 接下来的三行生成LDIF。 migrate_base在树中生成一些基本条目,接下来的两行将密码和组文件转换为LDIF。 注意,使用append运算符(>>),因此生成的文件将包含所有三个迁移脚本的输出。 最后,您调用ldapadd导入数据。

无论您采用哪种方式,都要执行一些基本搜索以确保可以看到数据。 确保您可以看到密码哈希(为此使用根DN,因为您可能有一个访问控制列表,以防止看到密码)。

此时,您已将NIS数据存储在LDAP中。 在移走所有NIS客户端之前,必须将对NIS的所有更改复制到LDAP,反之亦然。

移动客户端并验证结果

移动客户端是在客户端上设置NSS和PAM的简单问题。 上一节详细介绍了这一点。 简而言之,用服务器信息填充/etc/ldap.conf,然后编辑/etc/nsswitch.conf,用ldap替换nis 。 如果要设置PAM,则需要在/etc/pam.d中编辑相关文件,以添加对pam_ldap.so的引用。

通过以常规用户身份登录客户端并在移至LDAP的数据库上运行getent命令来测试客户端。

方法2:与LDAP集成

第二种方法要求NIS和LDAP共存。 如果您的客户使用不使用LDAP的客户端(或者没有本地LDAP模块或不支持PAM),或者希望在更长的时间内扩展过渡,这将很有帮助。 NIS / LDAP共存的方法类似于第一种策略:

  1. 确定正在使用哪些NIS数据库。
  2. 将NIS数据加载到LDAP中。
  3. ypldapd替换您的NIS服务器。
  4. 重新配置将使用LDAP的客户端。

继续使用NIS的客户端不需要更改,因为ypldapd是功能齐全的NIS服务器。 它和操作系统随附的标准ypserv之间的唯一区别是ypldapd从LDAP而不是本地文件获取数据。

前两个步骤与第一个方法相同,因此从步骤3开始。

用ypldapd替换您的NIS服务器

ypldapd是一个NIS服务器守护程序,它从LDAP而不是/ var / yp中的数据库文件获取其信息。 这是一个从PADL商业软件,但你可以通过电子邮件发送PADL 30天的试用许可证(参见相关主题 )。 ypldapd安装是一个简单的过程:

  1. 将软件解压缩到/ opt / ypldapd。
  2. 将许可证复制到/opt/ypldapd/etc/padlock.ldif。
  3. 编辑配置文件/opt/ypldapd/etc/ypldapd.conf
  4. 停止现有的NIS服务器。
  5. 启动ypldapd。

首先,以根用户身份运行mkdir -p /opt/ypldapd以创建ypldapd目录(如果不存在,则为/ opt)。 切换到该目录( cd /opt/ypldapd ),然后使用tar -xzf /tmp/ypldapd_linux-i386.tar.gz解压缩ypldapd发行tar -xzf /tmp/ypldapd_linux-i386.tar.gz 。 这会将ypldapd文件放置在正确的目录中。

您将获得一个许可证文件,该文件将放置在/opt/ypldapd/etc/padlock.ldif中。 如果要从电子邮件中复制,请确保电子邮件客户端未使用长行:密钥应为四行,并带有一系列attribute:value对。

ypldapd的配置文件在/opt/ypldapd/etc/ypldapd.conf中。 您可以复制一个名为ypldapd.conf.sample的文件作为开始。 与到目前为止所看到的其他实用程序一样,您需要提供有关LDAP服务器的信息。 清单9显示了一个简单的ypldapd.conf。

清单9.样例ypldapd.conf
# The NIS domain name ypdomain ertw # The LDAP server and base DN ldaphost localhost basedn dc=ertw,dc=com # Credentials... The user must be able to read the userPassword attribute binddn cn=ypldapd,dc=ertw,dc=com bindcred mypassword # The map of NIS databases to DNs (relative to basedn) # If you used the migration tools then you shouldn't have to change anything namingcontexts namingcontexts.conf # Should ypldapd cache data? caching on # Cache lifetime, in minutes cache_dump_interval 15 # Should passwords be hidden? hide_passwords off # How many ypldapd servers can be running at a given time? maxchildren 5

有了ypldapd.conf,您可以关闭ypserv所有实例,然后运行sbin/ypldapd ,这ypldapd在后台启动ypldapd

移动客户端并验证结果

要测试新的NIS服务器,请运行ypwhich ,它告诉您绑定到哪个NIS服务器。 如果出现错误,请确保没有其他ypserv实例在运行,并且仅一个ypldapd正在运行。 然后,尝试通过键入ypcat passwd来获取地图(假定您的服务器也在运行客户端)。

将要使用NIS的客户端也应该能够在新服务器上运行ypwhichypcat 。 对于将要迁移到LDAP的客户端,请参阅上一组迁移说明。

将LDAP与UNIX服务集成

本节介绍了高级Linux专业人员(LPIC-3)考试301的主题305.3的材料。此主题的权重为1。

在本节中,学习如何:

  • 将SSH与LDAP集成
  • 将FTP与LDAP集成
  • 将HTTP与LDAP集成
  • 将FreeRADIUS与LDAP集成
  • 将打印服务与LDAP集成

如果您已配置NSS和PAM,则大多数应用程序都可以与LDAP一起正常使用。 需要告知某些应用程序使用PAM,或通过正确访问LDAP提供其他功能。 本节重点介绍常见的UNIX守护程序以及它们如何支持LDAP集成。

将SSH与LDAP集成

只要已编译功能,OpenSSH发行版就通过PAM与LDAP集成。要检查,请运行ldd /usr/sbin/sshd | grep pam ldd /usr/sbin/sshd | grep pam查看PAM共享库是否已链接。 如果没有,则必须使用--with-pam重新编译sshd

要使用PAM,请确保有一个名为/etc/pam.d/sshd的PAM配置文件(如果尚不存在)。 清单10显示了一个使用system-auth堆栈的示例PAM文件。

清单10.一个示例/etc/pam.d/system-auth
auth required pam_stack.so service=system-auth account required pam_stack.so service=system-auth password required pam_stack.so service=system-auth session required pam_stack.so service=system-auth

使用PAM配置文件后,您可以配置sshd以与PAM一起使用。 在/ etc / ssh / sshd_config中,添加UsePAM yes ,然后重新启动sshd

将FTP与LDAP集成

有许多FTP守护程序可用,尚不清楚哪些守护程序适用于LPIC 3考试。

最简单的集成方法是依靠NSS集成。 当FTP服务器执行密码查找时,NSS工具将使用LDAP。

但是,在现代,FTP服务器很可能是通过PAM支持构建的。 在这些情况下,您可以在/etc/pam.d中创建PAM配置文件。 该文件通常称为ftp,但可以根据软件和发行版来覆盖。 例如,RedHat将vsftpd守护程序打包为使用/etc/pam.d/vsftpd而不是默认的/etc/pam.d/ftp。

ftp守护程序找到其PAM配置文件后,便会像处理其他任何PAM客户端一样对其进行处理。 清单10中的配置足以开始。 您还可以考虑在auth阶段使用pam_listfile.so item=user sense=deny file=/etc/ftpusers onerr=succeed pam_shells pam_listfile.so item=user sense=deny file=/etc/ftpusers onerr=succeedpam_shells来限制可以登录的用户和有效的Shell,就像旧版FTP服务器一样。

将HTTP与LDAP集成

Apache Web服务器具有使用LDAP后端而不是传统的htpasswd基于文件的后端来处理基本HTTP身份验证的模块。 这是通过mod_authnz_ldapmod_ldap模块提供的。 第一个模块提供了使用LDAP信息对Web用户进行身份验证的机制,而mod_ldap提供了用于mod_authnz_ldap (或任何将来的基于LDAP的模块)访问LDAP的接口,包括连接池和缓存。

本节中的说明参考Apache 2.2。 如果您使用的是Apache 2.0,则使用mod_auth_ldap模块而不是mod_authnz_ldap 。 这两个模块的配置类似。

mod_ldapmod_authnz_ldap都是Apache发行版的一部分。 如果手动编译Web服务器,则需要在configure命令中添加--enable-authnz-ldap --enable-ldap 。 如果使用发行版的Apache,则安装适当的模块(对于Red Hat发行版,这些模块是核心httpd软件包的一部分)。

当用户向受保护的资源发出请求时,Apache返回错误代码401(未授权)。 此时,Web浏览器应提示用户输入用户名和密码。 然后,Web浏览器使用在Authorization标头中编码的此信息重新发出请求。 如果用户名和密码被Web服务器接受,则该页面将提供给客户端; 否则,服务器返回另一个401。

Apache, when configured to check passwords against LDAP, first binds to the server as a predefined user and performs a lookup on the user to find the DN. The server then rebinds as the user with the provided password. If the server can successfully bind as this user, the authentication is considered successful.

After a successful authentication, the server can be configured to perform additional authorization tasks, such as checking against the DN or attribute, or testing to see if the user passes a search filter. If any of these tests are configured, then the test must pass for the authorization to pass.

Configuration of mod_authnz_ldap is similar to the standard authentication method using text files. Listing 11 shows the simplest case of LDAP authentication with no authorization.

Listing 11. Apache configuration for LDAP authentication
LoadModule ldap_module modules/mod_ldap.so LoadModule authnz_ldap_module modules/mod_authnz_ldap.so <Location /protected> AuthType basic AuthName ProtectedByLDAP AuthBasicProvider ldap AuthLDAPUrl ldap://192.168.1138/ou=People,dc=ertw,dc=com?uid # Anon bind for first phase #AuthLDAPBindDN #AuthLDAPBindPassword AuthzLDAPAuthoritative off require valid-user </Location>

The first two lines of Listing 11 load the required modules into the Web server. The rest of the configuration is enclosed in a Location container, meaning it applies only to requests beginning with /protected . The configuration first declares Basic authentication and a name of ProtectedByLDAP . The Web browser shows the name to the user. The AuthBasicProvider line tells Apache that authentication is provided through LDAP.

Listing 11 continues with AuthLDAPUrl , which points Apache to the LDAP server. The form of the parameter is ldap://host:port/basedn?attribute?scope?filter . host and port define the LDAP server, and basedn is the base DN from which the initial search is performed. attribute refers to the attribute that will be searched along with the username during the initial search (the default is uid ). scope is either one or sub to correspond with one level or all children. filter is an optional filter that will be logically ANDed with the search for the given user/attribute combination.

The example in Listing 11 has AuthLDAPBindDN and AuthLDAPBindPassword commented out, which results in an anonymous bind. If you want to specify a user here, you may. Either way, the user performing the initial bind must be able to search on the attribute provided in the AuthLDAPUrl command.

The final two lines disable authorization by allowing any validated user. AuthzLDAPAuthoritative off means that a later module can allow the access even if LDAP denies authorization (but not authentication). require valid-user comes from another module, so this deferral is required. Instead of these two lines, you can use LDAP-related ones, such as checking for group membership or an LDAP attribute. Listing 12 shows part of the configuration from Listing 11, but it restricts access to people with the ou=Engineering attribute and value.

Listing 12. Restricting access to a particular OU
AuthzLDAPAuthoritative on require ldap-filter ou=engineering

Two things are notable in Listing 12. First, AuthzLDAPAuthoritative is now on (this is the default) because your requirement can be handled by the LDAP module. Second, the ldap-filter doesn't include parentheses. Apache uses the given LDAP filter and also performs a logical AND with the uid (or whichever attribute you specified in the AuthLDAPUrl command) and builds the search filter with a simple string insertion. If you have extra quotes or parentheses in your filter, the resulting query becomes invalid. The authentication fails, and a log message is printed to the server's error_log.

Integrate FreeRADIUS with LDAP

FreeRADIUS is an open source Remote Authentication Dial In User Service (RADIUS) server that is often used for authentication of dial-up or other network devices. Clients use RADIUS to authenticate users, and the RADIUS server in turn uses LDAP to find its information.

You can integrate PAM and FreeRADIUS two ways: by using PAM, or by enabling native LDAP support through the rlm_ldap module. The choice depends on how you plan to use RADIUS. If all you need is authentication, or you don't wish to modify your LDAP schema, then use PAM. If you need to use RADIUS attributes, then it's easier to configure the LDAP module and store the attributes in LDAP (RADIUS allows the server to send configuration details to the device asking for authentication, which lets you provide different services to different users).

For PAM mode, ensure that you have PAM set up for LDAP like the other systems. The PAM configuration file for FreeRADIUS is /etc/pam.d/radiusd. Starting from the default configuration files that come with FreeRADIUS, uncomment the pam keyword in the authenticate section of radiusd.conf. Next, edit the users file and look for DEFAULT Auth-Type = System . Change the System keyword to PAM . Restart radiusd , and you're done.

The native LDAP module, rlm_ldap , is more complex. First, you must have FreeRADIUS installed on your system, built with the rlm_ldap module ( --enable-ldap ). FreeRADIUS is built like most other packages and so won't be covered here. Your Linux distribution, if it includes FreeRADIUS, likely includes the LDAP module.

FreeRADIUS includes an LDAP schema in a file called openldap.schema. Copy this to /etc/openldap/schema/freeradius.schema, and import it into OpenLDAP through the include directive in slapd.conf. The schema provides several attributes and two objectClasses. One of the objectClasses is radiusprofile ; it's used for any users who will be authenticated with RADIUS. radiusprofile is an auxiliary objectClass and therefore can go on any entry. radiusObjectProfile is a structural objectClass used to create containers of radius profiles; it isn't necessary for operation.

Next, edit the default users file as in the PAM example, but instead of changing the default method to PAM, comment out that entire section. This file controls how users are authenticated and authorized. Removing the default method is enough to allow the LDAP module to take over and handle user authentication and authorization.

radiusd.conf needs more work. In both the authenticate and authorize sections, uncomment the ldap keyword that enables LDAP authentication and authorization. You must also find a section that looks like Auth-Type LDAP { ldap } and uncomment that. Finally, uncomment the ldap { ... } section, and enter your server's address, base DN, and optional authentication information. Like other software you've seen, the initial bind performs the lookup of the user's DN; then, a second bind is made as that user to confirm the password and retrieve the attributes. Therefore, the user you initially bind as (or anonymous if you have no configured user) must be able to perform searches on the uid attribute, and users must be able to read their own attributes.

Users who need to be authenticated by LDAP must use the radiusProfile objectClass and have a dialupAccess attribute with some value in it, such as "yes". With more advanced configurations, you can use the value to apply different settings, but for basic purposes, the attribute can take any value.

FreeRADIUS is an extremely robust RADIUS server, and a great deal of configuration can be required to get it to do what you need. The two configurations shown here focus only on what is needed to get LDAP working.

Integrate CUPS with LDAP

The Common UNIX Printing System (CUPS) is the currently favored printing daemon because of its ease of configuration, support for the Internet Printing Protocol (IPP), and backward compatibility with the traditional lpr tools. CUPS supports PAM, but it must be told how and when to authenticate.

First edit /etc/pam.d/cups so that it supports LDAP. Next, in /etc/cups/cupsd.conf, create for your printers a container that requires authentication, such as in Listing 13.

Listing 13. A printers container that requires authentication
<Location /printers> AuthType Basic </Location>

Listing 13 shows a configuration that requires Basic authentication for any URL beginning with /printers. The CUPS configuration is almost identical to that of Apache, so this configuration should remind you of Listing 11. However, CUPS is using PAM instead of a native LDAP module, so no LDAP configuration is necessary. CUPS uses PAM for authentication because that is how it's configured. Now, when you try to browse a URL under /printers, which includes printing to a printer, you're prompted for a password. Listing 14 shows such a prompt.

Listing 14. Verifying that CUPS is working with LDAP
[sean@bob LPIC-III_5]$ lpr index.xml Password for sean on localhost? mypassword [sean@bob LPIC-III_5]$

If the password were incorrect or PAM wasn't working, then Listing 14 would have reprompted for a password. PAM was successful, though, so the document was printed and the user was returned to the shell prompt.

Integrate LDAP with Samba

This section covers material for topic 305.4 for the Senior Level Linux Professional (LPIC-3) exam 301. This topic has a weight of 1.

在本节中,学习如何:

  • Migrate from smbpasswd to LDAP
  • Understand the OpenLDAP Samba schema
  • Understand LDAP as a Samba password backend

Samba is the UNIX community's way of integrating with Microsoft Windows networks. With this software, you can share files with Microsoft networks (both client and server) and make your UNIX computer appear as a Windows computer to the other Windows clients.

Understand Samba authentication

Samba's goal is integration with Windows networks, so it must use the authentication mechanisms that Windows uses. If you're authenticating against a Windows server, this is fine, but often the Samba server is the repository for the credentials. Thus, two copies of password hashes are needed—one for the traditional UNIX passwords and another for the Microsoft hashes.

Microsoft passwords are similar to UNIX passwords in that they're hashes of the real password. A hash function is a one-way function that accepts a variable-length input (such as a password) and outputs a fixed-length hash (string). It's impossible to take the hash and recover the original password, although you could try billions of different inputs in hopes that the resulting hash will match.

Two different password hashes are stored for Microsoft passwords: the LANManager hash and the Windows NT hash. The first isn't as secure as the second because several things are done to the password before hashing that reduce the number of possible outputs. The Windows NT hash was designed to overcome these limitations. Even though both hashes are stored, you can choose to disable the LANManager support if all your clients support NT hashes (available on Windows NT SP 3 and above).

Samba has traditionally stored the password hashes in the smbpasswd file and uses tools like smbpasswd to manage the password file by the same name. This can easily be moved to LDAP so that multiple Samba servers can authenticate without needing to use Primary Domain Controllers or other Microsoft infrastructure. Storing the data in LDAP also reduces duplication of information across your network.

Understand the Samba schema

NT passwords are different from UNIX passwords and can't be stored in the userPassword attribute. Therefore, the LDAP schema must be extended to store the password hashes and other pieces of information that a Microsoft device expects to be available.

The schema file is distributed with the Samba suite as samba.schema. Copy this file to /etc/openldap/schema, and use the include directive in slapd.conf to make it a part of your server's schema.

samba.schema introduces several new objectClasses, which are explained in Table 4.

Table 4. objectClasses in samba.schema
objectClass 描述
sambaSamAccount Provides the information needed for an account (computer, user, and so on) in an NT environment.
sambaGroupMapping Maps a UNIX group to a Windows group.
sambaTrustPassword Provides authentication information about trust relationships between domains.
sambaDomain Stores information about the domain in the LDAP tree. You'll find one of these added automatically to your LDAP tree after you set up Samba/LDAP.

Configure Samba for LDAP

Configuring Samba for LDAP involves editing smb.conf to set up the LDAP data source and then manipulating your users' LDAP entries to make them aware of the new Samba attributes.

In your smb.conf, you'll find a line like passdb backend = tdbsam , which represents the smbpasswd file storage mechanism. Replace this with the code in Listing 15, modified for your environment.

Listing 15. Using the ldapsam password storage
# ldapsam requires the uri to the LDAP server passdb backend = ldapsam:ldap://192.168.1.138/ # A user in your LDAP server that can read and write the new attributes # The password will be entered later ldap admin dn = cn=root,dc=ertw,dc=com # Same as search base ldap suffix = dc=ertw,dc=com # OUs for users/computers/groups ldap user suffix = ou=People ldap machine suffix = ou=Computers ldap group suffix = ou=Group

Once you've set up smb.conf, restart Samba and execute smbpasswd -W . You're prompted for the password for the LDAP admin DN you entered in smb.conf. At this point, Samba will use LDAP data to authenticate users.

Manage Samba users in LDAP

Users must be set up with the sambaSamAccount objectClass before they can use Samba, which includes setting the password hashes and assigning a security identifier (SID) to the user. This is easily handled by the smbpasswd utility, which traditionally added users to the smbpasswd file. smbpasswd will manage an LDAP user if smb.conf is configured to use LDAP, such as in Listing 15.

To set up a new user, first be sure the user's account is set up with the posixAccount objectClass and a uid attribute, which should already be there if the user logs in through LDAP and PAM or NSS. Next, run smbpasswd -a username to modify the user's LDAP entry, which includes setting the Samba password. Listing 16 shows a typical user's entry after being set up for Samba.

Listing 16. A Samba user's entry
dn: cn=Jim Joe,ou=people,dc=ertw,dc=com givenName: Jim sn: Joe cn: Jim Joe uid: jjoe uidNumber: 1000 sambaSID: S-1-5-21-2287037134-1443008385-640796334- userPassword:: e01ENX1yTDBZMjB6QytGenQ3MlZQek1TazJBPT0= sambaLMPassword: 5BFAFBEBFB6A0942AAD3B435B51404EEsambaNTPassword: AC8E657F83DF82BEEA5D43BDAF7800CC loginShell: /bin/bash gidNumber: 4 homeDirectory: /home/a sambaAcctFlags: [U] objectClass: inetOrgPerson objectClass: sambaSamAccount objectClass: posixAccount objectClass: top

The bold lines from Listing 16 were added by smbpasswd . Starting from the top, a SID is added to the account. Using smbpasswd frees you from needing to calculate this, because smbpasswd figures out what SID to use. Next, the LanManager and NT password hashes are stored. The sambaAcctFlags is used to store some attributes of the entry. Possible values of this flag are as follows:

  • N : No password required
  • D : Account disabled
  • H : Home directory required
  • T : Temporary duplicate of other account
  • U : Regular user account
  • M : MNS (Majority Node Set cluster) logon user account
  • W : Workstation Trust Account
  • S : Server Trust Account
  • L : Automatic locking
  • X : Password doesn't expire
  • I : Domain Trust Account

Finally, the sambaSamAccount objectClass enables all these attributes.

In addition to those described here, you can set many other options to carry more Windows-specific information. Consult the pdbedit manpage to learn about reading and modifying Samba user information from the command line. Samba can act as a Windows Primary Domain Controller (PDC), and the extra information is necessary for Windows clients to function correctly.

Password synchronization

Now that two sets of passwords exist ( userPassword and the two Samba hashes), you must find a way to keep the passwords in sync with each other. If a user changes his or her Samba password, either from the command line or from a Windows client, the UNIX password should change. Likewise, if a user changes the UNIX password, the Samba password should change.

The first case is the easiest. Add ldap password sync = yes to the [global] section of smb.conf, and restart Samba. Any further password changes will change both the Samba and userPassword hashes.

Getting the Samba passwords changed when a user changes his or her password through the UNIX passwd command requires PAM. Samba comes with mod_smbpasswd , which is used to authenticate and change passwords through the Samba system. For now, there is no need to authenticate passwords, so only the password function will be used. Listing 17 shows part of a PAM configuration file that, when used, changes both UNIX and Samba passwords in LDAP.

Listing 17. A PAM password stack to change both UNIX and Samba passwords
password requisite pam_cracklib.so try_first_pass retry=3 password optional pam_smbpass.so use_authtok use_first_pass password sufficient pam_unix.so md5 shadow nullok try_first_pass use_authtok password sufficient pam_ldap.so use_authtok password required pam_deny.so

In Listing 17, the added line is shown in bold. The pam_smbpass module is listed as optional so that if a user isn't configured as a Samba user, that step will fall through. The Samba password change is before the UNIX and LDAP password changes, because these two are marked as sufficient , meaning the first one to succeed stops processing.

With Listing 17 in place, a user changing his or her password from the command line will also change the Samba password.

Migrate existing users to LDAP

When you move to an LDAP backend, you're likely to have existing users in a file-based password mechanism that you need to migrate. The pdbedit utility can copy accounts from one place to another to make this job easy.

Listing 18 shows the use of pdbedit to migrate users. The -i parameter sets the source of the data, and the -e parameter sets the destination. Before running the pdbedit command, you should have the ldapsam database set up in smb.conf.

Listing 18. Migrating users from tdbsam to ldapsam
[root@server1 ~]# pdbedit -e ldapsam -i tdbsam Importing account for fred...ok Importing account for jsmith...ok

If you're using the older smbpasswd password backend, use smbpasswd instead of tdbsam .

This section covers material for topic 305.5 for the Senior Level Linux Professional (LPIC-3) exam 301. This topic has a weight of 2.

在本节中,了解以下内容:

  • Kerberos integration with LDAP
  • Cross-platform authentication
  • Single sign-on concepts
  • Integration and compatibility limitations between OpenLDAP and Active Directory

Microsoft Windows can be found in almost every company; there's a good chance that your environment already makes use of Active Directory, Microsoft's enterprise directory service. Active Directory is based on two open protocols: LDAP and Kerberos. By understanding these protocols and configuring the Linux system appropriately, your Linux box can authenticate against the enterprise directory and facilitate single sign on (SSO). This means you log in to your machine once, and your credentials are good throughout the network.

Understand Kerberos

Kerberos, named after the three-headed dog from Hades in Greek mythology, is a protocol that allows users and servers to prove their identity to each other over an untrusted network. It was developed at the Massachusetts Institute of Technology (MIT) for use on their network and has since found its place in many other networks. Microsoft chose to use Kerberos as part of Windows 2000's Active Directory.

Kerberos V is the currently developed stream, although you may run into Kerberos IV at times. Kerberos V provides backward compatibility for systems still using Kerberos IV.

The Kerberos protocol

Kerberos is a protocol that allows a service to authenticate the identity of a user without needing to see a password. This is achieved by having a mutually trusted server, called the Authentication Service (AS). The AS shares a secret with each user and service. The secret is used to protect information between the AS and the other end of the conversation; it even lets the AS give the user a message (called a ticket ) destined for someone else. In this latter case, users can't read the ticket because they don't have the shared secret.

All clients and servers form a Kerberos realm , which is much like an NIS domain or, in some respects, the base DN of an LDAP tree. The realm defines all the devices and people that authenticate to a common set of Kerberos servers. Generally, the realm is the DNS zone of the organization written in uppercase, such as ERTW.COM. For the purposes of Kerberos, the clients are the computers that get tickets from a Kerberos server. The servers are the devices that provide the Kerberos services of granting tickets.

Everything that is authenticated in the Kerberos realm has a corresponding Kerberos principal that identifies it and is associated with the password or shared secret. When a user connects to a server, they're really connecting to a service running on the server. Each service is treated separately and must be registered as a principal with the Kerberos server. A service's principal is of the form servicename/servername@REALM , whereas a user's principal is of the form user@REALM .

The Kerberos protocol is shown in Figure 1.

Figure 1. The Kerberos protocol
The Kerberos protocol

The Kerberos protocol can be viewed as having two distinct phases: the initial login of the user to the realm, and the authenticating of the user to the service. The magic of Kerberos is that the initial login happens only once; the subsequent service authentication can happen many times to many servers.

The first phase of Kerberos starts with the user asking the Kerberos server (specifically, a component called the Key Distribution Center [KDC]) for a Ticket Granting Ticket (TGT), which will be used later to request service. The KDC generates a TGT, encrypts it with the user's password, and sends it back to the user.

The TGT has been likened to a visitor pass in a company. You show your identification to the security guard (KDC) and are granted a visitor pass that's valid for one day. This process allows you to keep your own ID secure and also limits the company's exposure to a stolen visitor pass. The TGT expires in a short period of time, usually around 8 hours.

In the second phase, the user decides he or she needs access to a service. The user sends a request to the Kerberos server's Ticket Granting Service (TGS) component, which includes the TGT and the name of the service (the principal). The TGS checks to see if the TGT is still valid and then issues a ticket that has been encrypted with the shared secret of the service . Finally, the user presents this ticket to the service. If the service can successfully decrypt the ticket, then the service knows the Kerberos system approved the request. No passwords ever crossed the network.

Kerberos thwarts replay attacks, where an attacker captures a ticket and uses it again, by imposing limited lifetimes on tickets and including timestamps in the encrypted ticket. A ticket for a service may be valid for 5 minutes, so the service has to remember just 5 minutes' worth of tickets to know if a ticket was replayed. All clocks must be synchronized for this to succeed.

Where does LDAP fit in?

Kerberos provides only an authentication framework, much like the PAM system does. User information isn't stored in the Kerberos database.

Kerberos secrets can be stored in the LDAP database or they can be left separate. The choice is up to the implementation of Kerberos. In either case, LDAP is used to store the user information such as home directory and personal information.

You must keep your Kerberos database secure regardless of where it's stored. The Kerberos keys are like passwords: they can be stolen and used to generate TGTs and tickets. Most guides strongly recommend keeping your Kerberos server on its own device and protecting it as much as possible.

Configure Microsoft Active Directory for your Linux guests

Active Directory uses implementations of Kerberos and LDAP that are compatible with those shipped with Linux. Microsoft has extended Kerberos to support Windows-specific attributes, but this doesn't prevent UNIX users from using it (see the Related topics for Microsoft's documentation on the subject).

The Active Directory schema must be extended to support some of the UNIX attributes, which is easily done in Windows 2003 Server. Go to the Control Panel of your Domain Controller, and choose Add or Remove Programs > Add/Remove Windows Components . From the Active Directory Services component, choose the Identity Management for UNIX subcomponent. (If you have an earlier version of Windows, this component is sometimes called the Server for NIS.) Install this software, and the LDAP schema will be extended; your user dialogs will also include a UNIX Attributes tab, which will be used soon.

From the Active Directory Users and Computers application, edit the Domain Users security group. Note the new tab, UNIX Attributes . Assign a group and NIS domain to your Domain Users group, as shown in Figure 2. Doing so allows the group to be seen by the UNIX systems. This group will be the user's primary group.

Figure 2. Assigning UNIX attributes to a group
Assigning UNIX attributes to a group

Still in the Users container, find a user whom you want to use on your UNIX servers. Find the UNIX Attributes tab for this user, and assign the standard UNIX attributes to them. Figure 3 shows a sample user.

Figure 3. The UNIX attributes of a user
The UNIX attributes of a user

The user in Figure 3 has been assigned a primary group, a home directory, a shell, and a userid.

Next, you must create a service account that allows access to your LDAP tree, because anonymous access is disabled by default. Use the following configuration for this user:

  • Name : LDAP service account (or your choice)
  • User logon name : ldap (or your choice)
  • Password : Your choice
  • User can't change password : Selected
  • Password never expires : Selected
  • Primary group : Domain Guests

The service account should only be a member of Domain Guests. From the Member Of tab, add the Domain Guests group to the account, highlight it in the list of groups, then click the Set Primary Group button. With the group changed, you can remove the Domain Users group from the profile.

If your security policy prohibits the password options, you'll have to adjust your Linux configuration (described next) each time the password changes. Note that LDAP is used here only for directory information and not passwords, so the requirement to change passwords is lessened.

Configure Linux

The Linux side of the equation involves three steps. First, you set up directory access through /etc/ldap.conf. Next, you configure PAM for Kerberos authentication. Finally, configure Samba to use Active Directory information for authentication, and join it to the domain.

Before you start, you must ensure that your Linux machine is using your Microsoft server for both DNS and network time. Your Linux server must also have a host record in the Microsoft DNS zone for your domain.

Configure LDAP

LDAP is configured as it was earlier , except that some mapping is required from UNIX attributes to Microsoft attributes. Listing 19 shows /etc/ldap.conf configured to access a Microsoft LDAP directory using the user account set up previously.

Listing 19. Configuring ldap.conf to use a Microsoft directory
# Information about the directory uri ldap://192.168.1.151 binddn ldap@ertw.com bindpw ldap ssl no base dc=ertw,dc=com # Map attributes nss_map_objectclass posixAccount user nss_map_objectclass shadowAccount user nss_map_attribute uid sAMAccountName nss_map_attribute homeDirectory unixHomeDirectory nss_map_attribute shadowLastChange pwdLastSet nss_map_objectclass posixGroup group nss_map_attribute uniqueMember member pam_login_attribute sAMAccountName pam_filter objectclass=User pam_password ad

The configuration shown in Listing 19 first points the module to the Microsoft LDAP server using the credentials set up earlier. The attributes are mapped from the UNIX name to the Microsoft name, such as using sAMAccountName for the userid.

Finally, add ldap winbind to the passwd , group , and shadow sections of /etc/nsswitchconf (leave files in there). This lets your system pull directory information from LDAP and Samba (the latter to be configured later).

After this step, you can run getent passwd to see the LDAP users. Note that you must set the UNIX attributes for the user in Active Directory for the user to show up in the list.

Configure Kerberos

Kerberos is configured through PAM and the /etc/krb5.conf file. If you're using your Microsoft DNS server for your DNS, then you only need to specify your realm, because the server will be learned automatically from DNS. Listing 20 shows the contents of /etc/krb5.conf

Listing 20. /etc/krb5.conf for the ERTW.COM realm
[logging] default = FILE:/var/log/krb5libs.log kdc = FILE:/var/log/krb5kdc.log admin_server = FILE:/var/log/kadmind.log [libdefaults] default_realm = ERTW.COM dns_lookup_realm = false dns_lookup_kdc = true ticket_lifetime = 24h forwardable = yes [realms] ERTW.COM = { default_domain = ertw.com } [domain_realm] .ertw.com = ERTW.COM ertw.com = ERTW.COM [appdefaults] pam = { debug = false ticket_lifetime = 36000 renew_lifetime = 36000 forwardable = true krb4_convert = false }

krb5.conf is divided into sections, with the name of the section enclosed in square brackets. The logging section specifies the paths of various logfiles. The libdefaults sections configure the Kerberos libraries: in particular, the dns_lookup_kdc tells the library to look for server records (SRV) in DNS to find the KDC. The record looks like _kerberos._tcp.ERTWCOM. , and the response is the name of a server and the port to contact.

The realms section defines the realms and the associated DNS zones. The domain_realm section does the reverse: it allows a host to determine its realm based on its fully qualified domain name (FQDN). Finally, the appdefaults section is for the applications using Kerberos; in this case, PAM has been configured with some default options.

In practice, there is little to configure in krb5.conf because the default configuration file has all the required elements. All you have to do is substitute your realm and domain name where appropriate. You can also use your system's Kerberos configuration utility, such as authconfig .

The configuration of PAM is just like the previous configurations of LDAP and smbpasswd. You insert a call to the Kerberos PAM library where appropriate. Listing 21 shows part of the Fedora system-auth file after Kerberos has been configured.

Listing 21. system-auth file after configuring Kerberos
auth sufficient pam_unix.so nullok try_first_pass auth sufficient pam_krb5.so use_first_pass auth required pam_deny.so account required pam_unixso broken_shadow account [default=bad success=ok user_unknown=ignore] pam_krb5.so account required pam_permit.so password sufficient pam_unix.so md5 shadow nullok try_first_pass use_authtok password sufficient pam_krb5.so use_authtok password required pam_deny.so session required pam_unix.so session optional pam_krb5.so

Kerberos has been added directly after the UNIX password check in the authorization phase as a sufficient item. This means that if a UNIX password is found, Kerberos isn't consulted. If no UNIX password is found, then Kerberos is consulted. If Kerberos fails, the stack fails. If no user is found, then control passes to the pam_deny module, which causes a failure.

The account phase uses an alternative syntax to the one you've seen so far. Each PAM module can return different options, such as "success" or "no such user". The square brackets allow the administrator to take a different action based on each possible return code. Listing 21 implements a policy that says if pam_krb5 returns a successful result, then continue processing. If the user is unknown, then ignore the module completely. Anything else is considered a failure. This behavior is close to the required keyword, with the exception that an unknown user doesn't cause a failure. Consult the pam.conf(5) manpage for more details on this syntax, including the options.

The password and session phases include the module in the stack with no special options.

At this point, you should be able to log in to your Linux server using Active Directory credentials. The next step configures Samba and further secures the connection by creating a computer account for the server.

Configure Samba and join the domain

For Samba's configuration, you must first remove your existing password backend from smb.conf, and any of the tdb files in /etc/samba and /var/cache/samba. Listing 22 shows the directives you must add to the [global] section of smb.conf to allow Samba to use AD.

Listing 22. Samba configuration for AD integration
# Active directory security security = ads realm = ERTW.COM use kerberos keytab = yes # Identity mapping idmap backend = ad ldap idmap suffix = dc=ertw,dc=com # LDAP configuration ldap admindn = cn=ldap,cn=users,dc=ertw,dc=com ldap suffix = dc=ertw,dc=com # Winbind winbind use default domain = yes winbind nested groups = yes

Listing 22 starts by specifying that ADS security mode is used (remote Active Directory server), along with the Kerberos realm. The second section configures idmapping, which is a feature that maps remote Microsoft SIDs to local UNIX ids. This configuration specifies that Active Directory is the source of the information. The mapping is taken care of on the Microsoft side, because you've already entered the IDs in the UNIX Attributes tab of the users and groups. Your server just has to pull this information from LDAP.

The LDAP configuration is familiar; it sets the DN for the LDAP connection to the ldap user created earlier. Note that the container is cn=users instead of the ou=people that has been used so far. The password is entered through smbpasswd .

The last two lines enable Winbind, which is an implementation of some of the Microsoft Remote Procedure Calls (see Related topics for more information on Winbind). It lets you get more information out of your Active Directory server, rather than only the groups and users for which you've added UNIX attributes.

After smb.conf is configured, start the Samba and winbind services.

The final steps in the Samba configuration are to set the admindn password and to join your domain. Listing 23 shows the computer joining the domain.

Listing 23. Setting the admindn password and joining the domain
[root@server1 ~]# smbpasswd -W Setting stored password for "cn=ldap,cn=users,dc=ertw,dc=com" in secrets.tdb New SMB password: ldap Retype new SMB password: ldap [root@server1 ~]# net ads join -U administrator administrator's password: mypassword Using short domain name -- ERTW0 Joined 'SERVER1' to realm 'ERTW.COM'
Test it out

You should be able to log in to your server with Active Directory credentials and browse file shares from a remote computer without having to log in. Some helpful commands to test are:

  • net ads testjoin : Tests the computer account
  • wbinfo -u : Shows a list of Active Directory users and tests winbind
  • klist : After you log in through Kerberos, shows your TGT and any service tickets that have been issued
  • smbclient -k -L '\\SERVERNAME' : Shows a list of shares from SERVERNAME, using a Kerberos login

Integrate LDAP with e-mail services

This section covers material for topic 305.6 for the Senior Level Linux Professional (LPIC-3) exam 301. This topic has a weight of 1.

在本节中,学习如何:

  • Plan LDAP schema structure for e-mail services
  • Create e-mail attributes in LDAP
  • Integrate Postfix with LDAP
  • Integrate sendmail with LDAP

sendmail and Postfix are two of the more popular mail transport agents (MTAs) in use. The job of the MTA is to receive messages from the systems and send them to be delivered to the end user or to the next hop MTA. MTAs also take messages from users and find the remote MTA that is capable of delivering the message.

Both sendmail and Postfix rely on various maps—key/value pairs that are normally held in flat files or hash databases like BDB. This type of lookup is also a good fit for LDAP. The advantages of LDAP are that many hosts can share the same configuration, and that it's easier to develop tools to manage the data in LDAP rather than in flat files that must then be rebuilt into hash tables. The overhead of LDAP versus disk reads should not be that onerous, especially if the LDAP tree is properly indexed.

Configure sendmail

The sendmail MTA is a complex creature, and adding LDAP to the mix only increases the complexity. You can do just about anything with sendmail because it's almost infinitely configurable. The downside is that things that should be simple tend to be more complicated than necessary.

Understand that sendmail is a program that interprets a language often called cf in order to process mail. Cf is a language made for easy parsing by sendmail, not humans. Fortunately, humans can use a language called M4, which has a much simpler syntax, to generate the resulting cf code.

sendmail maps

Many cf operations involve looking up information in maps , which are series of key-value pairs. Each map has a particular purpose, such as the aliases map for mail aliases and the mailertable map for static routing of e-mail. The map is a two-column entity; lookups are performed on the left-hand side (LHS), and the corresponding value from the right-hand side (RHS) is returned.

The concept of a map doesn't translate directly into LDAP. A single-key lookup in a sendmail map may return only one RHS entry (the RHS can have multiple values, but only one instance of the key may exist). sendmail works with this by defining a schema that allows key-value pairs to be stored in LDAP. Furthermore, sendmail translates each map request into an LDAP query filter that is designed to return a set of attributes from a single entry. You can choose to use the sendmail schema, or you can modify the filters to work with the data in your tree.

To get started, add the misc.schema schema (it comes with OpenLDAP) to your server's schema. This implements LDAP-based mail routing. Then, add sendmail.schema from the sendmail distribution, which lets you store maps in LDAP.

Configure LDAP mail routing

Some organizations have multiple mail servers to handle all their users, either because of geographical constraints or for managing capacity on the servers. In this case, a user's mailbox might be on a server called wpgertw.com but the user's e-mail address might be sean@ertw.com. LDAP mail routing allows any sendmail server to receive the message, perform an LDAP lookup, and rewrite the address to the internal version. It's then a simple matter to change the destination server by changing LDAP. In any case, the user's e-mail address stays the same.

The misc.schema implements an Internet draft for LDAP routing. This schema provides the inetLocalMailRecipient objectClass with the following attributes:

  • mailLocalAddress : An attribute that defines someone's e-mail address as it's seen by someone outside the organization
  • mailRoutingAddress : An attribute that defines the internal address of a user, which usually includes the server that holds the user's mailbox
  • mailHost : An attribute that defines the server that handles this user's e-mail

The host information for the user can be held in either mailRoutingAddress or mailHost . For example, a mailRoutingAddress of sean@wpg.ertw.com with a mailHost of mx.ertw.com seems like a contradiction. If the host is set, the mail will be delivered there regardless of the routing address. The address will still be rewritten to the routing address if that attribute exists. In the example of sean@wpg.ertw.com, the address in the envelope will be rewritten to sean@wpg.ertw.com, but the message will be delivered to mx.ertw.com.

Listing 24 shows the M4 code that enables LDAP routing. This should go in /etc/mail/sendmail.mc; then, you must rebuild your sendmail.cf. Usually this means going into /etc/mail/ and running make ; or it may mean running m4 sendmail.mc > sendmail.cf .

Listing 24. Enabling LDAP routing in sendmail.mc
define(`confLDAP_DEFAULT_SPEC', `-h localhost -b dc=ertw,dc=com') FEATURE(`ldap_routing') LDAPROUTE_DOMAIN(`ertw.com')

The first line sets the default arguments for the internal LDAP client: the host and the search base. The second line enables the LDAP routing feature, and the third enables the ertw.com domain for LDAP routing.

The duplication of the mailLocalAddress attribute from inetLocalMailRecipient and the mail attribute from inetOrgPerson is worth looking at. sendmail lets you override the searches it uses internally by passing extra arguments to the ldap_routing feature. The first argument is the filter used to find the mailHost attribute, and the second is used to find mailRoutingAddress . Therefore, FEATURE(`ldap_routing', `ldap -1 -T<TMPF> -v mailHost -k (&(objectClass=inetLocalMailRecipient)(mail=%0))', `ldap -1 -T<TMPF> -v mailRoutingAddress -k (&(objectClass=inetLocalMailRecipient)(mail=%0))') enables sendmail to use the mail attribute instead of mailLocalAddress . The search filter is specified with the -k switch, and the attribute to return with -v . The rest of the arguments are standard for sendmail.

Configure aliases

sendmail implements LDAP aliases as a series of entries in the LDAP tree, keyed on an attribute called sendmailMTAKey using an objectClass of sendmailMTAAliasObject . You may wish to keep the aliases in their own container. Listing 25 shows the LDIF for a sendmail alias that takes mail for exec@ertw.com and sends it to hair@ertwcom and teeth@ertw.com.

Listing 25. Alias for exec@ertw.com
dn: sendmailMTAKey=execs,ou=aliases,dc=ertw,dc=com objectClass: sendmailMTAAliasObject sendmailMTACluster: external sendmailMTAAliasGrouping: aliases sendmailMTAKey: execs sendmailMTAAliasValue: hair@ertwcom sendmailMTAAliasValue: teeth@ertw.com

The first attribute, sendmailMTACluster , defines the servers that can use this alias. You must also define the cluster name in the sendmail.mc file, such as define(`confLDAP_CLUSTER', `external') . This cluster is used as part of the search filter, so if you forget to define it, your aliases will never be used. The alternative to defining a cluster is to set sendmailMTAHost , which makes the entry apply only to a particular host.

sendmailMTAAliasGrouping must be aliases ; this is part of the search filter. The key refers to the name of the alias; finally, you have one or more values that are the targets.

The final step is to configure sendmail to use LDAP for the aliases file with the define(`ALIAS_FILE', `ldap:') M4 directive. In general, anywhere you're asked for a file in sendmail.mc, you can put ldap: , and the map will be referenced in LDAP. The sendmailMTAAliasGrouping then becomes the name of the map.

Configure Postfix

Postfix is designed to be simpler than sendmail but to remain compatible with sendmail. The concept of maps is still around, but instead of fitting the maps into a schema, you must define your own query filters that use your own attributes.

For most maps, you specify the target as ldap:/path/to/config.cf , with config.cf being a configuration file that defines the LDAP server, the query, and the attributes that form the response. For example, the local_recipient_maps directive specifies how Postfix will map e-mail addresses to local accounts. Specify local_recipient_maps = $aliases, ldap:/etc/postfix/localrecipients.cf to first check the aliases database (to come later) and then the regular address attached to a user's entry. Listing 26 shows the contents of localrecipients.cf.

Listing 26. The local recipients LDAP lookup
# LDAP server info server_host = ldap://localhost search_base = ou=people,dc=ertw,dc=com # %s is the e-mail address... query_filter = mail=%s # the uid tells the account that gets the delivery result_attribute = uid

Listing 26 specifies the local LDAP server and the People OU. Postfix consults the search filter and replaces the %s with the e-mail address. Thus, an e-mail for fred@ertw.com will result in a search for (mail=fred@ertw.com) in the People OU. The uid attribute is used to determine the mailbox. To test, you can run postmap -q fred@ertw.com ldap:/etc/postfix/localrecipients.cf , which runs the given e-mail address through the localrecipients.cf configuration file (note that NSS must be configured to return details about the fred account).

摘要

In this tutorial, you learned how to integrate LDAP with your current systems. NSS provides an easy way for core UNIX tools to make use of LDAP by redirecting the standard C library calls to the backend of your choice. PAM is yet another abstraction; it allows you to change the way applications authenticate in a granular fashion as long as the application is PAM aware. PAM also has hooks for account restrictions and password changes. The PAM files live in /etc/pam.d.

Migrating from NIS to LDAP involves planning which databases need to be moved and then running some utilities to extract the data and convert it to LDIF. If you still must support NIS in your environment, PADL has written a NIS server called ypldapd that translates between NIS and LDAP by presenting a NIS interface to applications, and that reads the data from LDAP.

Many applications are PAM aware, which means your migration to LDAP is as simple as changing a few files in /etc/pam.d. Some applications, like Apache, speak LDAP directly. Configuring Apache for LDAP involves using the mod_authnz_ldap module and specifying search filters that help Apache find the users in the tree.

Samba provides Windows services on a UNIX platform. You can configure Samba to use LDAP data or even to use Kerberos data to talk directly to Windows. In the latter case, LDAP is still used for directory information, and Kerberos is used for authentication.

E-mail is a natural fit for LDAP because of its similarity to a phone book. Both sendmail and Postfix allow maps to be served from LDAP.

This concludes the look at directory services for the LPIC 3 exam. The next and final tutorial in the series will focus on monitoring and predicting the performance of your Linux servers.


翻译自: https://www.ibm.com/developerworks/linux/tutorials/l-lpic3305/index.html

数据迁移:索引重建

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值