修改帐户
在 UNIX® 环境下,管理用户帐户的命令种类繁多,但实际日常操作中常用的只有几项。下表汇总了这些核心命令及其功能说明,接下来我们将逐一举例讲解。
| 命令 | 摘要 |
| adduser(8) | 在命令行添加新用户 . |
| rmuser(8) | 在命令行删除用户 . |
| chpass(1) | 一个灵活的用于修改用户数据库信息的工具 . |
| passwd(1) | 一个用于修改用户口令的简单的命令行工具 . |
| pw(8) | 一个强大灵活修改用户帐户的工具 . |
FreeBSD 允许多个用户同时使用计算机。当然,这些用户并不是都坐在同一台机器前,而是通过网络远程连接来完成各自的工作。每个需要使用系统的人,都必须拥有一个独立的帐户。
读完本章,你将掌握以下内容:
- FreeBSD 系统中不同类型用户帐户的区别。
- 如何添加用户帐户。
- 如何删除用户帐户。
- 如何修改帐户细节,例如用户的全名或首选 Shell。
- 如何在每个帐户基础上设置限制,控制内存、CPU 时间等资源的使用。
- 如何利用组简化帐户管理工作。
阅读本章之前,建议你先了解:
- UNIX 和 FreeBSD 的基础知识(参见第 3 章)。
8.2 介绍
所有访问系统的用户都通过帐户来登录,因此用户及用户帐户的管理在 FreeBSD 中至关重要。
用户名:在 login: 提示符后输入。用户名在计算机上具有唯一性,不能有两个相同的用户名。创建用户名需遵循一定规则(可参考 passwd 的联机手册),通常要求不超过 8 个小写字母。
口令(password):每个帐户都对应一个口令。口令可以为空(即无需密码即可访问系统),但这通常不推荐。每个帐户都应当设置一个强口令。
用户 ID (UID):UID 是系统用来标识用户的数字,取值范围 0 到 65536。FreeBSD 使用 UID 识别用户——任何允许指定用户名的命令,在执行前都会将用户名转换为 UID。这意味着你可以用不同的用户名拥有多个帐户,但如果 UID 相同,FreeBSD 会视其为同一个用户。
组 ID (GID):GID 是用户所属组的数字标识,范围也是 0 到 65536。组是一种基于 GID 而非 UID 的资源访问控制机制,有助于减小配置文件大小。一个用户可以同时属于多个组。
登录类:登录类是对组机制的扩展,在分配系统资源时能为不同用户提供更灵活的配置。
口令的定期更换:默认情况下,FreeBSD 不会强制用户定期更改口令。不过,你可以为每个用户单独设置强制更换策略,例如让帐户过期或要求部分/全部用户定期更新口令。
帐户到期:默认情况下,FreeBSD 不会自动注销帐户。如果你创建了有使用期限的帐户(例如学校的学生帐户),可以为其设置过期时间。到期后,该帐户的目录和文件仍会保留,但用户将无法登录系统。
用户的全名:用户名唯一标识一个 FreeBSD 帐户,但并不反映用户的真实姓名。这些个人信息可以关联到帐户中。
主目录(home):用户登录后默认进入的目录的完整路径。通常将所有用户的主目录放置在 /home/用户名 下。用户一般会将个人文件存放在自己的主目录中,并可在此目录下任意创建子目录。
用户 shell:Shell 提供了用户与操作系统交互的默认环境。市面上常见的 Shell 有很多,有经验的用户会根据自己的使用习惯进行选择。
帐户可以分为三种类型:超级用户、系统用户和普通用户。超级用户帐户通常称为 root,可以不受限制地管理系统;系统用户用于运行服务;普通用户帐户则供日常登录、收发邮件等常规操作使用。
8.3 超级用户帐户
超级用户帐户(通常叫 root)拥有重新配置和管理系统的全部权限。但请注意:在日常收发邮件、系统检查或编程时,应尽量避免使用 root 权限。
原因很简单:普通用户出错不会破坏系统,而超级用户具有完全控制权,一个细微的误操作就可能引发严重后果。因此,日常应使用普通帐户,仅在需要额外特权时切换到 root。
此外,使用超级用户帐户时务必反复检查命令——多一个空格或少一个字符都可能导致数据丢失。
本章首先建议:平时创建一个没有特权的用户帐户。无论你是在多用户环境还是单用户环境中工作,这条建议都适用。后续我们将讨论如何创建更多帐户,以及在普通用户和超级用户之间切换的方法。
8.4 系统帐户
系统用户是用于运行 DNS、邮件、Web 等服务的专用帐户。采用专用帐户的原因是为了安全——如果所有服务都以超级用户身份运行,那么它们就能不受限制地进行任何操作。常见的系统用户包括 daemon、operator、bind 或 news。系统管理员也经常创建 httpd 帐户来运行 Web 服务器。
nobody 是一个没有特权的普通系统用户。但要注意,许多与用户紧密相关的服务都使用 nobody,这反而可能使 nobody 拥有相当大的“特权”。记住这一点很重要。
8.5 用户帐户
用户帐户是真实用户访问系统的主要途径。这些帐户将用户与环境隔离,既能防止用户损坏系统或其他用户的工作,又能让每个人在不影响他人的前提下定制自己的环境。
每个访问系统的人都应拥有自己唯一的帐户。这样既能追踪每个人的操作记录,也能防止他人擅自修改设置、阅读邮件等。
每个用户都可以自行配置环境,例如选择不同的 Shell、编辑器、键盘绑定、语言等,以适应个人使用习惯。
8.6 修改帐户
在 UNIX 环境下,处理用户帐户的命令有不少。前面表格中列出了最常用的几个命令,下面我们详细说明每个命令的具体用法。
8.6.1 增加用户
adduser 是一个简洁的添加新用户命令。它会为用户创建 passwd 和 group 文件条目,新建用户主目录,从 /usr/share/skel 复制默认配置文件(即“dotfiles”),最后还会向新用户发送一封包含欢迎信息的邮件。
若要创建初始配置文件,可运行 adduser -s -config_create。直接为普通用户创建 root 帐户风险较大,因此我们先配置 adduser 的默认设置,然后再创建第一个用户帐户。
例 8-1,配置 adduser
# adduser -v Use option "-silent" if you don't want to see all warnings and questions. Check /etc/shells Check /etc/master.passwd Check /etc/group Enter your default shell: csh date no sh tcsh zsh [sh]: zsh Your default shell is: zsh -_ /usr/local/bin/zsh Enter your default HOME partition: [/home]: Copy dotfiles from: /usr/share/skel no [/usr/share/skel]: Send message from file: /etc/adduser.message no [/etc/adduser.message]: no Do not send message Use passwords (y/n) [y]: y Write your changes to /etc/adduser.conf? (y/n) [n]: y Ok, let's go. Don't worry about mistakes. I will give you the chance later to correct any input. Enter username [a-z0-9_-]: jru Enter full name []: J. Random User Enter shell csh date no sh tcsh zsh [zsh]: Enter home directory (full path) [/home/jru]: Uid [1001]: Enter login class: default []: Login group jru [jru]: Login group is "jru". Invite jru into other groups: guest no [no]: wheel Enter password []: Enter password again []: Name: jru Password: **** Fullname: J. Random User Uid: 1001 Gid: 1001 (jru) Class: Groups: jru wheel HOME: /home/jru Shell: /usr/local/bin/zsh OK? (y/n) [y]: y Added user "jru" Copy files from /usr/share/skel to /home/jru Add another user? (y/n) [y]: n Goodbye! #
总的来说,我们将默认 Shell 设置为 zsh(该 Shell 可在 ports collection 中找到),并关闭了欢迎邮件。随后保存配置,接着创建用户 jru,并确保 jru 属于 wheel 组(以便使用 su 切换到 root)。
注意:输入口令时屏幕不会显示,仅显示星号。请确保两次输入的口令一致。从现在起,每次使用 adduser 时,无需再更改默认设置。如果程序要求改变默认设置,请先退出,然后添加 -s 选项重新运行。
8.6.2 rmuser
你可以使用 rmuser 从系统中彻底删除一个用户。该命令会执行以下步骤:
- 删除用户的 crontab 记录。
- 删除属于用户的 at 任务。
- 终止属于用户的所有进程。
- 删除本地口令文件中该用户的条目。
- 删除用户的主目录。
- 删除
/var/mail中属于用户的邮件。 - 删除
/tmp等临时文件存储区中属于用户的文件。 - 最后,在
/etc/group中删除所有包含该用户的组条目。
注意:如果某个组因此变成空组,且组名与用户名相同,则该组会被自动删除。此外,rmuser 不能用于删除超级用户帐户。
例 8-2. rmuser 交互式删除
# rmuser jru Matching password entry: jru:*:1000:1000::0:0:J. Random User:/home/jru:/usr/local/bin/tcsh Is this the entry you wish to remove? y Remove user's home directory (/home/jru)? y Updating password file, updating databases, done. Updating group file: trusted (removing group jru-personal group is empty) done. Removing user's incoming mail file /var/mail/jru: done. Removing files belonging to jru from /tmp: done. Removing files belonging to jru from /var/tmp: done. Removing files belonging to jru from /var/tmp/vi.recover: done. #
8.6.3 chpass
chpass 可用来修改用户的口令、Shell 以及个人信息等数据库内容。只有超级用户才能更改其他用户的信息。如果不带参数运行,chpass 会打开一个编辑器,显示当前用户的数据库信息,供你修改。
例 8-3. 以超级用户身份交互式执行 chpass
#Changing user database information for jru. Login: jru Password: * Uid [#]: 1000 Gid [# or name]: 1000 Change [month day year]: Expire [month day year]: Class: Home directory: /home/jru Shell: /usr/local/bin/tcsh Full Name: J. Random User Office Location: Office Phone: Home Phone: Other information:
普通用户只能修改自己帐户信息中的部分字段。
例 8-4. 以普通用户身份交互式执行 chpass
#Changing user database information for jru. Shell: /usr/local/bin/tcsh Full Name: J. Random User Office Location: Office Phone: Home Phone: Other information:
注意:chfn 和 chsh 实际上是 chpass 的符号链接。同样地,ypchpass、ypchfn 和 ypchsh 也是类似的链接。NIS 支持是自动集成的,因此无需在命令前特意加 yp 前缀。如果你仍感困惑,别着急,第 17 章会详细讲解 NIS。
8.6.4 passwd
passwd 是更改用户口令的常用方法——普通用户可更改自己的口令,超级用户可更改任何用户的口令。
注意:修改口令前,用户必须先输入旧口令。这样即使你离开控制台,他人也无法未经认证就更改你的口令。
例 8-5. 更改你自己的口令
% passwd Changing local password for jru. Old password: New password: Retype new password: passwd: updating the database... passwd: done
例 8-6. 更改另一个用户的口令
# passwd jru Changing local password for jru. New password: Retype new password: passwd: updating the database... passwd: done
注意:与 chpass 类似,yppasswd 也只是 passwd 的符号链接,所以在 NIS 环境下使用哪个命令效果一样。
8.6.5 pw
pw 是一个命令行工具,用于创建、删除、修改和显示用户及组,同时兼具编辑系统用户和组文件的功能。它的命令行选项非常强大,但对于新手来说可能比其他命令稍显复杂。
8.7 受限制的用户
如果你运行一个多用户系统,并且对某些用户不放心,担心他们可能做出损害系统的操作,FreeBSD 提供了限制用户访问系统资源的方法。这些限制主要分为两类:磁盘配额和其他资源限制。
磁盘配额:允许系统管理员告诉文件系统每个用户可以使用多少磁盘空间。它还能快速检查用户已使用的空间,无需手动计算。配额将在第 12.5 节中讨论。
其他资源限制:包括限制 CPU 时间、内存数量以及用户可能消耗的其他资源。这些限制通过登录类(login class)来实现,下面继续介绍。
登录类由 /etc/login.conf 文件定义。具体细节超出了本章范围,但 login.conf 的联机手册中有详细说明。
资源限制与普通的登录限制有所不同。首先,每种限制都有软限制和硬限制之分:软限制可以被用户或应用程序调整,但不能超过硬限制;之后只能降低,不能升高。其次,大多数资源限制是针对每个用户进程分配的。
以下是常见的资源限制示例:
- coredumpsize:程序产生的核心文件大小限制。核心文件不会自动消失,用户也常忘记删除它们,设置此参数可避免因大型应用崩溃导致大量磁盘空间被浪费。
- cputime:用户程序能消耗的最大 CPU 时钟时间。不正常的进程会被内核杀死。注意:这个限制是 CPU 耗时的时钟限制,而不是
top或ps中显示的 CPU 使用百分比。 - filesize:用户能处理的单个文件的最大值。与磁盘配额不同,这个限制是针对单个文件强制执行的。
- maxproc:用户能运行的最大进程数(包括前台和后台进程)。显然不能超过系统设定的上限。设置太小会影响用户工作——例如需要多次登录或执行多个管道,一些任务(如编译大型程序)会生成很多进程。
- memorylocked:一个进程能锁定到主内存中的最大内存数量。像
amd这类大型程序遇到问题时,巨大的交换量可能无法及时处理。 - memoryuse:一个进程在给定时间内能消耗的最大内存数量(包括核心内存和交换内存)。这不是完全的限制,但是一个很好的起点。
- openfiles:一个进程能打开的最大文件数。在 FreeBSD 中,文件也可以代表套接字和 IPC 通道。注意不要设置得过小。更深层的限制由
kern.maxfilessysctl 定义。 - sbsize:网络内存数量的限制。通常用于限制网络通信,也能防止通过创建大量套接字发起的简单 DoS 攻击。
- stacksize:一个进程堆栈能到达的最大值。不能单独限制内存使用,需要与其他限制配合。
设置资源限制时,还需注意以下几点:
- 系统启动的进程会被分配到守护程序(daemon)的登录类。
/etc/login.conf文件为大多数限制提供了合理配置,但只有你——系统管理员——才清楚什么对你的系统最合适。设置过高可能让系统被滥用,设置过低则会影响处理效率。- X 视窗系统的用户通常比其他人消耗更多资源。X11 本身就需要不少资源,而且它允许用户同时运行更多程序。
- 记住:很多限制是针对单个进程的,而非所有用户。例如,将
openfiles设为 50,意味着用户运行的每个进程最多打开 50 个文件,但用户能打开的文件总数是maxproc乘以openfiles的结果。这也会影响内存消耗。
关于资源限制和登录类的更多信息,可参考联机手册:cap_mkdb、getrlimit、login.conf。
8.8 私有化用户
本地化(localization)是由系统管理员或用户设置的环境,用于调整语言、字符集、时间标准等。第 13 章“本地化 - I18N/L10N 使用与设置”会详细讨论这些内容。
8.9 组
组其实就是一组用户的列表。组通过组名和组 ID 来识别。在 FreeBSD(以及其他大多数 Unix 系统)中,内核决定一个进程是否有权执行某项操作时,会检查它的用户 ID 以及它所属的组列表。注意:用户 ID 只有一个,但一个进程可以关联多个组。你可能听说过“组 ID”这个词,在大多数情况下它指的是组列表中的第一个组。
组名与组 ID 的对应关系定义在 /etc/group 文件中。这是一个以冒号分隔的文本文件:第一部分是组名,第二部分是加密的口令,第三部分是组 ID,第四部分是用逗号分隔的成员列表。你可以手动编辑这个文件(具体语法参考 group 联机手册)。当然,也可以使用 pw 命令来添加和编辑组。
例如,要添加一个名为 teamtwo 的组:
例 8-7. 使用 pw 添加一个组
# pw groupadd teamtwo # pw groupshow teamtwo teamtwo:*:1100:
上面的 1100 就是组 teamtwo 的组 ID。目前该组没有成员,因此没什么作用。
接下来,使用 pw 向组中添加成员:
例 8-8. 使用 pw 在组中添加成员
# pw groupmod teamtwo -M jru # pw groupshow teamtwo teamtwo:*:1100:jru
-M 参数用于指定一个逗号分隔的成员列表。注意,口令文件中每个用户也会有一个对应的组,当使用 pw 查询组成员时,口令文件中的那个组会自动加入列表,但不会出现在 /etc/group 的成员列表中。要查看用户属于哪些组,可以使用 id 命令:
例 8-9. 使用 id 查看组成员
% id jru uid=1001(jru) gid=1001(jru) groups=1001(jru),1100(teamtwo)
可以看到,用户 jru 同时属于组 jru 和 teamtwo。
关于 pw 的更多信息,请查阅它的联机手册;关于 /etc/group 格式的更多信息,请参考 group 的联机手册。
