账号安全也是系统安全的一项关键性的决定因素。不常用的账号,以及采用了很容易被猜中的口令的账号,都是黑客攻击的主要目标。在这一章里,我们首先研究自动工具所实现的下层模型,然后介绍工具本身(useradd,userdel等)。系统提供的默认工具 useradd 实际用起来相当不错,应该能够满足站点的大多数需求。遗憾的是,useradd 却没有我们希望的那样好。
1 /etc/passwd 文件
/etc/passwd 文件是系统能够识别的用户的一份清单。在用户登录期间,系统查询这个文件,确定用户的 UID 并验证用户的口令。这个文件中的每一行代表一个用户,它包含 7 个由冒号分隔的字段。
- 登录名
- 经过加密的口令或者口令占位符
- UID 号
- 默认的 GID 号
- “GECOS”信息:全名、办公室、分机号、住宅电话
- 主目录
- 登录 shell
举个例子:
下面各小节中将更详细地讨论 /etc/passwd 中的字段。
1.1 登录名
登录名(也叫做用户名)必须是唯一的,它的长度一般不超过 32 个字符。代表的是登录到主机上的用户的所使用的名称。
1.2 加密的口令
目前大多数系统实际上把加密后的口令放在 /etc/shadow 而不是 /etc/passwd 文件里。但不管实际情况下口令到底保存在哪里,本节讨论的内容都适用。
/etc/shadow 文件以加密的形式保存口令。通过 passwd 命令来设置这个字段的内容,或者从另外一个账号中复制加密后的口令字符串。
如果通过手工编辑 /etc/passwd 文件来创建一个新账号,那么要在加密口令字段添一个星号或者一个 x 以防止在设置一个真实口令之前发生未经授权使用该账号的情况。千万不要让这个字段为空——那样会引入一个大大的安全漏洞,因为不需要口令就能访问这个账号。
目前大多数的 Linux 发行版本默认使用 SHA-512 算法来加密口令,在我所测试的 Ubuntu 10.10 和 Fedora 17 发行版本上均采用的是 SHA-512 加密算法。SHA-512 口令很容易辨认,因为它们总是以 $6$ 开头。在加密口令的过程中会随机掺入“salt”,这样一来,同一个口令可以对应许多不同的加密后的形式。如果"salt"是以"$id$"开头的,例如:
那么并非使用 DES 标准加密算法,而是使用 id 号所标识的加密算法,各个 id 所代表的加密算法如下表所示:
ID | 加密算法 |
---|---|
1 | MD5 |
2a | Blowfish(SUSE 发行版本所使用) |
5 | SHA-256 (since glibc 2.7) |
6 | SHA-512 (since glibc 2.7) |
所以 $5$salt$encrypted 代表的就是一个 SHA-256 加密串,而 $6$salt$encrypted 代表的是一个 SHA-512 加密串。
1.3 UID 号
UID 是 32 位无符号整数。然而,因为和老系统之间的互操作性问题,我们建议在可能的情况下将站点上的最大 UID 号限制为 32767(最大的 16 位有符号整数)。
按照定义,root 的 UID 号为 0。大多数系统还定义虚拟用户 bin、daemon 以及其他一些用户。习惯上将这些虚拟登录名放置在 /etc/passwd 文件的开关部分,并且给予它们比较小的 UID 号。为了能够给将来可能添加的任何非真实用户提供足够的空间,我们建议从 500(或更大)开始分配真实用户的 UID 号。
1.4 默认的 GID 号
和 UID 类似,组的 ID 号是一个 32 位的整数。GID 0 是给名为“root”的组保留的。GID 1 通常指的是名为“bin”的组,GID 2 指的是“daemon”的组,但不一定总是这样,在 Ubuntu 发行版本上,GID 1 指的是“daemon”组,GID 2 指的是“bin”组。
1.5 GECOS 字段
GECOS 字段通常用来记录每个用户的个人信息。它的语法定义不明确,GECOS 字段最初是用来保存登录信息的,在把批处理作业从贝尔实验室中的 UNIX 系统传送到运行 GECOS(代表 General Electric Comprehensive Operating System)的大型机时需要这些登录信息,现如今只留下了 GECOS 这个名字而已。
1.6 主目录
当用户登录之后,他们的 shell 就进入到自己的主目录中。如果在登录时找不到用户的主目录,那么系统会显示诸如“no home directory”这样的信息。如果把 /etc/login.defs 中的 DEFAULT_HOME 设为 no,那么就会禁止没有主目录的用户登录;否则会允许登录,并且让用户处在根目录下。
1.7 登录 shell
虽然登录 shell 一般是像 Bourne shell 或者 C shell(/bin/sh 或者 /bin/csh)那样的命令解释程序,但是它可以是任何程序。bash 是默认的 shell,如果 /etc/passwd 没有指定一个登录 shell,那么就用它。
2 /etc/shadow 文件
只有超级用户才能读 /etc/shadow 文件,它用来保护加密口令的安全。在使用了隐蔽口令系统的情况下,/etc/passwd 文件中原来的口令字段一定要包含一个 x。
shadow 文件并不是 passwd 文件的超集,而 passwd 文件也不是从它产生的,管理员必须两个文件都维护(或者使用诸如 useradd 这样的工具来自行维护)。和 /etc/passwd 类似,/etc/shadow 文件也是给每个用户一行,每行有 9 个用冒号分隔的字段:
- 登录名
- 加密后的口令
- 上次修改口令的时间
- 两次修改口令之间最少的天数
- 两次修改口令之间最多的天数
- 提前多少天警告用户口令即将过期
- 在口令过期之后多少天禁用账号
- 账号过期的日期
- 保留字段,目前为空
唯独要求非空的字段是用户名和口令。/etc/shadow 中指定的绝对日期是从 1970 年 1 月 1 日至今的天数(不是秒数),这不是 UNIX 系统上估算时间的标准方法。一个典型的 shadow(隐蔽口令文件)看上去类似于:
2S6C.l16.XrbvP.2rmnZtZ4s1X.:15512:0:99999:7:::
系统管理员可以通过使用
查看上次修改口令的时间。也可以使用工具 pwconv 让 shadow 文件的内容和 passwd 文件的内容保持一致,补上任何新加的用户,删除不在 passwd 中列出的用户。pwconv 会用 /etc/login.defs 里指定的默认值填充 shadow 文件里大多数的隐蔽参数。
3 /etc/group 文件
/etc/group 文件包含了 UNIX 组的名称和每个组中成员的列表。例如:
csstaff:x:100:lloyd,evi
student:x:200:dotty
每一行都代表了一个组,其中包含有 4 个字段;
- 组名
- 加密的口令或者包含一个 x 表明有一个 gshadow 文件
- GID 号
- 成员列表,彼此用逗号隔开(注意不要加空格)
在我所测试的发行版本中都配置有 /etc/gshadow 文件,它的概念和 /etc/shadow 文件类似,但是却没有那么重要(组的口令很少使用)。
4 添加用户
通常,添加一个新用户的过程包含系统要求的 4 个步骤,两个步骤用来为新用户建立一个有用的环境,还有其他几个步骤用来为管理员自己提供更多便利。系统所需的步骤:
- 编辑 /etc/passwd 和 /etc/shadow 文件,定义账号
- 把用户添加到 /etc/group 文件里
- 使用 passwd 设置一个初始口令
- 创建用户主目录,用 chown 和 chmod 命令改变用户主目录的属主和属组
为用户所进行的步骤:
- 将默认的启动文件复制到用户的主目录中
- 设置用户的邮件主目录并建立邮件别名
为管理员准备的步骤:
- 核实账号是否设置正确
- 将用户的联系信息和账号状态加入数据库
您必须以 root 的身份来执行每一步骤,或者也可以使用诸如 sudo 这样让您以 root 身份来执行命令的程序。
4.1 创建用户的主目录
系统管理员创建的任何目录最初都由 root 所有,所以必须使用 chown 命令修改它的属主和属组。下面这一系列命令将为我们举例的用户创建一个合适的主目录:
$ sudo chown tyler:staff /home/tyler
$ sudo chmod 700 /home/tyler
4.2 复制默认启动文件
通过将配置文件放置到用户的主目录中,可以对一些命令和工具进行定制。启动文件一般都是以圆点(.)开关,以字母 rc(“run command”的缩写)结尾,这是 CTSS 操作系统留下的”遗迹“。除非 ls 使用 -a 选项,否则开头的圆点让 ls 在显示的目录列表中不显示这些文件,这些文件被认为是”不感兴趣的“。下表列出了一些常见的启动文件:
命令 | 文件名 | 典型的用途 |
---|---|---|
bash | .bashrc | 设置启动环境 |
vim | .vimrc | 设置 vim 编辑器的选项 |
emacs | .emacs | 设置 emacs 编辑器的选项 |
.mailrc | 定义个人邮件别名 |
如果还没有一组不错的默认启动文件,那么也可以使用发行版在 /etc/skel 下提供的文件,把它们作为修改的起点。还要保证给新用户的 umask 设置一个合理的值(建议采用 077、027 或者 022,具体是哪一个取决于站点的友好性和规模)。
5 删除用户
当某个用户离开您的单位时,应该从系统中删除该用户的登录账号和文件。如果需要手工删除一个用户,可能需要对照下面的步骤来做:
- 将用户从所有本地用户数据库中删除
- 将用户从 aliases 文件中删除,或者添加一个转发地址
- 删除用户的 crontab 文件和所有挂起的 at 作业
- 终止所有仍在运行的用户进程
- 将用户从 /etc/passwd, /etc/shadow, /etc/group 和 /etc/gshadow 文件中删除
- 删除用户的主目录
- 删除用户的邮件存储文件
6 账号管理工具
useradd 命令把用户添加到 passwd 文件中去(如果可以的话还会添加到 shadow 文件中去)。它提供了一个命令行驱动的接口,很容易通过手工运行或从自制的 adduser 脚本调用。usermod 命令可以改变已有用户在 passwd 文件中的条目。userdel 命令可以将用户从系统中删除,还可以删除用户的主目录。groupadd、groupmod 和 groupdel 命令也可以对 /etc/group 文件进行操作。
例如,为了用 useradd 命令(使用系统的默认设置)创建新用户 hilbert,只需运行:
这条命令将在 /etc/passwd 文件中创建下面的项
需要说明的是,useradd 在口令字段中旋转了一个星号,直到您指派一个真实的口令之前,它都能有效地禁用该账号。
当给出其他参数的时候,useradd 往往会更有用。在下面的例子中,我们指定 hilbert 的主属组为“faculty”,而且还应该把他加入到“famous”组里。我们也重新指定了默认的主目录位置,如果目录不存在,还要让 useradd 创建它:
-G famous -m -s /bin/sh hilbert
这条命令在 passwd 文件中创建了这么一条:
(指派的 UID 比系统上最大的 UID 大 1)在 shadow 文件中相应的项为:
它还在 /etc/group 中将 hilbert 添加到“faculty”组和“famous”组中,还创建 /home/math/hilbert 目录,并按照 /etc/skel 的山窝在这个目录下增加若干初始配置文件。
usermod 命令用来修改已经存在的账号,并且使用了很多和 useradd 命令一样的标志。例如,我们能够使用下面的命令将 hilbert 账号的作废日期设为 2013 年 7 月 4 日:
userdel 命令删除用户账号,并且取消 useradd 命令所做的全部修改。要删除 hilbert 这个账号,我们可以使用下面的命令:
这条命令删除了 passwd、shadow 和 group 文件中与 hilbert 相关的资料。默认情况下,它不会删除 hilbert 的主目录。-r 选项让 userdel 也删除用户的主目录。