3.3.用户和基本账户管理 ====================== FreeBSD 允许多用户同时使用计算机。虽然在任何时候都只有一个用户可以坐在屏幕前使用键盘,但任意数量的用户都可以通过网络登录到系统。每个为了使用该系统的用户都应该有自己的用户账户。 本章介绍了: - FreeBSD 系统中不同类型的用户账户。 - 如何添加、删除和修改用户账户。 - 如何设置限制来控制允许用户和组访问的资源。 - 如何创建组并将用户添加为组的成员。 3.3.1.账户类型 -------------- 由于对 FreeBSD 系统的所有访问都是通过帐户实现的,而且所有进程都是由用户运行的,因此用户和帐户的管理非常重要。 主要有三种类型的账户:系统账户、用户账户和超级用户账户。 3.3.1.1.系统账户 ~~~~~~~~~~~~~~~~ 系统账户用于运行服务,如 DNS、邮件和网络服务器。这样做的原因是安全问题;如果所有的服务都以超级用户的身份运行,它们就可以不受限制地行动。 系统账户例如 ``daemon``\ 、\ ``operator``\ 、\ ``bind``\ 、\ ``news``\ 、\ ``www``\ 。 ``nobody`` 是通用的无特权系统账户。然而,使用 ``nobody`` 的服务越多,该用户将与更多的文件和进程相关联,因此该用户的特权也就越大。 3.3.1.2.用户账户 ~~~~~~~~~~~~~~~~ 用户账户被分配给真实的人,用来登录和使用系统。每个访问系统的人都应该有一个独特的用户账户。这使管理员能够发现谁在做什么,并防止用户篡改其他用户的设置。 每个用户都可以通过配置默认的 shell、编辑器、组合键和语言设置来设置自己的环境,以适应他们对系统的使用。 在 FreeBSD 系统上的每个用户账户都有一些相关的信息。 **User name** 用户名称是在 ``login:`` 提示符下输入的。每个用户都必须有一个唯一的用户名。在 `passwd(5) `__ 中记录了一些创建有效用户名的规则。建议使用由八个或更少的小写字母组成的用户名,以保持与应用程序的向后兼容性。 **Password** 每个账户都有一个对应的密码。 **User ID (UID)** 用户 ID(UID)是一组数字,用于在 FreeBSD 系统中唯一地识别用户。当命令使用到了用户名时,会先将其转换为 UID。建议使用小于 65535 的 UID,因为过高的值可能会引起某些软件的兼容性问题。 **Group ID (GID)** 组 ID(GID)是一组数字,用于唯一地识别用户所属的主要组。组是根据用户的 GID 而不是 UID 来控制对资源的访问一种机制。这可以大大减少一些配置文件的大小,并允许用户成为多个组的成员。建议使用 65535 或更小的 GID,因为过高的 GID 可能会引起某些软件的兼容性问题。 **Login class** 登录分级是对组机制的扩展,在为不同用户定制系统时提供了额外的灵活性。登录分级在\ `配置登录分级 `__\ 中有进一步讨论。 **Password change time** 默认情况下,密码是不会过期的。然而,可以在每个用户的基础上启用密码过期,迫使部分或所有用户在一定时间后改变他们的密码。 **Account expiration time** 默认情况下,FreeBSD 不对账户进行过期保护。当创建需要有限寿命的账户时,例如学校的学生账户,可以使用 `pw(8) `__ 指定账户的过期时间。在过期时间过后,就不能用这个账户来登录系统了,不过会保留这个账户的目录和文件。 **User’s full name** 用户名称对 FreeBSD 来说是账户的唯一标识,但不一定反映用户的真实姓名。与注释类似,这一信息可以包含空格、大写字母,并且长度可超过 8 个字符。 **Home directory** 主目录是系统中某个目录的完整路径。当用户登录时,这是用户的起始目录。一个常见的惯例是把所有用户的主目录放在 ``/home/username`` 或 ``/usr/home/username`` 下。每个用户都把他们的个人文件和子目录存放在自己的主目录下。 **User shell** shell 为用户提供了与系统交互的默认环境。有许多不同种类的 shell,有经验的用户会有自己的偏好,这反映在他们的帐户设置中。 3.3.1.3.超级用户 ~~~~~~~~~~~~~~~~ 超级用户,通常称为 ``root``\ ,用于管理系统,没有权限限制。由于这个原因,它不应该被用于日常工作,如发送和接收邮件,以及对系统的一般探索或编程。 超级用户与普通用户不同,可以不受限制地操作,滥用超级用户可能导致巨大的灾难。普通用户因为权限不足而无法因人为失误而破坏操作系统。因此建议以普通用户登录,只有在命令需要额外权限时才成为超级用户。 对于以超级用户身份发布的任何命令,一定要进行双重和三重检查,因为一个额外的空格或缺失的字符可能意味着不可修复的数据损失。 有几种方法可以获得超级用户的权限。虽然人们可以直接以 ``root`` 身份登录,但这是非常不可取的。 相反,使用 `su(1) `__ 来成为超级用户。如果在运行这个命令时指定了 ``-``\ ,用户也将继承 root 用户的环境。运行该命令的用户必须在 ``wheel`` 组中,否则命令会执行失败。该用户还必须知道 ``root`` 用户的账户密码。 在这个例子中,用户只有成为超级用户才能运行 ``make install``\ ,因为这个步骤需要超级用户的权限。命令完成后,用户输入 ``exit``\ ,退出超级用户账户,返回到普通用户的权限。 **例 1. 以超级用户身份安装一个程序** .. code:: shell-session % configure % make % su - Password: # make install # exit % 内置的 `su(1) `__ 框架对于只有一个系统管理员的单一系统或小型网络来说效果很好。另一个选择是通过软件包或 port 安装 `security/sudo `__\ 。这个软件提供活动日志,并允许管理员配置哪些用户可以作为超级用户运行哪些命令。 3.3.2.管理账户 -------------- FreeBSD 提供了各种不同的命令来管理用户账户。最常见的命令在\ `管理用户帐户的实用工具 `__\ 中进行了总结,后面还有一些使用实例。关于更多的细节和使用例子,请参见每个工具的手册页面。 **表 1. 管理用户账户的实用工具** ======================================================================================== ================================================== 命令 摘要 ======================================================================================== ================================================== `adduser(8) `__ 推荐用于添加新用户的命令行程序。 `rmuser(8) `__ 推荐用于删除用户的命令行程序。 `chpass(1) `__ 一个灵活的,用于改变用户数据库信息的工具。 `passwd(1) `__ 用于更改用户密码的命令行工具。 `pw(8) `__ 一个强大而灵活的工具,用于修改用户账户的方方面面。 `bsdconfig(8) `__ 一个支持账户管理的系统配置工具。 ======================================================================================== ================================================== 3.3.2.1.添加用户 ~~~~~~~~~~~~~~~~ 推荐用于添加新用户的程序是 `adduser(8) `__\ 。当一个新用户被添加时,这个程序会自动更 ``/etc/passwd`` 和 ``/etc/group``\ 。它还为新用户创建一个主目录,从 ``/usr/share/skel`` 复制默认的配置文件,并可以选择给新用户发送欢迎信息。这个工具必须以超级用户的身份运行。 `adduser(8) `__ 工具是交互式的,它将引导你完成创建一个新用户账户的步骤。正如在 FreeBSD 上添加用户中所看到的,要么输入所需的信息,要么按\ ``回车键``\ 接受方括号中的默认值。在这个例子中,用户被邀请进入 ``wheel`` 组,允许他们用 `su(1) `__ 成为超级用户。完成后,该工具将提示创建另一个用户或退出。 **例 2. 在 FreeBSD 上添加一个用户** .. code:: shell-session # adduser 输出结果应类似于以下内容: .. code:: shell-session Username: jru Full name: J. Random User Uid (Leave empty for default): Login group [jru]: Login group is jru. Invite jru into other groups? []: wheel Login class [default]: Shell (sh csh tcsh zsh nologin) [sh]: zsh Home directory [/home/jru]: Home directory permissions (Leave empty for default): Use password-based authentication? [yes]: Use an empty password? (yes/no) [no]: Use a random password? (yes/no) [no]: Enter password: Enter password again: Lock out the account after creation? [no]: Username : jru Password : **** Full Name : J. Random User Uid : 1001 Class : Groups : jru wheel Home : /home/jru Shell : /usr/local/bin/zsh Locked : no OK? (yes/no): yes adduser: INFO: Successfully added (jru) to the user database. Add another user? (yes/no): no Goodbye! .. **注意** 由于密码在输入时并不会显示,所以在创建用户账户时要注意不要打错密码。 3.3.2.2.删除用户 ~~~~~~~~~~~~~~~~ 要从系统中完全删除一个用户,请以超级用户身份运行 `rmuser(8) `__\ 。该命令会执行以下步骤: 1. 删除该用户的 `crontab(1) `__ 条目,如果存在的话。 2. 删除属于该用户的任何 `at(1) `__ 作业。 3. 发送 SIGKILL 信号给所有属于该用户的进程。 4. 从系统的本地密码文件中删除该用户。 5. 删除用户的主目录(如果它是由该用户拥有的),包括处理实际主目录路径中的符号链接。 6. 从 ``/var/mail`` 中删除属于该用户的邮件文件。 7. 从 ``/tmp``\ 、\ ``/var/tmp`` 和 ``/var/tmp/vi.recover`` 中删除所有由用户拥有的文件。 8. 将用户名从其在 ``/etc/group`` 中所属的所有组中移除。(如果一个组变成空的,并且组名与用户名相同,这个组就会被删除;这是对 `adduser[8] `__ 的每个用户唯一组的补充规则)。 9. 移除用户拥有的所有消息队列、共享内存和信号量。 `rmuser(8) `__ 不能用来删除超级用户账户,因为这几乎代表着大规模破坏。 默认情况下,使用的是交互式模式,如下面的例子所示。 **例 3. rmuser 交互式删除账户** .. code:: shell-session # rmuser jru 输出结果应类似于以下内容: .. code:: shell-session Matching password entry: jru:*:1001:1001::0:0:J. Random User:/home/jru:/usr/local/bin/zsh Is this the entry you wish to remove? y Remove user's home directory (/home/jru)? y Removing user (jru): mailspool home passwd. 3.3.2.3.修改用户信息 ~~~~~~~~~~~~~~~~~~~~ 任何用户都可以使用 `chpass(1) `__ 来改变他们的默认 shell 和与用户帐户相关的个人信息。超级用户可以使用这个工具来改变任何用户的额外账户信息。 当除了一个可选的用户名外,没有其他选项时,\ `chpass(1) `__ 会显示一个包含用户信息的编辑器。当用户从编辑器中退出时,用户数据库被更新为新的信息。 **注意** 在退出编辑器时该工具将提示用户输入密码,除非以超级用户身份运行该工具。 在\ `以超级用户身份使用 chpass `__ 中,超级用户已经输入了 ``chpass jru``\ ,现在正在查看这个用户可以修改的字段。如果以 ``jru`` 来运行这个命令,只会显示且可编辑最后六个字段。这在\ `以普通用户身份使用chpass `__\ 中概述。 **例 4. 使用 chpass 作为超级用户** .. code:: shell-session # chpass 输出结果应类似于以下内容: .. code:: shell-session #Changing user database information for jru. Login: jru Password: * Uid [#]: 1001 Gid [# or name]: 1001 Change [month day year]: Expire [month day year]: Class: Home directory: /home/jru Shell: /usr/local/bin/zsh Full Name: J. Random User Office Location: Office Phone: Home Phone: Other information: .. **例 5. 使用 chpass 作为普通用户** .. code:: shell-session #Changing user database information for jru. Shell: /usr/local/bin/zsh Full Name: J. Random User Office Location: Office Phone: Home Phone: Other information: **注意** 命令 `chfn(1) `__ 和 `chsh(1) `__ 是 `chpass(1) `__ 的链接,\ `ypchpass(1) `__\ 、\ `ypchfn(1) `__ 和 `ypchsh(1) `__ 也是如此。NIS 的支持是系统自带的,不需要在命令前专门指定 ``yp``\ 。如何配置 NIS 在\ `网络服务器 `__\ 中有所介绍。 3.3.2.4.修改用户密码 ~~~~~~~~~~~~~~~~~~~~ 任何用户都可以使用 `passwd(1) `__ 轻松地修改他们的密码。为了防止意外或未经授权的更改,该命令在设置新密码之前会提示用户的原始密码: **例 6. 改变你的密码** .. code:: shell-session % passwd 输出结果应类似于以下内容: .. code:: shell-session Changing local password for jru. Old password: New password: Retype new password: passwd: updating the database... passwd: done 超级用户可以通过在运行 `passwd(1) `__ 时指定用户名来改变任何用户的密码。当这个工具以超级用户身份运行时,它将不会提示用户的当前密码。这允许在用户不记得原来的密码时修改密码。 **例 7. 以超级用户身份修改其他用户的密码** .. code:: shell-session # passwd jru 输出结果应类似于以下内容: .. code:: shell-session Changing local password for jru. New password: Retype new password: passwd: updating the database... passwd: done .. **注意** 与 `chpass(1) `__ 一样,\ `yppasswd(1) `__ 是 `passwd(1) `__ 的链接,所以 NIS 可以使用任何一条命令。 3.3.2.5.创建、删除、修改和显示系统用户和群组 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ `pw(8) `__ 可以删除、修改和显示用户和组。它的功能是作为系统用户和组文件的前端。\ `pw(8) `__ 有一组非常强大的命令行选项,使它适合于在 shell 脚本中使用,但新用户可能会发现它比本节介绍的其他命令更复杂。 3.3.3.组管理 ------------ 组是一个用户的列表。组由其组名和 GID 来识别。在 FreeBSD 中,内核使用一个进程的 UID 和它所属的组的列表来决定这个进程被允许做什么。大多数时候,一个用户或进程的 GID 通常意味着列表中的第一个组。 组名与 GID 的对应列表被列在 ``/etc/group`` 中。这是一个纯文本文件,有四个以冒号分隔的字段。第一个字段是组名,第二个是加密的密码,第三个是 GID,第四个是以逗号分隔的成员列表。关于语法的更完整说明,请参考 `group(5) `__\ 。 超级用户可以使用文本编辑器修改 ``/etc/group``\ ,但是建议使用\ `vigr[8] `__ 来编辑组文件,因为它可以捕捉到一些常见的错误。另外,可以用 `pw(8) `__ 来添加和编辑组。例如,添加一个名为 ``teamtwo`` 的组,然后确认它的存在: **警告** 使用 operator 组时必须小心,因为可能会被授予类似超级用户的访问权限,包括但不限于关机、重启,以及访问组内 ``/dev`` 中的所有项目。 .. **例 8. 使用** `pw(8) `__ **添加一个组** .. code:: shell-session # pw groupadd teamtwo # pw groupshow teamtwo 输出结果应类似于以下内容: .. code:: shell-session teamtwo:*:1100: 在这个例子中,\ ``1100`` 是 ``teamtwo`` 的 GID。现在,\ ``teamtwo`` 没有成员。这个命令将添加 ``jru`` 为 ``teamtwo`` 的成员。 **例 9. 使用** `pw(8) `__ **将用户账户添加到一个新组中** .. code:: shell-session # pw groupmod teamtwo -M jru # pw groupshow teamtwo 输出结果应类似于以下内容: .. code:: shell-session teamtwo:*:1100:jru 参数 ``-M`` 会显示一个以逗号分隔的用户列表,用来添加到一个新的(空的)组或替换现有组的成员。对用户来说,这个组的成员资格与密码文件中列出的用户的主组不同(额外的)。这意味着在使用 `pw(8) `__ 的 ``groupshow`` 时,用户不会显示为成员,但在通过 `id(1) `__ 或类似工具查询信息时,会显示出来。当 `pw(8) `__ 被用来将一个用户添加到一个组时,它只操作 ``/etc/group``\ ,而不试图从 ``/etc/passwd`` 读取其他数据。 **例 10. 使用** `pw(8) `__ **向一个组添加新成员** .. code:: shell-session # pw groupmod teamtwo -m db # pw groupshow teamtwo 输出结果应类似于以下内容: .. code:: shell-session teamtwo:*:1100:jru,db 在这个例子中,参数 ``-m`` 会显示一个以逗号分隔的用户列表,这些用户将被添加到该组。与前面的例子不同,这些用户被添加到组中,并不取代组中的现有用户。 **例 11. 使用** `id(1) `__ **来确定群组成员资格** .. code:: shell-session % id jru 输出结果应类似于以下内容: .. code:: shell-session uid=1001(jru) gid=1001(jru) groups=1001(jru), 1100(teamtwo) 在这个例子中,\ ``jru`` 是 ``jru`` 和 ``teamtwo`` 组的成员。 关于这个命令和 **/etc/group** 格式的更多信息,请参考 `pw(8) `__ 和 `group(5) `__\ 。