
一个缺乏全的的系统就不是一个系统。如何保证文件不被非法浏览和修改是一个操作系统最基本的要求。Linux 在这方面有着很高的口碑,当然也得益于他有一个巨人肩膀可以站立---Unix。Linux 对文件权限管理沿用了 Unix 的方案,通过用户、组以及文件和目录的授权来控制特定用户对特定文件访问限制的。接下来我会用几篇文章详细讲解一下 LInux 系统是如何做权限管理的。
Linux 的安全系统是以用户账户为核心的,用户本身具有的权限决定了用户登陆后对系统文件的访问权限。
用户的信息藏在哪?
/etc/passwd 文件记录着用户的信息, 如图

图1
图中可以看到 root 是系统管理员账户,拥有者最高的权限,还包括系统账户,例如daemon,这些这户不是真正意义上的账户,不能用作登录账户,是Linux为了运行某些特定服务而创建的特殊账户,就像 Windows 的 SYSTEM, MSA账户一样。追溯这段历史还是蛮有趣的,在最开始安全问题还没有爆发出来之前,这些系统通服务都是用 root 账号登录的,这就有个隐患,如果某个进程被攻破,获得这个进程的权限,从而获得了root权限,那么整个系统也就完全被暴露了。所以用特定的账户启动特定的服务,这样即使某个服务被攻破,也不至于让整个系统都被抢占。
passwd 文件中存储的每条用户信息包含7个字段,用 ":" 分隔,下面以第一条信息为例逐一解释一下每项的具体含义:
root:x:0:0:root:/root:/bin/bash
- root: 代表登录用户名,Linux 系统 root 用户具有最高权限;
- x:代表用户密码,此处并不是真是的密码,真正的密码被加密后存储在/etc/shadow中,关于shadow 稍后讲解。
- 0:代表用户ID(UID)
- 0:代表用户组ID(GID)
- 用户的文本描述或备注,例如可以记录用户的电话,地址等信息
- 用户的 HOME 目录
- 用户登录后默认启动的shell 类型。
/etc/shadow 不能说的秘密
其实早期的密码确实是加密后存储在/etc/passwd文件中的,但是因为这个文件经常需要被程序访问,后来就出现了很多不务正业的的人热衷于从事破解密码的勾当,所以后来就将密码存储在了/etc/shadow中,而且提高了 shadow文件的访问权限,只有特定的程序才能访问,例如登录程序,从而保证了密码的安全。

图2
shadow文件中包含9个字段,如图
- root: 与 /etc/passwd 中登录用户名对应的登录名
- "$6...1VO1": 用户加密后的密码
- 17971:上次修改密码后过去的天数(从1970.1.1开始计算)
- 0:多少天后才能更改密码,0表示随时可以修改
- 99999:多少天后必须修改密码,此处表示永不过期
- 7:表示提前多少天提醒用户更换密码
- 7、8、9字段为空值,一次表示密码过去后多少天禁用账户、账户被禁用的日期、预留字段。
账户管理
关于账户管理,之前的文章已经简单介绍过,此处再详细的讲解一下:
1. 添加账户 (useradd 命令)
使用 useradd 命令创建账户时,如果没有指定属性参数,系统会默认给用户创建一些属性,这些默认属性可以通过"useradd -D" 来查看;

图3
- GROUP=100:新建用户会被默认添加到GID为100的公共组。
- HOME=/home:新用户的HOME目录会位于/home/username 下(会在/home下创建一个与用户名同名的目录)
- INACTIVE=-1:密码过期后不会被禁用
- EXPIRE 没有设置过期日期
- SHELL=/bin/sh:用户默认启用的shell
- SKEL=/etc/skel:创建用户后,会将/etc/skel下的文件拷贝到HOME目录下,注:adduser 命令默认并不会创建HOME目录,需要附加 "-m" 参数
- CREATE_MAIL_SPOOL=no:系统不会在mail目录下创建用于接受邮件的文件。
2.删除用户 (userdel 命令)
userdel [-r][用户帐号] -r 删除用户HOME目录以及目录中所有文件。 注:使用-r 参数时,确保用户的HOME目录下没有其他重要文件。
3.修改用户信息

图4
说明一点,passwd 修改密码时有个原则:任何用户都有权限修改自己的密码,但是如果想修改其他账户的密码,只能通过root账户。修改用户信息前后,可以通过 finger 工具去查看用户的详细信息。

图5
Linux 用户组(group)
和 Windows 用户组相同,通过用户组授权,从而使组内的所有成员具有相同的权限,极大方便了多个用户的管理,那么具体的组信息保存在哪里呢?
/etc/group 文件

图6
group 文件有4个字段, 以adamg 为例:
- adamg: 组名称
- x: 组密码
- 1005: GID
- "adam2,adam3"隶属改组的用户成员列表
1.创建新组(groupadd)
2.修改组属性(groupmod)
groupmod [-g <群组识别码> <-o>][-n <新群组名称>][群组名称] -g <群组识别码> 设置欲使用的群组识别码。 -o 重复使用群组识别码。 -n <新群组名称> 设置欲使用的群组名称。
文件权限才是灵魂
用户其实只是授权的载体,权限的真正主体是文件,一个文件通过将自身不同的权限赋予用户和组才真正实现了一个用户对文件和目录的访问权限控制。说简单一点,就是文件决定了一个用户能否对它进行读写和执行等权限。在《初识 Shell(1)》中,我们讲解过文件权限的含义,不了解的可以翻看查阅。此处我们在那篇文章的基础上,再深入讲解一下。
谁规定了文件的默认权限?
我们创建一个文件后,发现该文件已经默认具备了一些权限,例如

图7
新创建的文件 my_file 已经具备了权限,而决定这个默认权限的是 "umask" 我的环境中 umask值为022,这和默认的权限有什么关系呢?这里我们要介绍一下权限的另一种表示方法:8进制表示法。《初识 Shell(1)》我们介绍过,文件将自身的权限以字母"r,w,x,-"表示,

图8
我们将权限 "rwx" 三位占位符用二进制数字占位表示"000"分别代表读权限、写权限、执行权限。如果对应位具有权限,我们就将该位置为 "1",否则置为 "0"。例如权限 "rw-"转换为二进制表示为"110"(也就是8进制的4+2+0=6)。所以图7中my_file权限"rw-r--r--"就可以按照8进制表示为"644", 但是这和umask "022" 又有什么联系呢?其实从 umask 名字可以看出,它是一个掩码,文件的默认权限是通过文件的最高权限值与umask 相减得到的。对于文件而言最高权限是"rw-rw-rw- "也就是8进制的"666",对于目录而言最高权限是"rwxrwxrwx "等于8进制的"777",所以图7中文件my_file的默认权限就是"666"与"022"对应位相减得到"644",转换成字母表示即"rw-r--r-- "。此处稍微有点绕,希望仔细阅读,对于文件权限的深刻理解还是有帮助的,有讲解不清楚的地方,欢迎大家留言,我会针对问题认真回复,希望能帮到有需要的人。
改变权限,改变世界
常用修改权限的命令

图9