从Windows系统转到Linux以后,在很长一段时间里,我对Linux的文件系统安全都是一知半解,对其安全性更是知之甚少。经过几年的使用,终于对其有了较深入的了解。
由于自己的亲身经历,我一直想把相关的内容以比较简单的方式写出来,让Linux初学者可以在短时间内对Linux的文件系统及安全性有一个比较透彻的了解。
不管在什么操作系统中,文件和文件系统都是非常重要的概念。文件可以简单定义为有名字的一组相关信息的集合。在Linux系统中,文件的准确定义是不包含有任何其它结构的字符流。也就是说,文件中字符与字符之间除了同属于一个文件之外,不存在任何其它的关系。文件中字符关系是由使用文件的应用程序来建立和解释的。每一个文件都具有特定的属性。Linux系统的文件属性比较复杂,主要包括文件类型和文件权限两个方面。
文件类型
Linux下的文件可以分为5种不同的类型:普通文件、目录文件、链接文件、设备文件和管道文件。
1.普通文件
这是一类常见的文件,也是常使用的一类文件,其特点是不包含有文件系统的结构信息。通常所接触到的文件,包括图形文件、数据文件、文档文件、声音文件等都属于这种文件。这种类型的文件按其内部结构又可细分为文本文件和二进制文件。
2.目录文件
目录文件是用于存放文件名及其相关信息的文件,是内核组织文件系统的基本节点。目录文件可以包含下一级目录文件或普通。对于习惯于使用Windows的用户来说,这可能有些难于理解,目录怎么会是文件呢?的确,在Linux中,目录文件是一种文件。但Linux的目录文件和其它操作系统中的“目录”的概念不同,它是Linux文件中的一种。当然,在实际使用中可以不仔细区分这两种说法。实际上,在很多Linux的书籍和资料中就是将目录文件简称为目录的。不过,我们必需清楚此“目录”非彼“目录”。
3.链接文件
链接文件是一种特殊的文件,实际上是指向一个真实存在的文件的链接。这有点类似于Windows下的快捷方式。根据链接文件的不同,它又可以细分为硬链接文件和符号链接文件。
4.设备文件
设备文件是Linux中最特殊的文件。正是由于它的存在,使得Linux系统可以十分方便地访问外部设备。Linux系统为外部设备提供一种标准接口,将外部设备视为一种特殊的文件。用户可以像访问普通文件一样访问外部设备,使Linux系统可以很方便地适应不断发展的外部设备。通常Linux系统将设备文件放在/dev目录下,设备文件使用设备的主设备号和次设备号来指定某外部设备。根据访问数据方式的不同,设备文件又可以细分为块设备和字符设备文件。
5.管道文件
管道文件是一种很特殊的文件,主要用于不同进程间的信息传递。当两个进程间需要进行数据或信息传递时,可以通过管道文件。一个进程将需传递的数据或信息写入管道的一端,另一进程则从管道的另一端取得所需的数据或信息。通常管道是建立在调整缓存中。
文件的权限
Linux系统是一个典型的多用户系统,不同的用户处于不同的地位。为了保护系统的安全性,Linux系统对不同用户访问同一文件的权限做了不同的规定。
对于一个Linux系统中的文件来说,它的权限可以分为三种:读的权限、写的权限和执行的权限,分别用r、w和x表示。不同的用户具有不同的读、写和执行的权限。
对于一个文件来说,它都有一个特定的所有者,也就是对文件具有所有权的用户。同时,由于在Linux系统中,用户是按组分类的,一个用户属于一个或多个组。文件所有者以外的用户又可以分为文件所有者的同组用户和其它用户。因此,Linux系统按文件所有者、文件所有者同组用户和其它用户三类规定不同的文件访问权限。
权限的概念
Linux文件系统安全模型是通过给系统中的文件赋予两个属性来起作用的,这两个赋予每个文件的属性称为所有者(ownership)和访问权限(access rights)。Linux下的每一个文件必须严格地属于一个用户和一个组。
图1是在我机器上的/mydoc目录下运行ls -l命令的情况。
图1 文件和文件夹的权限
从上面显示的内容可以注意到,每个文件的目录条目都是以下面类似的一些符号开始:
这些符号用来描述文件的访问权限类别,也就是常说的文件权限。这些访问权限指导Linux根据文件的用户和组所有权来处理所有访问文件的用户请求。总共有10种权限属性,因此一个权限列表总是10个字符的长度。它的格式遵循下列规则:
◆ 第1个字符表示一种特殊的文件类型。其中字符可为d(表示该文件是一个目录)、b(表示该文件是一个系统设备,使用块输入/输出与外界交互,通常为一个磁盘)、c(表示该文件是一个系统设备,使用连续的字符输入/输出与外界交互,如串口和声音设备),“.”表示该文件是一个普通文件,没有特殊属性。
◆ 2~4个字符用来确定文件的用户(user)权限,5~7个字符用来确定文件的组(group)权限,8~10个字符用来确定文件的其它用户(other user,既不是文件所有者,也不是组成员的用户)的权限。其中,2、5、8个字符是用来控制文件的读权限的,该位字符为r表示允许用户、组成员或其它人可从该文件中读取数据。短线“-”则表示不允许该成员读取数据。与此类似,3、6、9位的字符控制文件的写权限,该位若为w表示允许写,若为“-”表示不允许写。4、7、10位的字符用来控制文件的制造权限,该位若为x表示允许执行,若为“-”表示不允许执行。
各个位控制权限的情况如图2所示。
图2 不同的符号位表示不同的权限
任何列在/etc/passwd文件中的用户都可以是一个文件的所有者,也称为该文件的用户。同样任何列在/etc/group文件中的组都可以是文件组的所有者,也简称为文件的组。
下面来看两个例子,以便加深理解。首先来看一看图1中的第一行:
drwxrwxr-- 2 root root 4096 2月 11 10:36 guo |
因为guo的第1个位置的字符是d,所以由此知道guo是一个目录。第2至4位置上的属性是rwx,表示用户root拥有权限列表显示guo中所有的文件、创建新文件或者删除guo中现有的文件,或者将guo作为当前工作目录。第5至7个位置上的权限是rwx,表示root组的成员拥有和root一样的权限。第8至10位上的权限仅是r--,表示不是root的用户及不属于root组的成员只有对guo目录列表的权限。这些用户不能创建或者删除guo中的文件、执行junk中的可执行文件,或者将junk作为他们的当前工作目录。
下面再来看一看图1中的第三行:
-rwxr-xr-- 1 user admin 20480 11月 11 09:23 Readme.txt |
在该项中,第1个位置是短线“-”,表示该文件是一个普通文件,没有特殊属性。该文件对任何人都可读,只对user可写,user和admin的组成员可以执行该文件。
另外需要注意的是,当用户访问一个文件时,权限检查是从左到右的。假设上述的readme.txt文件具有以下权限:
那么即使user是属于admin组的一个成员,也不能对该文件进行写操作,因为已经被左边的写权限设置拒绝了。
修改文件或者目录权限
文件或者目录的用户能够使用chmod命令修改文件的权限。Chmod命令有两种方式:一种是字符方式,使用字符来修改文件的权限;另外一种是数字方式,使用3个数字的组合来修改文件的权限。
字符方式的基本语法是:chmod [ugoa] +或者-或者= [rwx] [文件...]
在上述命令中,使用“+”或者“-”是在保存原来权限设置的基础上修改权限。当使用“=”时,权限被明确地赋予要修改的文件。其中字符u表示文件或者目录的所有者,g表示文件或者目录所属组,o除所有者和所属组以外的用户,a表示全部用户。
数字方式的基本语法是:chmod nnn 文件
其中第1、2、3个n分别表示用户、组成员和所有其它用户。各个位置上的n要么是一个0,或者是一个由赋予权限的相关值相加得到的单个阿拉伯数字之和。这些数字的意义如表1所示。
表1 数字的含义
值 表示的意义
4 表示文件或者目录的读权限
2 表示文件或者目录的写权限
1 表示文件或者目录的执行权限 |
很显然,当使用数字方式时,这3个数字必须为0至7中的一个。
图3和图4是分别使用字符方式和数字方式改变文件权限的例子,两个例子中命令所实现的功能是一一对应的。
图3 使用字符方式改变文件权限
图4 使用数字方式改变文件权限
一般而言,作为系统管理员,更喜欢使用数字方式,因为这种方式的速度明显快得多。
很显然,系统中各种文件的权限设置对特定用户的数据安全有很大影响。但是要求用户逐一明确设置系统中每个文件的权限也是不现实的,为此,需要使用umask命令,该命令可以为用户账号中新文件的创建进行缺省设置。具体来说,umask是用来设置权限掩码的,权限掩码由3个数字组成,将现有的存取权限减掉权限掩码后,即可产生建立文件时默认的权限。例如,root的权限为777,若权限掩码设为022,那么两都相减后可得755。下面是在我的系统更改umask的一些情况:
[root@linuxserver root]# umask
022 |
上述命令显示表示我的系统的umask值为022。
[root@linuxserver root]# umask -S
u=rwx,g=rx,o=rx |
当umask值为022时,默认情况下各用户的权限。注意这里的参数“S”是大写。
[root@linuxserver root]# umask 177
[root@linuxserver root]# umask -S
u=rw,g=,o= |
上述两行命令把umask值改为177,结果只有文件所有者具有读写文件的权限,其它用户不能访问该文件。这显然是一种非常安全的状态。
其它问题
事实上,一个系统中的文件安全是一个综合问题,对于一些特殊的情况要做特殊的考虑。比如,对于设备文件的安全性、SUID/SGID的设置等。
一般来说,各Linux发行版在安装时就已经把设备文件的设置做得非常不错。但是对于磁盘设备而言,我认为惟一安全的还是只允许root用户进行读写。否则,其它用户的账号一旦被攻破,黑客通过访问磁盘很快就可以让系统崩溃。要做到这一点,可以使用以下命令:
#cd /dev
#chmod 600 sd* hd * |
Suid和Sgid是Linux系统中最复杂的属性,它跟一个系统的安全息息相关。我们可以利用chmod命令来清除或者设置一个文件的Suid/Sgid属性,具体方法如下所示。
将/usr/sbin/pppd程序设置为Suid/Sgid状态,使用的命令是:
#chmod ug+s /usr/sbin/pppd |
要清除Sgid状态而保留Suid状态,可用以下命令:
#chmod g-s /usr/sbin/pppd |
此外,如何装载文件系统,特别是将root文件系统装载为只读,以防止非授权的修改也比较重要。
总之,Linux下文件系统的安全问题是一个非常复杂的问题。通过本文的学习,读者对此应该有了一个较全面的了解,并且可以处理日常工作中常见的有关文件系统安全问题。
(作者:葛小明)