面试现场:整理一下 Linux 操作系统中的那些权限
文 | 大白
出品 | CS指南(ID:csguide)
大家好,我是大白。上一篇操作系统专题讲了进程中的几个数据结构,本来今天是轮到讲进程中还没讲的数据结构了。但是开始写进程权限的数据结构时发现和权限相关的知识太多了(我自己也被整糊了)。这个状态去和面试官 battle 可不行。所以就专门拿出一篇文章来写下操作系统中的权限问题,还是以 Linux 为例。相信这篇文章能让大家搞清楚 Linux 中的那些权限,这些知识不论是实际工作还是用来和面试官 battle,都是挺有用的。今天就不以面试的情景来讲述了,知识比较琐碎,整合一下自己的知识,下次再接着和面试官 battle。
Linux 一大优秀的地方就在于它的多人多任务环境。因此权限的管理就变得十分重要。Linux 一般将用户身份分为三个类别,分别是拥有者(owner)、所属群组(group)、其它人(others),这三种用户分别需要赋予读、写、执行的权限。
先说下 Linux的文件属性,尝试在你 Linux 系统任意的文件夹下输入命令 ls -al,可以看到下面这些显示。
dabai@study:~/code$ ls -al
drwxrwxr-x 2 dabai dabai 4096 Nov 26 01:40 pytorchtest
-rw-rw-r-- 1 dabai dabai 702 Mar 9 03:32 requirements.txt
// [权限] [链接] [拥有者] [用户组] 文件容量 修改日期 文件名
每一列对应什么已经在上面注释中列出了,后面主要解析第一列。
Part1文件的权限
第一列第一个字符代表类型,如果是目录(也就是文件夹)就是 d
;如果是文件,就是-
;如果是链接文件,就是 l
。比如 requirements.txt
就是一个文件,对应的 -rw-rw-r--
第一位就是 -
.
第二个字符到第四个字符代表文件拥有者得权限,-rw-rw-r--
的第二到第四个字符分别是 rwx
。对于文件来说,对应关系如下。
r(read) :可读。可读取文件的实际内容。
w(write):可写。可编辑、新增或是修该文件的内容。
x(execute):可执行。该文件具有被系统执行的权限。
如果具备对应权限,相应位置上就是对应得字符。如果不具备对应权限,相应位置就是 -
。
第五个字符到第七个字符代表用户组的权限。这里对应的权限也是可读、可写、可执行,就不重复讲了。可能有的同学不知道啥是用户组,这里简单讲一下。一般情况下,root 具备最高权限,普通用户对于自己拥有的文件有最高权限。但是刚才不是也说了吗?Linux 一大优秀的地方就在于它的多人多任务环境。为了协同工作,可以把需要协同工作的用户放在一个用户组,可以给与在用户组中的用户更多的权限。
第八到十个字符代表的是其它用户权限。也对应的是可读、可写、可执行。一般情况下给其它用户可读的权限就可以了。
Part2目录的权限
上面 列表中 pytorchtest
对应的是一个文件夹,也就是目录。所以权限处 drwxrwxr-x
第一个对应的字符是 d
。后面部分也分别对应着用户、用户组、其它用户的权限。目录在 rwx
的权限解释上和文件有一些差异。具体如下:
r(read) :可读。可读取目录结构列表
w(write):可写。增删改文件目录以及其中文件。
x(execute):可执行。可进入目录。如果没有目录x的权限,即使有 r (可读权限)也无法进入目录。
1如何修改权限
对于修改权限,Linux 可以用这三种命令来修改权限。
chgrp : 是
change group
的缩写,修改文件所属用户组。chown : 是
change owner
的缩写,修改文件拥有者。chmod :修改文件的权限。
具体命令怎么用,csdn 上有很多,我就不再赘述了。重点还是讲后面进程的权限。
Part3进程的权限以及数据结构
大家现在思考一个很典型的场景:Linux 中的用户信息是保存在 /etc/passwd
中的。当我们想要修改用户密码时,我们应该怎么做?(目前密码是存在 /etc/shadow
下的,但再去讲解 /etc/passwd
和 /etc/shadow
的关系担心讲乱了,我们就先把要修改的密码当作存在 /etc/passwd
下。其实早期的 Linux 系统也确实用户信息和密码是存在一个文件下的)
好了,首先我们考虑 /etc/passwd
, 这么核心的文件,肯定只有 root 用户有写的权限。如果一个普通用户具备写/etc/passwd
的权限,把别人密码改了就乱了套了。但是问题来了,/etc/passwd
下存放着所有用户的信息,普通用户自己的密码也会在这个文件下。普通用户有时候也是需要改自己的密码,既然要改自己密码,不具备写入的权限就无法修改密码。
为了解决这个问题,我们想想应该怎么做?我们可能需要一个进程,这个进程普通用户有可执行的权限就可以,但是执行的时候,希望这个进程具有和 root 用户一样读写的权限,这样这个进程便可以修改/etc/passwd
中用户的密码。但我们也希望这个进程仅仅是在执行时具有 root 权限。具体要怎么做呢?我们来看下面进程中这个数据结构。
struct cred {
kuid_t uid; //real UID of the task
kgid_t gid; //real GID of the task
kuid_t suid; //saved UID of the task
kgid_t sgid; //saved GID of the task
kuid_t euid; //effective UID of the task
kgid_t egid; //effective GID of the task
kuid_t fsuid; //UID for VFS Ops
kgid_t fsgid; //GID for VFS Ops
}
其中
uid
和gid
代表着是谁启动的这个进程,uid
是用户id
,gid
是用户组id
。
suid
和sgid
保存着程序拥有用户的uid
和gid
。比如操作系统下有两个用户,一个是 root,一个是常规账户。程序是属于root的,常规用户在执行这个程序时,uid
和gid
就是自己的id
,但suid
和sgid
会保存着 root 账户的id
。
euid
和egid
是用来判断一个用户或组是否对进程具有权限的。
fsuid
和fsgid
用来判断用户是否对文件操作具有权限。
一般情况下 这几种用户的 id 都是一样的,用户组的 id 也是一样的。但是出现如上所述的普通用户想改自己密码的情况,就需要一些变化了。操作系统在判断进程是否具备某些权限时,也是拿进程的 euid/egid
和 fsuid/fsgid
这两组进程所属用户的 id
来判断权限。
普通用户想修改密码需要调用 passwd
这个命令,而 passwd
这个命令就在 /usr/bin/passwd
。我们可以到文件夹下看下这个文件的权限。
[root@localhost bin]# ls -al
-rwsr-xr-x. 1 root root 33600 4月 7 2020 passwd
我们可以看到,多了一个 s
。Linux基本权限位为 9 位,分别是拥有者、所属群组、其它人三组所对应的 “rwx"。但额外还设置了 3 个权限位。s
便是额外的权限位。s
的作用是让普通用户可以仅在运行这个程序时具备 root
账户的权限。
s
标志位可以通过命令 chmod u+s
授予。当普通用户创建修改密码的进程时,看到 s
标识,就会把 suid
以及 euid
改成 root 用户的 id
。这个时候,进程就具备了写的权限,就可以成功修改密码了。
今天的分享就这么多,是不是感觉 Linux 在设计过程中充满了智慧?
程序员专属卫衣
商品直购链接 👇
脚本之家严选 , 交易担保 , 放心买 , 程序员极客连帽卫衣 Mini Program
推荐阅读:
!!!
推荐:
每日打卡赢积分兑换书籍入口