27.4 网络信息服务 (NIS/YP)

Written by Bill Swingle. Enhanced by Eric Ogren 和 Udo Erdelhoff.

27.4.1 它是什么?

  NIS, 表示网络信息服务 (Network Information Services), 最初由 Sun Microsystems 开发, 用于 UNIX® (最初是 SunOS™) 系统的集中管理。 目前, 它基本上已经成为了业界标准; 所有主流的类 UNIX 系统 (Solaris™, HP-UX, AIX®, Linux, NetBSD, OpenBSD, FreeBSD, 等等) 都支持 NIS

  NIS 也就是人们所熟知的黄页(Yellow Pages), 但由于商标的问题, Sun 将其改名为现在的名字。 旧的术语 (以及 yp), 仍然经常可以看到, 并被广泛使用。

  这是一个基于 RPC 的客户机/服务器系统, 它允许在一个 NIS 域中的一组机器共享一系列配置文件。 这样, 系统管理员就可以配置只包含最基本配置数据的 NIS 客户机系统, 并在单点上增加、 删除或修改配置数据。

  尽管实现的内部细节截然不同, 这和 Windows NT® 域系统非常类似, 以至于可以将两者的基本功能相互类比。

27.4.2 您应该知道的术语和进程

  有一系列术语和重要的用户进程将在您在 FreeBSD 上实现 NIS 时用到, 无论是在创建 NIS 服务器, 或作为 NIS 客户机:

术语 说明
NIS 域名 NIS 主服务器和所有其客户机 (包括从服务器) 会使用同一 NIS 域名。 和 Windows NT 域名类似, NIS 域名与 DNS 无关。
rpcbind 必须运行这个程序, 才能够启用 RPC (远程过程调用, NIS 用到的一种网络协议)。 如果没有运行 rpcbind, 则没有办法运行 NIS 服务器, 或作为 NIS 客户机。
ypbind “绑定(bind)” NIS 客户机到它的 NIS 服务器上。 这样, 它将从系统中获取 NIS 域名, 并使用 RPC 连接到服务器上。 ypbind 是 NIS 环境中, 客户机-服务器通讯的核心; 如果客户机上的 ypbind 死掉的话, 它将无法访问 NIS 服务器。
ypserv 只应在 NIS 服务器上运行它; 这是 NIS 的服务器进程。 如果 ypserv(8) 死掉的话, 则服务器将不再具有响应 NIS 请求的能力 (此时, 如果有从服务器的话, 则会接管操作)。 有一些 NIS 的实现 (但不是 FreeBSD 的这个) 的客户机上, 如果之前用过一个服务器, 而那台服务器死掉的话, 并不尝试重新连接到另一个服务器。 通常, 发生这种情况时, 唯一的办法就是重新启动服务器进程 (或者, 甚至重新启动服务器) 或客户机上的 ypbind 进程。
rpc.yppasswdd 另一个只应在 NIS 主服务器上运行的进程; 这是一个服务程序, 其作用是允许 NIS 客户机改变它们的 NIS 口令。 如果没有运行这个服务, 用户将必须登录到 NIS 主服务器上, 并在那里修改口令。

27.4.3 它是如何工作的?

  在 NIS 环境中, 有三种类型的主机: 主服务器, 从服务器, 以及客户机。 服务器的作用是充当主机配置信息的中央数据库。 主服务器上保存着这些信息的权威副本, 而从服务器则是保存这些信息的冗余副本。 客户机依赖于服务器向它们提供这些信息。

  许多文件的信息可以通过这种方式来共享。 通常情况下, master.passwdgroup, 以及 hosts 是通过 NIS 分发的。 无论什么时候, 如果客户机上的某个进程请求这些本应在本地的文件中的资料的时候, 它都会向所绑定的 NIS 服务器发出请求, 而不使用本地的版本。

27.4.3.1 机器类型

  • 一台 NIS 主服务器。 这台服务器, 和 Windows NT 域控制器类似, 会维护所有 NIS 客户机所使用的文件。 passwdgroup, 以及许多其他 NIS 客户机所使用的文件, 都被存放到主服务器上。

    注意: 可以将一台 NIS 主服务器用在多个 NIS 域中。 然而, 本书不打算对这种配置进行介绍, 因为这种配置, 通常只出现在小规模的 NIS 环境中。

  • NIS 从服务器。 这一概念, 与 Windows NT 的备份域控制器类似。 NIS 从服务器, 用于维护 NIS 主服务器的数据文件副本。 NIS 从服务器提供了一种冗余, 这在许多重要的环境中是必需的。 此外, 它也帮助减轻了主服务器的负荷: NIS 客户机总是挂接到最先响应它们的 NIS 服务器上, 而这也包括来自从服务器的响应。

  • NIS 客户机。 NIS 客户机, 和多数 Windows NT 工作站类似, 通过 NIS 服务器 (或对于 Windows NT 工作站, 则是 Windows NT 域控制器) 来完成登录时的身份验证过程。

27.4.4 使用 NIS/YP

  这一节将通过实例介绍如何配置 NIS 环境。

27.4.4.1 规划

  假定您正在管理大学中的一个小型实验室。 在这个实验室中, 有 15 台 FreeBSD 机器, 目前尚没有集中的管理点; 每一台机器上有自己的 /etc/passwd/etc/master.passwd。 这些文件通过人工干预的方法来保持与其他机器上版本的同步; 目前, 如果您在实验室中增加一个用户, 将不得不在所有 15 台机器上手工执行 adduser 命令。 毋庸置疑, 这一现状必须改变, 因此您决定将整个实验室转为使用 NIS, 并使用两台机器作为服务器。

  因此, 实验室的配置应该是这样的:

机器名 IP 地址 机器的角色
ellington 10.0.0.2 NIS 主服务器
coltrane 10.0.0.3 NIS 从服务器
basie 10.0.0.4 教员工作站
bird 10.0.0.5 客户机
cli[1-11] 10.0.0.[6-17] 其他客户机

  如果您是首次配置 NIS, 仔细思考如何进行规划就十分重要。 无论您的网络的大小如何, 都必须进行几个决策。

27.4.4.1.1 选择 NIS 域名

  这可能不是您过去使用的 “域名(domainname)”。 它的规范的叫法, 应该是 “NIS 域名”。 当客户机广播对此信息的请求时, 它会将 NIS 域的名字作为请求的一部分发出。 这样, 统一网络上的多个服务器, 就能够知道谁应该回应请求。 您可以把 NIS 域名想象成以某种方式相关的一组主机的名字。

  一些机构会选择使用它们的 Internet 域名来作为 NIS 域名。 并不推荐这样做, 因为在调试网络问题时, 这可能会导致不必要的困扰。 NIS 域名应该是在您网络上唯一的, 并且有助于了解它所描述的到底是哪一组机器。 例如对于 Acme 公司的美工部门, 可以考虑使用 “acme-art” 这样的 NIS 域名。 在这个例子中, 您使用的域名是 test-domain

  然而, 某些操作系统 (最著名的是 SunOS) 会使用其 NIS 域名作为 Internet 域名。 如果您的网络上存在包含这类限制的机器, 就 必须 使用 Internet 域名来作为您的 NIS 域名。

27.4.4.1.2 服务器的物理要求

  选择 NIS 服务器时, 需要时刻牢记一些东西。 NIS 的一个不太好的特性就是其客户机对于服务器的依赖程度。 如果客户机无法与其 NIS 域的服务器联系, 则这台机器通常会陷于不可用的状态。 缺少用户和组信息, 会使绝大多数系统进入短暂的冻结状态。 基于这样的考虑, 您需要选择一台不经常重新启动, 或用于开发的机器来承担其责任。 如果您的网络不太忙, 也可以使用运行着其他服务的机器来安放 NIS 服务, 只是需要注意, 一旦 NIS 服务器不可用, 则 所有 的 NIS 客户机都会受到影响。

27.4.4.2 NIS 服务器

  所有的 NIS 信息的正规版本, 都被保存在一台单独的称作 NIS 主服务器的机器上。 用于保存这些信息的数据库, 称为 NIS 映射(map)。 在 FreeBSD 中, 这些映射被保存在 /var/yp/[domainname] 里, 其中 [domainname] 是提供服务的 NIS 域的名字。 一台 NIS 服务器, 可以同时支持多个域, 因此可以建立很多这样的目录, 所支撑一个域对应一个。 每一个域都会有一组独立的映射。

  NIS 主和从服务器, 通过 ypserv 服务程序来处理所有的 NIS 请求。 ypserv 有责任接收来自 NIS 客户机的请求, 翻译请求的域, 并将名字映射为相关的数据库文件的路径, 然后将来自数据库的数据传回客户机。

27.4.4.2.1 配置 NIS 主服务器

  配置主 NIS 服务器相对而言十分的简单, 而其具体步骤则取决于您的需要。 FreeBSD 提供了一步到位的 NIS 支持。 您需要做的全部事情, 只是在 /etc/rc.conf 中加入一些配置, 其他工作会由 FreeBSD 完成。

  1. nisdomainname="test-domain"
    
    这一行将在网络启动 (例如重新启动) 时, 把 NIS 域名配置为 test-domain

  2. nis_server_enable="YES"
    
    这将要求 FreeBSD 在网络子系统启动之后立即启动 NIS 服务进程。

  3. nis_yppasswdd_enable="YES"
    
    这将启用 rpc.yppasswdd 服务程序, 如前面提到的, 它允许用户在客户机上修改自己的 NIS 口令。

注意: 随 NIS 配置的不同, 可能还需要增加其他一些项目。 请参见 关于 NIS 服务器同时充当 NIS 客户机 这一节, 以了解进一步的情况。

  现在, 所需要做的最后的工作是以超级用户身份执行 /etc/netstart 命令。 这将依据 /etc/rc.conf 为您配置好所有的东西。

27.4.4.2.2 初始化 NIS 映射

  NIS 映射 是一些数据库文件, 它们位于 /var/yp 目录中。 这些文件基本上都是根据 NIS 主服务器的 /etc 目录自动生成的, 唯一的例外是: /etc/master.passwd 文件。 一般来说, 您会有非常充分的理由不将 root 以及其他管理帐号的口令发到所有 NIS 域上的服务器上。 因此, 在开始初始化 NIS 映射之前, 我们应该:

# cp /etc/master.passwd /var/yp/master.passwd
# cd /var/yp
# vi master.passwd

  这里, 删除掉和系统有关的帐号对应的项 (binttykmemgames, 等等), 以及其他不希望被扩散到 NIS 客户机的帐号 (例如 root 和任何其他 UID 0 (超级用户) 的帐号)。

注意: 确认 /var/yp/master.passwd 这个文件是同组用户, 以及其他用户不可读的 (模式 600)! 如果需要的话, 用 chmod 命令来改它。

  完成这些工作之后, 就可以初始化 NIS 映射了! FreeBSD 提供了一个名为 ypinit 的脚本来帮助您完成这项工作 (详细信息, 请见其联机手册)。 请注意, 这个脚本在绝大多数 UNIX 操作系统上都可以找到, 但并不是所有操作系统的都提供。 在 Digital UNIX/Compaq Tru64 UNIX 上它的名字是 ypsetup。 由于我们正在生成的是 NIS 主服务器的映射, 因此应该使用 ypinit-m 参数。 如果已经完成了上述步骤, 要生成 NIS 映射, 只需执行:

ellington# ypinit -m test-domain
Server Type: MASTER Domain: test-domain
Creating an YP server will require that you answer a few questions.
Questions will all be asked at the beginning of the procedure.
Do you want this procedure to quit on non-fatal errors? [y/n: n] n
Ok, please remember to go back and redo manually whatever fails.
If you don't, something might not work.
At this point, we have to construct a list of this domains YP servers.
rod.darktech.org is already known as master server.
Please continue to add any slave servers, one per line. When you are
done with the list, type a <control D>.
master server   :  ellington
next host to add:  coltrane
next host to add:  ^D
The current list of NIS servers looks like this:
ellington
coltrane
Is this correct?  [y/n: y] y

[..output from map generation..]

NIS Map update completed.
ellington has been setup as an YP master server without any errors.

  ypinit 应该会根据 /var/yp/Makefile.dist 来创建 /var/yp/Makefile 文件。 创建完之后, 这个文件会假定您正在操作只有 FreeBSD 机器的单服务器 NIS 环境。 由于 test-domain 还有一个从服务器, 您必须编辑 /var/yp/Makefile

ellington# vi /var/yp/Makefile

  应该能够看到这样一行, 其内容是

NOPUSH = "True"

  (如果还没有注释掉的话)。

27.4.4.2.3 配置 NIS 从服务器

  配置 NIS 从服务器, 甚至比配置主服务器还要简单。 登录到从服务器上, 并按照前面的方法, 编辑 /etc/rc.conf 文件。 唯一的区别是, 在运行 ypinit 时需要使用 -s 参数。 这里的 -s 选项, 同时要求提供 NIS 主服务器的名字, 因此我们的命令行应该是:

coltrane# ypinit -s ellington test-domain

Server Type: SLAVE Domain: test-domain Master: ellington

Creating an YP server will require that you answer a few questions.
Questions will all be asked at the beginning of the procedure.

Do you want this procedure to quit on non-fatal errors? [y/n: n]  n

Ok, please remember to go back and redo manually whatever fails.
If you don't, something might not work.
There will be no further questions. The remainder of the procedure
should take a few minutes, to copy the databases from ellington.
Transferring netgroup...
ypxfr: Exiting: Map successfully transferred
Transferring netgroup.byuser...
ypxfr: Exiting: Map successfully transferred
Transferring netgroup.byhost...
ypxfr: Exiting: Map successfully transferred
Transferring master.passwd.byuid...
ypxfr: Exiting: Map successfully transferred
Transferring passwd.byuid...
ypxfr: Exiting: Map successfully transferred
Transferring passwd.byname...
ypxfr: Exiting: Map successfully transferred
Transferring group.bygid...
ypxfr: Exiting: Map successfully transferred
Transferring group.byname...
ypxfr: Exiting: Map successfully transferred
Transferring services.byname...
ypxfr: Exiting: Map successfully transferred
Transferring rpc.bynumber...
ypxfr: Exiting: Map successfully transferred
Transferring rpc.byname...
ypxfr: Exiting: Map successfully transferred
Transferring protocols.byname...
ypxfr: Exiting: Map successfully transferred
Transferring master.passwd.byname...
ypxfr: Exiting: Map successfully transferred
Transferring networks.byname...
ypxfr: Exiting: Map successfully transferred
Transferring networks.byaddr...
ypxfr: Exiting: Map successfully transferred
Transferring netid.byname...
ypxfr: Exiting: Map successfully transferred
Transferring hosts.byaddr...
ypxfr: Exiting: Map successfully transferred
Transferring protocols.bynumber...
ypxfr: Exiting: Map successfully transferred
Transferring ypservers...
ypxfr: Exiting: Map successfully transferred
Transferring hosts.byname...
ypxfr: Exiting: Map successfully transferred

coltrane has been setup as an YP slave server without any errors.
Don't forget to update map ypservers on ellington.

  现在应该会有一个叫做 /var/yp/test-domain 的目录。 在这个目录中, 应该保存 NIS 主服务器上的映射的副本。 接下来需要确定这些文件都及时地同步更新了。 在从服务器上, 下面的 /etc/crontab 项将帮助您确保这一点:

20      *       *       *       *       root   /usr/libexec/ypxfr passwd.byname
21      *       *       *       *       root   /usr/libexec/ypxfr passwd.byuid

  这两行将强制从服务器将映射与主服务器同步。 由于主服务器会尝试确保所有其 NIS 映射的变动都知会从服务器, 因此这些项并不是绝对必需的, 尽管如此, 强制更新能够保证这些对依赖于服务器的系统至关重要的口令信息及时地同步。 同时, 在繁忙的网络上, 有时也会出现映射同步更新不完全的情况。

  现在, 在从服务器上执行 /etc/netstart, 就可以启动 NIS 服务了。

27.4.4.3 NIS 客户机

  NIS 客户机会通过 ypbind 服务程序来与特定的 NIS 服务器建立一种称作绑定的联系。 ypbind 会检查系统的默认域 (这是通过 domainname 命令来设置的), 并开始在本地网络上广播 RPC 请求。 这些请求会指定 ypbind 尝试绑定的域名。 如果已经配置了服务器, 并且这些服务器接到了广播, 它将回应 ypbind, 后者则记录服务器的地址。 如果有多个可用的服务器 (例如一个主服务器, 加上多个从服务器), ypbind 将使用第一个响应的地址。 从这一时刻开始, 客户机会把所有的 NIS 请求直接发给那个服务器。 ypbind 偶尔会 “ping” 服务器以确认其仍然在正常运行。 如果在合理的时间内没有得到响应, 则 ypbind 会把域标记为未绑定, 并再次发起广播, 以期找到另一台服务器。

27.4.4.3.1 设置 NIS 客户机

  配置一台 FreeBSD 机器作为 NIS 客户机是非常简单的。

  1. 编辑 /etc/rc.conf 文件, 并在其中加上下面几行, 以设置 NIS 域名, 并在网络启动时启动 ypbind

    nisdomainname="test-domain"
    nis_client_enable="YES"
    
  2. 要从 NIS 服务器导入所有的口令项, 需要从您的 /etc/master.passwd 文件中删除所有用户, 并使用 vipw 在这个文件的最后一行加入:

    +:::::::::
    

    注意: 这一行将让 NFS 服务器的口令映射中的帐号能够登录。 也有很多修改这一行来配置 NIS 客户机的办法。 请参见稍后的 netgroups 小节 以了解进一步的情况。 要了解更多信息, 可以参阅 O'Reilly 的 Managing NFS and NIS 这本书。

    注意: 需要至少保留一个本地帐号 (也就是不通过 NIS 导入) 在您的 /etc/master.passwd 文件中, 而这个帐号应该是 wheel 组的成员。 如果 NIS 发生不测, 这个帐号可以用来远程登录, 成为 root, 并修正问题。

  3. 要从 NIS 服务器上导入组信息, 需要在 /etc/group 文件末尾加入:

    +:*::
    

  完成这些步骤之后, 就应该可以通过运行 ypcat passwd 来看到 NIS 服务器的口令映射了。

27.4.5 NIS 的安全性

  基本上, 任何远程用户都可以发起一个 RPC 到 ypserv(8) 并获得您的 NIS 映射的内容, 如果远程用户了解您的域名的话。 要避免这类未经授权的访问, ypserv(8) 支持一个称为 “securenets” 的特性, 用以将访问限制在一组特定的机器上。 在启动过程中, ypserv(8) 会尝试从 /var/yp/securenets 中加载 securenet 信息。

注意: 这个路径随 -p 参数改变。 这个文件包含了一些项, 每一项中包含了一个网络标识和子网掩码, 中间用空格分开。 以 “#” 开头的行会被认为是注释。 示范的 securenets 文件如下所示:

# allow connections from local host -- mandatory
127.0.0.1     255.255.255.255
# allow connections from any host
# on the 192.168.128.0 network
192.168.128.0 255.255.255.0
# allow connections from any host
# between 10.0.0.0 to 10.0.15.255
# this includes the machines in the testlab
10.0.0.0      255.255.240.0

  如果 ypserv(8) 接到了来自匹配上述任一规则的地址的请求, 则它会正常处理请求。 反之, 则请求将被忽略, 并记录一条警告信息。 如果 /var/yp/securenets 文件不存在, 则 ypserv 会允许来自任意主机的请求。

  ypserv 程序也支持 Wietse Venema 的 TCP Wrapper 软件包。 这样, 管理员就能够使用 TCP Wrapper 的配置文件来代替 /var/yp/securenets 完成访问控制。

注意: 尽管这两种访问控制机制都能够提供某种程度的安全, 但是, 和特权端口检查一样, 它们无法避免 “IP 伪造” 攻击。 您的防火墙应该阻止所有与 NIS 有关的访问。

使用 /var/yp/securenets 的服务器, 可能会无法为某些使用陈旧的 TCP/IP 实现的 NIS 客户机服务。 这些实现可能会在广播时, 将主机位都设置为 0, 或在计算广播地址时忽略子网掩码。 尽管这些问题可以通过修改客户机的配置来解决, 其他一些问题也可能导致不得不淘汰那些客户机系统, 或者不使用 /var/yp/securenets

在使用陈旧的 TCP/IP 实现的系统上, 使用 /var/yp/securenets 是一个非常糟糕的做法, 因为这将导致您的网络上的 NIS 丧失大部分功能。

使用 TCP Wrapper 软件包, 会导致您的 NIS 服务器的响应延迟增加。 而增加的延迟, 则可能会导致客户端程序超时, 特别是在繁忙的网络或者很慢的 NIS 服务器上。 如果您的某个客户机因此而产生一些异常, 则应将这些客户机变为 NIS 从服务器, 并强制其绑定自己。

27.4.6 不允许某些用户登录

  在我们的实验室中, basie 这台机器, 是一台教员专用的工作站。 我们不希望将这台机器拿出 NIS 域, 而主 NIS 服务器上的 passwd 文件, 则同时包含了教员和学生的帐号。 这时应该怎么做?

  有一种办法来禁止特定的用户登录机器, 即使他们身处 NIS 数据库之中。 要完成这一工作, 只需要在客户机的 /etc/master.passwd 文件中加入一些 -username 这样的项, 其中, username 是希望禁止登录的用户名。 一般推荐使用 vipw 来完成这个工作, 因为 vipw 会对您在 /etc/master.passwd 文件上所作的修改进行合法性检查, 并在编辑结束时重新构建口令数据库。 例如, 如果希望禁止用户 bill 登录 basie, 我们应该:

basie# vipw
[在末尾加入 -bill, 并退出]
vipw: rebuilding the database...
vipw: done

basie# cat /etc/master.passwd

root:[password]:0:0::0:0:The super-user:/root:/bin/csh
toor:[password]:0:0::0:0:The other super-user:/root:/bin/sh
daemon:*:1:1::0:0:Owner of many system processes:/root:/sbin/nologin
operator:*:2:5::0:0:System &:/:/sbin/nologin
bin:*:3:7::0:0:Binaries Commands and Source,,,:/:/sbin/nologin
tty:*:4:65533::0:0:Tty Sandbox:/:/sbin/nologin
kmem:*:5:65533::0:0:KMem Sandbox:/:/sbin/nologin
games:*:7:13::0:0:Games pseudo-user:/usr/games:/sbin/nologin
news:*:8:8::0:0:News Subsystem:/:/sbin/nologin
man:*:9:9::0:0:Mister Man Pages:/usr/share/man:/sbin/nologin
bind:*:53:53::0:0:Bind Sandbox:/:/sbin/nologin
uucp:*:66:66::0:0:UUCP pseudo-user:/var/spool/uucppublic:/usr/libexec/uucp/uucico
xten:*:67:67::0:0:X-10 daemon:/usr/local/xten:/sbin/nologin
pop:*:68:6::0:0:Post Office Owner:/nonexistent:/sbin/nologin
nobody:*:65534:65534::0:0:Unprivileged user:/nonexistent:/sbin/nologin
+:::::::::
-bill

basie#

27.4.7 使用 Netgroups

Contributed by Udo Erdelhoff.

  前一节介绍的方法, 在您需要为非常少的用户和/或机器进行特殊的规则配置时还算凑合。 在更大的网络上, 您 一定会 忘记禁止某些用户登录到敏感的机器上, 或者, 甚至必须单独地修改每一台机器的配置, 因而丢掉了 NIS 最重要的优越性: 集中式 管理。

  NIS 开发人员为这个问题提供的解决方案, 被称作 netgroups。 它们的作用和语义, 基本上可以等同于 UNIX 文件系统上使用的组。 主要的区别是它们没有数字化的 ID, 以及可以在 netgroup 中同时包含用户和其他 netgroup。

  Netgroups 被设计用来处理大的、 复杂的包含数百用户和机器的网络。 一方面, 在您不得不处理这类情形时, 这是一个很有用的东西。 而另一方面, 它的复杂性又使得通过非常简单的例子很难解释 netgroup 到底是什么。 这一节的其余部分的例子将展示这个问题。

  假设您在实验室中成功地部署 NIS 引起了上司的兴趣。 您接下来的任务是将 NIS 域扩展, 以覆盖校园中的一些其他的机器。 下面两个表格中包括了新用户和新机器, 及其简要说明。

用户名 说明
alpha, beta IT 部门的普通雇员
charlie, delta IT 部门的学徒
echo, foxtrott, golf, ... 普通雇员
able, baker, ... 目前的实习生
机器名 说明
war, death, famine, pollution 最重要的服务器。 只有 IT 部门的雇员才允许登录这些机器。
pride, greed, envy, wrath, lust, sloth 不太重要的服务器, 所有 IT 部门的成员, 都可以登录这些机器。
one, two, three, four, ... 普通工作站。 只有 真正的 雇员才允许登录这些机器。
trashcan 一台不包含关键数据的旧机器。 即使是实习生, 也允许登录它。

  如果您尝试通过一个一个地阻止用户来实现这些限制, 就需要在每一个系统的 passwd 文件中, 为每一个不允许登录该系统的用户添加对应的 -user 行。 如果忘记了任何一个, 就可能会造成问题。 在进行初始配置时, 正确地配置也许不是什么问题, 但随着日复一日地添加新用户, 总有一天 您会忘记为新用户添加某个行。 毕竟, Murphy 是一个乐观的人。

  使用 netgroups 来处理这一状况可以带来许多好处。 不需要单独地处理每一个用户; 您可以赋予用户一个或多个 netgroups 身份, 并允许或禁止某一个 netgroup 的所有成员登录。 如果添加了新的机器, 只需要定义 netgroup 的登录限制。 如果增加了新用户, 也只需要将用户加入一个或多个 netgroup。 这些变化是相互独立的: 不再需要 “对每一个用户和机器执行 ……”。 如果您的 NIS 配置经过了谨慎的规划, 就只需要修改一个中央的配置文件, 就能够允许或禁止访问某台机器的权限了。

  第一步是初始化 NIS 映射 netgroup。 FreeBSD 的 ypinit(8) 默认情况下并不创建这个映射, 但它的 NIS 实现能够在创建这个映射之后立即对其提供支持。 要创建空映射, 简单地输入

ellington# vi /var/yp/netgroup

  并开始增加内容。 在我们的例子中, 至少需要四个 nergruop: IT 雇员, IT 学徒, 普通雇员和实习生。

IT_EMP  (,alpha,test-domain)    (,beta,test-domain)
IT_APP  (,charlie,test-domain)  (,delta,test-domain)
USERS   (,echo,test-domain)     (,foxtrott,test-domain) \
        (,golf,test-domain)
INTERNS (,able,test-domain)     (,baker,test-domain)

  IT_EMP, IT_APP 等等, 是 netgroup 的名字。 每一个括号中的组中, 都有一些用户帐号。 组中的三个字段是:

  1. 在哪些机器上能够使用这些项。 如果不指定主机名, 则项在所有机器上都有效。 如果指定了主机, 则很容易造成混淆。

  2. 属于这个 netgroup 的帐号。

  3. 帐号的 NIS 域。 您可以从其他 NIS 域中把帐号导入到您的 netgroup 中, 如果您管理多个 NIS 域的话。

  每一个字段都可以包括通配符。 参见 netgroup(5) 了解更多细节。

注意: Netgroup 的名字一般来说不应超过 8 个字符, 特别是当您的 NIS 域中有机器打算运行其它操作系统的时候。 名字是区分大小写的; 使用大写字母作为 netgroup 的名字, 能够让您更容易地区分用户、 机器和 netgroup 的名字。

某些 NIS 客户程序 (FreeBSD 以外的那些) 可能无法处理含有大量项的 netgroup。 例如, 某些早期版本的 SunOS 会在 netgroup 中包含多于 15 个 时出现问题。 要绕过这个问题, 可以创建多个 子netgroup,每一个中包含少于 15 个用户, 以及一个包含所有 子netgroup 的真正的 netgroup:

BIGGRP1  (,joe1,domain)  (,joe2,domain)  (,joe3,domain) [...]
BIGGRP2  (,joe16,domain)  (,joe17,domain) [...]
BIGGRP3  (,joe31,domain)  (,joe32,domain)
BIGGROUP  BIGGRP1 BIGGRP2 BIGGRP3

如果需要超过 225 个用户, 可以继续重复上面的过程。

  激活并分发新的 NIS 映射非常简单:

ellington# cd /var/yp
ellington# make

  这个操作会生成三个 NIS 映射, 即 netgroupnetgroup.byhostnetgroup.byuser。 用 ypcat(1) 可以检查这些 NIS 映射是否可用了:

ellington% ypcat -k netgroup
ellington% ypcat -k netgroup.byhost
ellington% ypcat -k netgroup.byuser

  第一个命令的输出, 应该与 /var/yp/netgroup 的内容相近。 第二个命令, 如果没有指定本机专有的 netgroup, 则应该没有输出。 第三个命令, 则用于显示某个用户对应的 netgroup 列表。

  客户机的设置也很简单。 要配置服务器 war, 只需进入 vipw(8) 并把

+:::::::::

  改为

+@IT_EMP:::::::::

  现在, 只有 netgroup IT_EMP 中定义的用户会被导入到 war 的口令数据库中, 因此只有这些用户能够登录。

  不过, 这个限制也会作用于 shell 的 ~, 以及所有在用户名和数字用户 ID 之间实施转换的函数的功能。 换言之, cd ~user 将不会正常工作, 而 ls -l 也将显示数字的 ID 而不是用户名, 并且 find . -user joe -print 将失败, 并给出 “No such user” 的错误信息。 要修正这个问题, 您需要导入所有的用户项, 而 不允许他们登录服务器

  这可以通过在 /etc/master.passwd 加入另一行来完成。 这行的内容是:

  +:::::::::/sbin/nologin, 意思是 “导入所有的项, 但导入项的 shell 则替换为 /sbin/nologin”。 通过在 /etc/master.passwd 中增加默认值, 可以替换掉 passwd 中的任意字段。

警告: 务必确认 +:::::::::/sbin/nologin 这一行出现在 +@IT_EMP::::::::: 之后。 否则, 所有从 NIS 导入的用户帐号将以 /sbin/nologin 作为登录 shell。

  完成上面的修改之后, 在 IT 部门有了新员工时, 只需修改一个 NIS 映射就足够了。 您也可以用类似的方法, 在不太重要的服务器上, 把先前本地版本的 /etc/master.passwd 中的 +::::::::: 改为:

+@IT_EMP:::::::::
+@IT_APP:::::::::
+:::::::::/sbin/nologin

  相关的用于普通工作站的配置则应是:

+@IT_EMP:::::::::
+@USERS:::::::::
+:::::::::/sbin/nologin

  一切平安无事, 直到数周后, 有一天策略发生了变化: IT 部门也开始招收实习生了。 IT 实习生允许使用普通的终端, 以及不太重要的服务器; 而 IT 学徒, 则可以登录主服务器。 您增加了新的 netgroup IT_INTERN, 以及新的 IT 实习生到这个 netgroup 并开始修改每一台机器上的配置…… 老话说得好:“牵一发, 动全身”。

  NIS 通过 netgroup 来建立 netgroup 的能力, 正可以避免这样的情形。 一种可能的方法是建立基于角色的 netgroup。 例如, 您可以创建称为 BIGSRV 的 netgroup, 用于定义最重要的服务器上的登录限制, 以及另一个成为 SMALLSRV 的 netgroup, 用以定义次重要的服务器, 以及第三个, 用于普通工作站的 netgroup USERBOX。 这三个 netgroup 中的每一个, 都包含了允许登录到这些机器上的所有 netgroup。 您的 NIS 映射中的新项如下所示:

BIGSRV    IT_EMP  IT_APP
SMALLSRV  IT_EMP  IT_APP  ITINTERN
USERBOX   IT_EMP  ITINTERN USERS

  这种定义登录限制的方法, 在您能够将机器分组并加以限制的时候可以工作的相当好。 不幸的是, 这是种例外, 而非常规情况。 多数时候, 需要按机器去定义登录限制。

  与机器相关的 netgroup 定义, 是处理上述策略改动的另一种可能的方法。 此时, 每台机器的 /etc/master.passwd 中, 都包含两个 “+” 开头的行。 第一个用于添加允许登录的 netgroup 帐号, 而第二个则用于增加其它帐号, 并把 shell 设置为 /sbin/nologin。 使用 “全大写” 的机器名作为 netgroup 名是个好主意。 换言之, 这些行应该类似于:

+@BOXNAME:::::::::
+:::::::::/sbin/nologin

  一旦在所有机器上都完成了这样的修改, 就再也不需要修改本地的 /etc/master.passwd 了。 所有未来的修改都可以在 NIS 映射中进行。 这里是一个例子, 其中展示了在这一应用情景中所需要的 netgroup 映射, 以及其它一些常用的技巧:

# Define groups of users first
IT_EMP    (,alpha,test-domain)    (,beta,test-domain)
IT_APP    (,charlie,test-domain)  (,delta,test-domain)
DEPT1     (,echo,test-domain)     (,foxtrott,test-domain)
DEPT2     (,golf,test-domain)     (,hotel,test-domain)
DEPT3     (,india,test-domain)    (,juliet,test-domain)
ITINTERN  (,kilo,test-domain)     (,lima,test-domain)
D_INTERNS (,able,test-domain)     (,baker,test-domain)
#
# Now, define some groups based on roles
USERS     DEPT1   DEPT2     DEPT3
BIGSRV    IT_EMP  IT_APP
SMALLSRV  IT_EMP  IT_APP    ITINTERN
USERBOX   IT_EMP  ITINTERN  USERS
#
# And a groups for a special tasks
# Allow echo and golf to access our anti-virus-machine
SECURITY  IT_EMP  (,echo,test-domain)  (,golf,test-domain)
#
# machine-based netgroups
# Our main servers
WAR       BIGSRV
FAMINE    BIGSRV
# User india needs access to this server
POLLUTION  BIGSRV  (,india,test-domain)
#
# This one is really important and needs more access restrictions
DEATH     IT_EMP
#
# The anti-virus-machine mentioned above
ONE       SECURITY
#
# Restrict a machine to a single user
TWO       (,hotel,test-domain)
# [...more groups to follow]

  如果您正使用某种数据库来管理帐号, 应该可以使用您的数据库的报告工具来创建映射的第一部分。 这样, 新用户就自动地可以访问这些机器了。

  最后的提醒: 使用基于机器的 netgroup 并不总是适用的。 如果正在为学生实验室部署数十台甚至上百台同样的机器, 您应该使用基于角色的 netgroup, 而不是基于机器的 netgroup, 以便把 NIS 映射的尺寸保持在一个合理的范围内。

27.4.8 需要牢记的事项

  这里是一些其它在使用 NIS 环境时需要注意的地方。

27.4.9 NIS v1 兼容性

  FreeBSD 的 ypserv 提供了某些为 NIS v1 客户提供服务的支持能力。 FreeBSD 的 NIS 实现, 只使用 NIS v2 协议, 但其它实现可能会包含 v1 协议, 以提供对旧系统的向下兼容能力。 随这些系统提供的 ypbind 服务将首先尝试绑定 NIS v1 服务器, 即使它们并不真的需要它 (有些甚至可能会一直广播搜索请求, 即使已经从某台 v2 服务器得到了回应也是如此)。 注意, 尽管支持一般的客户机调用, 这个版本的 ypserv 并不能处理 v1 的映射传送请求; 因而, 它就不能与较早的支持 v1 协议的 NIS 服务器配合使用, 无论是作为主服务器还是从服务器。 幸运的是, 现今应该已经没有仍然在用的这样的服务器了。

27.4.10 同时作为 NIS 客户机的 NIS 服务器

  在多服务器域的环境中, 如果服务器同时作为 NIS 客户, 在运行 ypserv 时要特别小心。 一般来说, 强制服务器绑定自己要比允许它们广播绑定请求要好, 因为这种情况下它们可能会相互绑定。 某些怪异的故障, 很可能是由于某一台服务器停机, 而其它服务器都依赖其服务所导致的。 最终, 所有的客户机都会超时并绑定到其它服务器, 但这个延迟可能会相当可观, 而且恢复之后仍然存在再次发生此类问题的隐患。

  您可以强制一台机器绑定到特定的服务器, 这是通过 ypbind-S 参数来完成的。 如果不希望每次启动 NIS 服务器时都手工完成这项工作, 可以在 /etc/rc.conf 中加入:

nis_client_enable="YES"    # run client stuff as well
nis_client_flags="-S NIS domain,server"

  参见 ypbind(8) 以了解更多情况。

27.4.11 口令格式

  在实现 NIS 时, 口令格式的兼容性问题是一种最为常见的问题。 假如您的 NIS 服务器使用 DES 加密口令, 则它只能支持使用 DES 的客户机。 例如, 如果您的网络上有 Solaris NIS 客户机, 则几乎肯定需要使用 DES 加密口令。

  要检查您的服务器和客户机使用的口令格式, 需要查看 /etc/login.conf。 如果主机被配置为使用 DES 加密的口令, 则 default class 将包含类似这样的项:

default:\
    :passwd_format=des:\
    :copyright=/etc/COPYRIGHT:\
    [Further entries elided]

  其他一些可能的 passwd_format 包括 blfmd5 (分别对应于 Blowfish 和 MD5 加密口令)。

  如果修改了 /etc/login.conf, 就必须重建登录性能数据库, 这是通过以 root 身份运行下面的程序来完成的:

# cap_mkdb /etc/login.conf

注意: 已经在 /etc/master.passwd 中的口令的格式不会被更新, 直到用户在登录性能数据库重建 之后 首次修改口令为止。

  接下来, 为了确保所有的口令都按照您选择的格式加密了, 还需要检查 /etc/auth.confcrypt_default 给出的优先选择的口令格式。 要完成此工作, 将您选择的格式放到列表的第一项。 例如, 当使用 DES 加密的口令时, 对应项应为:

crypt_default  =   des blf md5

  在每一台基于 FreeBSD 的 NIS 服务器和客户机上完成上述工作之后, 就可以肯定您的网络上它们都在使用同样的口令格式了。 如果在 NIS 客户机上做身份验证时发生问题, 这也是第一个可能出现问题的地方。 注意: 如果您希望在混合的网络上部署 NIS 服务器, 可能就需要在所有系统上都使用 DES, 因为这是所有系统都能够支持的最低限度的公共标准。

本文档和其它文档可从这里下载:ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/.

如果对于FreeBSD有问题,请先阅读文档,如不能解决再联系<questions@FreeBSD.org>.
关于本文档的问题请发信联系 <doc@FreeBSD.org>.