Linux系统命令及Shell脚本实践指南
上QQ阅读APP看书,第一时间看更新

第2章 Linux用户管理

2.1 Linux用户和用户组

Linux是一个多用户分时系统,想要使用系统资源,就必须在系统中有合法的账号,每个账号都有一个唯一的用户名,同时必须设置密码。在系统中使用用户的概念,一方面可以方便识别不同的用户,另一方面也可以为用户设置合理的文件权限,为每个用户的数据提供安全保障。另外,为了更灵活地管理用户和控制文件权限,Linux还采用了用户组的概念,这为系统管理提供了极大的便利。本节将具体介绍用户和用户组相关内容。

2.1.1 UID和GID

Linux系统如何区别不同的用户呢?可以很自然地想到,使用不同的用户名应该是一个好主意,就像真实世界中每个人都有名字一样。但“用户名”只是一种方便让人读的字符串,对机器来说是没有意义的。事实上,Linux系统采用一个32位的整数记录和区分不同的用户,这意味着系统可以记录多达40亿个不同的用户。这个用来区分不同用户的数字被称为User ID,简称UID。系统会自动记录“用户名”和UID的对应关系。Linux系统中的用户分为3类,即普通用户、根用户、系统用户。

普通用户是指所有使用Linux系统的真实用户,这类用户可以使用用户名及密码登录系统。Linux有着极为详细的权限设置,所以一般来说普通用户只能在其家目录、系统临时目录或其他经过授权的目录中操作,以及操作属于该用户的文件。通常普通用户的UID大于500,因为在添加普通用户时,系统默认用户ID从500开始编号。

根用户也就是root用户,它的ID是0,也被称为超级用户,root账户拥有对系统的完全控制权:可以修改、删除任何文件,运行任何命令。所以root用户也是系统里面最具危险性的用户,root用户甚至可以在系统正常运行时删除所有文件系统,造成无法挽回的灾难。所以一般情况下,使用root用户登录系统时需要十分小心。

系统用户是指系统运行时必须有的用户,但并不是指真实的使用者。比如在RedHat或CentOS下运行网站服务时,需要使用系统用户apache来运行httpd进程,而运行MySQL数据库服务时,需要使用系统用户mysql来运行mysqld进程。在RedHat或CentOS下,系统用户的ID范围是1~499。下面给出的示例显示的是目前系统运行的进程,第一列是运行该进程的用户。

[root@localhost ~]# ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.0   2072   632 ?        Ss   Oct18   0:00 init [3]
......(略去内容)......
apache    7930  0.0  0.1   9944  2064 ?        S    21:23  0:00 /usr/sbin/httpd

在Linux系统中除了有用户之外,还有“用户组”的概念,不同的用户组同样也是用数字来区分的,这种用于区分不同用户组的ID被称为Group ID,也就是GID。

在下面的例子中,使用ls-l查看文件时,第三列和第四列显示的是这个文件的所有者是用户root,所有组是root组,如果加上了-n参数,第三列和第四列则是用UID和GID来显示的,这里分别是0和0。

[root@localhost ~]# ls-l anaconda-ks.cfg
-rw------- 1 root root 954 Oct  7 21:02 anaconda-ks.cfg
[root@localhost ~]# ls-ln anaconda-ks.cfg
-rw------- 1 0 0 954 Oct  7 21:02 anaconda-ks.cfg

那么,UID和GID又有什么联系呢?事实上,在Linux下每个用户都至少属于一个组。举个例子:每个学生在学校使用学号来作为标识,而每个学生又都属于某一个班级,这里的学号就相当于UID,而班级就相当于GID。当然了,每个学生可能还会同时参加一些兴趣班,而每个兴趣班也是不同的组。也就是说,每个学生至少属于一个组,也可以同时属于多个组。在Linux下也是一样的道理。既然是这样,如何查看自己的UID和GID呢?

要确认自己的UID,可以使用以下id命令来获得:

[root@localhost ~]# id
uid=0(root)gid=0(root)groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel)

要确认自己所属的用户组,可以使用以下groups命令来获得:

[root@localhost ~]# groups
root bin daemon sys adm disk wheel

如果要查询当前在线用户,可在用户登录以后,使用命令who看到目前登录在系统中的所有用户。下面的例子说明当前有3个登录,其中用户root分别从tty1、pts/0登录到系统,而用户john从pts/1登录。

[root@localhost ~]# who
root     tty1         2012-10-22 00:13
root     pts/0        2012-10-22 21:20 (192.168.179.1)
john     pts/1        2012-10-22 22:35 (192.168.179.1)

2.1.2 /etc/passwd和/etc/shadow

前面已经说明,在登录Linux时必须要输入用户名和密码。而系统用来记录用户名、密码最重要的两个文件就是/etc/passwd和/etc/shadow。以下是/etc/passwd中的几行内容:

[root@localhost ~]# cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
......(略去内容)......

可以看到,虽然每行的内容不一样,但格式却是一致的,即每行都是使用6个分隔号“:”隔开的7列字符串。每一列所代表的含义如表2-1所示。

表2-1 etc/passwd内容格式说明

从表2-1中可以了解到,/etc/passwd的第二列最早是在UNIX系统中用于记录密码的,但是这其中存在一个问题:由于每个用户都需要有读取这个文件的权限,而随着现代密码破解技术的发展,即便是加密的密码,也有被破解的可能,所以将密码从这个文件中剥离出去是非常必要的。

目前Linux的做法是,将密码相关的信息保存到/etc/shadow中,而且默认只有root用户才有读的权限,其他人完全没有读取这个文件的可能。这种密码保存方式被称为“影子密码”。看一下/etc/shadow中的第一行内容:

[root@localhost ~]# cat /etc/shadow
root:$1$JjIvgikC$YjiVyo3wVahvrwr0IETTV/:15620:0:99999:7:::
......(略去内容)......

与/etc/passwd类似,/etc/shadow也是由冒号“:”隔开的,不同的是这里是8个冒号隔开的9列。每一列代表的含义如表2-2所示。

表2-2 /etc/shadow内容格式说明