基本概念

用户
对于支持多任务的 Linux 系统来说,用户就是获取资源的凭证。

权限
权限用来控制用户对计算机资源(CPU、内存、文件等)的访问,一般会分为认证和授权两步。比如用户先经过认证机制(authentication)登录系统,然后由授权系统(authorization)对用户的操作进行授权。

进程
进程是任何支持多道程序设计的操作系统中的基本概念。通常把进程定义为程序执行时的一个实例。因此,如果有 10 个用户同时运行 vi,就会有 10 个独立的进程(尽管它们共享同一份可执行代码)。
实际上,是进程在帮助我们完成各种任务。进程就是用户访问计算机资源的代理,用户执行的操作其实是带有用户身份信息的进程执行的操作。

进程权限
既然是进程在为用户执行具体的操作,那么当用户要访问系统的资源时就必须给进程赋予权限。也就是说进程必须携带发起这个进程的用户的身份信息才能够进行合法的操作。

从登陆过程观察进程携带的用户身份信息

在 Linux 系统启动后,init 系统会 fork 出子进程执行 /sbin/getty 程序等待用户登录。当用户进行登录操作时,该子进程通过 exec 函数开始执行 /bin/login 程序(此时该进程已经变成了 login 进程)。由 login 进程验证我们的用户名和密码并查询 /etc/passwd 和 /etc/shadow 确定其合法性。如果是合法的用户,该进程再次通过 exec 函数执行用户的默认 shell 程序,此时的 login 进程就变成了 shell 进程(笔者机器上是 bash 进程)。并且该 shell 进程的有效身份被设置成为该用户的身份,之后 fork 此 shell 进程的子进程都会继承该有效身份。我们可以通过下图来理解用户从 tty 登录系统的过程(此图来自互联网):

上图描述了 init 进程、getty 进程、login 进程和 shell 进程的交互。
简单点说就是:用户登录后, shell 进程的有效用户就是该用户。下面我们来了解下进程的用户信息。

进程的 real user id、effective user id 和 saved set user id

通过 cat /proc/<PID>status 命令,我们可以查看到进程所属的用户和组相关的信息:

通过 man proc 可以查询到第一行的四个数字分别是 real user id, effective user id, saved set user id 和 filesystem UID,第二行则是对应的组 ID。这里我们只介绍第一行中的前三个 ID,即  real user id, effective user id 和 saved set user id。

real user id
real user id 是执行进程者的 user id,一般情况下就是用户登录时的 user id。子进程的 real user id 从父进继承。通常这个是不更改的,也不需要更改。比如我以用户 nick 登录 Linux 系统,我接下来运行的所有命令的进程的 real user id 都是 nick 的 user id。

effective user id
如果要判断一个进程是否对某个文件有操作权限,验证的是进程的 effective user id,而不是 real user id。
通常我们是不建议直接使用 root 用户进行操作的,但是在很多情况下,程序可能需要特殊的权限。比如 passwd 程序需要 root 权限才能够为普通用户修改密码,一些 services 程序的操作也经常需要特殊的权限。为此,Linux 中设计了一些特殊的权限,请参考《Linux 特殊权限 SUID,SGID,SBIT》一文。这里我们以 passwd 程序为例,为二进制可执行文件 /usr/bin/passwd 设置  set-user-id bit=ON,这个可执行文件被用 exec 启动之后的进程的 effective user id 就是这个可执行文件的 owner id,而并非父进程的 real user id。如果 set-user-id bit=OFF 的时候,这个被 exec 起来的进程的 effective user id 应该是等于进程的 user id 的。所以,effective user id 存在的意义在于,它可能和 real user id 不同。

saved set user id
saved set user id 相当于是一个 buffer,在 exec 函数启动之后,它会拷贝 effective user id 位的信息覆盖自己。对于非 root 用户来说,可以在未来使用 setuid() 函数将 effective user id 设置成为 real user id 或 saved set user id 中的任何一个。但是不允许非 root 用户用 setuid() 函数把 effective user id 设置成为任何第三个 user id。
对于 root 用户来说,调用 setuid() 的时候,将会设置所有的这三个 user id。

从总体上来看,进程中 real user id, effective user id 和 saved set user id 的设计是为了让 unprivilege user 可以获得两种不同的权限。同时我们也可以得出下面的结论:
Linux 系统通过进程的有效用户 ID(effective user id) 和有效用户组 ID(effective group id) 来决定进程对系统资源的访问权限。

其实我们通过 ps aux 查看的结果中,第一列显示的就是进程的 effective user:

Shell 中外部命令的执行方式

在 shell 中执行的命令分为内部命令和外部命令两种。

  • 内部命令:内建的,相当于 shell 的子函数
  • 外部命令:在文件系统的某个路径下的一个可执行文件

外部命令的执行过程如下:

  1. Shell 通过 fork() 函数建立一个新的子进程,新的子进程为当前 shell 进程的一个副本。
  2. 在新的进程里,从 PATH 变量所列出的目录中寻找指定的命令程序。当命令名称包含有斜杠(/)符号时,将略过路径查找步骤。
  3. 在新的进程里,通过 exec 系列函数,以所找到的新程序替换 shell 程序并执行。
  4. 子进程退出后,最初的 shell 会接着从终端读取并执行下一条命令。

我们通过下面的例子来理解在 shell 中执行外部命令的过程,例子很简单就是通过 cat 命令查看一个文本文件 test.log:

$ cat test.log

我们先来检查一下当前用户以及相关文件的权限:

当前用户 nick 的 real user id 为 1000,/bin/cat 文件的所有者为 root,但是所有人都有执行权限,test.log 文件的所有者为 nick。我们结合下图来介绍 cat test.log 命令的执行过程:

当我们在 shell 中执行一个外部程序的时候,默认情况下进程的 effective user ID 等于 real user ID,进程的 effective group ID 等于 real group ID(接下来的介绍中省略 group ID)。当我们以用户 nick 登录系统,并在 bash 中键入 cat test.log 命令并回车后。Bash 先通过 fork() 建立一个新的子进程,这个新的子进程是当前 bash 进程的一个副本。新的进程在 PATH 变量指定的路径中搜索 cat 程序,找到 /bin/cat 程序后检查其权限。/bin/cat 程序的所有者为 root,但是其他人具有读和执行的权限,所以新进程可以通过 exec 函数用 cat 程序的代码段替换当前进程中的代码段(把 /bin/cat 程序加载到了内存中,此时的进程已经变成了 cat 进程,cat 进程会从 _start 函数开始执行)。由于 cat 进程是由用户 nick 启动的,所以 cat 进程的 effective user ID 是 1000(nick)。同时 cat 进程的 effective user ID 和 test.log 文件的 owner ID 相同(都是 1000),所以 cat 进程拥有对此文件的 rw- 权限,那么顺理成章地就可以读写 test.log 文件的内容了。

下面我们演示一个通过设置特殊权限 set uid ID 改变进程 effective user ID 的例子。
创建文件 root.log,权限为 640,此时只有 root 有权限读写该文件的内容,用户 nick 连读取该文件的权限都没有:

然后通过设置特殊权限 set uid ID 让运行 cat 程序的进程具有 root 权限:

$ sudo chmod 4755 /bin/cat 

现在可以了!因为运行 cat 程序的进程的 effective user ID 变成了 root。记得要把 /bin/cat 的权限改回去呀:

$ sudo chmod 755 /bin/cat

Shell 脚本的执行方式

在 shell 中执行脚本的方式和执行外部命令的方式差不多,比如我们要执行下面的脚本:

$ /bin/bash ./test.sh

这时同样会 fork 出一个子进程。只不过脚本与程序相比没有代码段,也没有 _start 函数,此时 exec 函数就会执行另外一套机制。比如我们在 test.sh 文件的第一行通过 #!/bin/bash 指定了一个解释器,那么解释器程序的代码段会用来替换当前进程的代码段,并且从解释器的 _start 函数开始执行,而这个文本文件被当作命令行参数传给解释器。所以上面的命令执行过程为:Bash 进程 fork/exec 一个子 bash 进程用于执行脚本,子 bash 进程继承父进程的环境变量、用户信息等内容,父进程等待子 bash 进程终止。

总结

文件上的权限信息和用户的信息都是静态的,而进程是动态的,它把自身携带的用户信息和将要进行的操作结合起来,从而实现权限管理。至此我们也基本上搞明白了 Linux 权限系统的工作原理。

linux 用户身份与进程权限相关推荐

  1. Linux用户和组:linux用户和组及权限讲解

    linux用户和组及权限讲解 Linux用户和组概念精讲 Linux用户和组实战应用 Linux系统用户权限管理 Linux用户和组概念精讲 Linux是一种多用户的操作系统(服务器系统),允许多个用 ...

  2. 第七节 红帽认证培训 用户身份与文件权限(5.1-5.3)

    第七节 红帽认证培训 用户身份与文件权限(5.1-5.3) 文章目录 5.1 用户身份与能力 1.id 命令 2.useradd命令 3.groupadd命令 4.usermod命令 5. passw ...

  3. linux用户管理和文件权限

    linux用户管理和文件权限 新建用户: useradd ftpuser      useradd -g gxx userxx 修改密码: passwd ftpuser 新增用户组: # groupa ...

  4. 第八节 红帽认证培训 用户身份与文件权限(5.4-5.6)

    第八节 红帽认证培训 用户身份与文件权限(5.4-5.6) 文章目录 5.4 文件的隐藏属性 1.chattr命令 2.lsattr命令 5.5 文件访问控制列表 1.setfacl命令 2.getf ...

  5. linux 用户、组、权限基本权限

    linux用户.组.权限等简单操作 1.groupadd student useradd -g student -d /usr/local/stu1 -m stu1 echo "123456 ...

  6. linux用户没有创建文件的权限设置密码,Linux学习第五章用户身份与文件权限

    一.用户身份与能力 Linux系统中一共有三种用户 第一种:管理员  root  UID =0 第二种:系统用户 不需要登录系统  负责单一服务的运行  UID = 0-1000 第三种:普通用户 日 ...

  7. Linux基础(用户身份和文件权限)

    用户身份与能力 Linux是一个多用户.多任务的操作系统,具有很好的稳定性与安全性,在幕后保障Linux系统安全则是一系列复杂的配置工作. Linux系统的管理员之所以是root,并不是因为它的名字叫 ...

  8. Linux学习笔记-用户身份与文件权限

    一.用户身份与能力 在Linux RHEL8中,用户身份为: 管理员UID为0:系统的管理员用户 系统用户UID为1~999:Linux系统为了避免因某个服务程序出现漏洞而被黑客提权至整台服务器,默认 ...

  9. linux修改组的选项名字为,Linux用户、组及权限管理浅析

    一.用户和组 1.用户 系统用来认证(Authentication),授权(Authorization),审计(Autition)的帐号.通过登录用户来登录系统.操作系统通过登录不同的用户来调用相对应 ...

最新文章

  1. 如何写网站的robots.txt和meta name robots的配置
  2. 加密移动硬盘解决方案
  3. VMware vSphere@cloudstack基本功能测试报告
  4. SpringSecurity加密认证
  5. ext4fs error mysql_请教一个 Linux 挂在磁盘阵列报错 EXT4-fs error 问题
  6. informix和mysql的区别_DB2与Informix区别比较
  7. 关于iconfont的一些东西
  8. 数据库系统:NoSQL与SQL的区别
  9. n个labeled顶点k棵树森林计数
  10. 运维必看:2017 年 Python 大事件年度盘点!
  11. HDU1010【走迷宫】Tempter of the Bone-------2015年1月26日
  12. linux rtl8111/8168网卡驱动下载,Debian Linux 编译 Realtek (RTL8111/RTL8168) 网卡驱动
  13. Ubuntu下安装VSCODE并输入中文
  14. Linux搭建测试环境
  15. 多传感器融合算法,基于Lidar,Radar,Camera算法
  16. 会议摘要怎么写?这篇论文手把手教你
  17. Java 错别字检查接口 API
  18. p2psear正在连接服务器,P2PSearcher无法连接到网络,也无法连接到服务器
  19. 企业WiFi认证,怎么确保企业WiFi安全?
  20. c#延时函数,不止Sleep函数

热门文章

  1. Segment Routing — SRv6 — 统一的 SDN 控制面与数据面
  2. OpenShift — Overview
  3. php纯面向过程--论坛
  4. 用Python让单片机“行动”起来——MicroPython实战入门篇
  5. python -- numpy 基本数据类型,算术运算,组合,分割 函数
  6. -Objc 、 -all_load 、 -force_load
  7. MySQL数据单个数据太大,导入不进去
  8. (二)nimlang web开发 hello world jester
  9. 做最好的自己,人生十件事(事业,人生,情感)
  10. 使用Windows8开发Metro风格应用三