第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内容格式说明