0%

深入理解Linux

Linux 中的账号与组、文件权限、文件描述符。


账号与组

UID与GID

Linux 系统根据 ID 来识别不同的账号,每个登陆的用户至少都会取得两个 ID ,一个是用户 ID (User ID ,简称 UID)、一个是组 ID (Group ID ,简称 GID)。

文件也是利用 UID 与 GID 辨别它的拥有者与组。我们使用ls -l查看文件属性时,系统会依据 /etc/passwd/etc/group 的内容, 找到 UID / GID 对应的账号与组名再显示出来。

RUID,EUID与SUID

  • RUID:真实用户 ID,当用户登录一个 UNIX 系统后就唯一确定,也就是登录用户的 UID。
  • EUID:有效用户 ID,用于系统决定用户对文件资源的访问权限。
  • SUID:设置用户 ID,它与文件绑定而非用户,用于对外权限的开放。对于某一个文件,当设置文件权限后,可以使本没有相应权限的用户执行这个程序时,可以访问没有访问权限的资源。同理,SGID 也是这个意思。

举例说明:

用户账号

用户登录的时候,Linux 系统做了以下工作:

  1. 查看/etc/passwd中是否有该账号。如果没有则退出,如果有则去/etc/group将该账号对应的 UID 与 GID 读出来。此外,该账号的 home 目录与 shell 配置也一并读出来
  2. 核对口令表。Linux 会去/etc/shadow找出对应的账号与 UID,然后核对一下输入的口令与里头的口令是否相符
  3. 如果一切都 OK 的话,就进入 Shell 控管的阶段

/etc/passwd文件结构

//TODO 第十四章、Linux 账号管理与 ACL 权限配置

文件权限

十位文件权限

我们使用 ls -l 命令查看文件列表时,可以看到前面有一串文件权限信息:

1
2
3
$ ls -l
drwxr-xr-x. 2 root root 6 8月 5 15:47 dir
-rw-r--r--. 1 root root 0 8月 5 15:47 file

文件信息

第一个位置代表的是文件类型:

  • -:普通文件;
  • b:块设备文件;
  • c:字符设备文件;
  • d:目录;
  • l:链接文件;
  • p:命名管道文件;
  • s:套接字文件。

第二部分代表的是文件权限,每一段代表不同的用户:

  • 主权限(User):当前文件所属用户的权限,在 Linux 中每一个文件都有所属的用户。
  • 组权限(Group):当前文件的用户所在组的其它成员的权限。
  • 其它用户权限(Other):跟文件所属用户不在同组的其它用户的权限。

每一段中的内容都是一样的,分别限定:读(r=4)、写(w=2)、执行(x=1)

1
2
3
4
5
6
7
8
rwx	7	具备所有权限(421) 
rw- 6 具备读写权限(420)
r-x 5 具备读和执行权限(401)
r-- 4 具备只读权限(400)
-wx 3 具备写和执行权限(021)
-w- 2 具备写权限(020)
--x 1 具备执行权限(001)
--- 0 000

十二位权限

在 Linux 的实现中,文件权限使用 12 个二进制位表示,除了常用的 9 位权限外,还有 3 位特殊权限经常用于提权。对于 u/g/o,对应有 SUID/SGID/sticky:

十二位权限 11 10 9 8 7 6 5 4 3 2 1 0
含义 S G T r w x r w x r w x
说明 SUID SGID sticky
  • SUID(Set User ID)位:与文件绑定,用 S 表示,任何用户执行该文件时,获得该文件属主账号对应的身份。举例说明,普通用户可以使用 passwd 命令修改自己的密码,就是用到了 SUID,这样就相当于 root 用户在执行该命令。
  • SGID(Set Group ID)位:与文件绑定,用 S 表示,任何用户执行该文件时,获得该文件属组账号对应的身份。
  • sticky 位:用 T 表示,任何用户执行该文件时,获得其他用户组账号对应的身份。

SUID 位 / SGID 位 / sticky 位在以十位文件权限表示时,体现在对应的 u/g/o 的执行权限的位置上:如果该位置上已有执行权限,则以小写字母的方式表示;否则,以大写字母表示。示例如下:

1
2
3
4
5
6
7
-rwsr-xr-x 表示没有设置suid/sgid/sticky
-rwsr-xr-x 表示设置了suid,且属主用户有执行权限
-rwSr--r-- 表示设置了suid,但属主用户没有执行权限
-rwxr-sr-x 表示设置了sgid,且属组用户有执行权限
-rw-r-Sr-- 表示设置了sgid,但属组用户没有执行权限
-rwxr-xr-t 表示设置了sticky,且其他用户有执行权限
-rw-r-xr-T 表示设置了sticky,但其他用户没有执行权限

权限管理

  • chmod:修改文件权限
1
2
3
4
5
6
7
8
# 使用数字表示权限,r=4,w=2,x=1
chmod 755 a.txt

# 使用字符表示权限,r/w/x代表读/写/执行,u/g/o代表属主/属组/其他用户,a代表全部的身份,+/-/=代表加入/减去/设定
chmod u=rwx,go=rx a.txt
chmod u=rwx,g=rx,o=rx a.txt
# 所有用户去除执行权限
chmod a-x a.txt
  • chown:变更文件拥有者,要被改变的组名必须要在 /etc/passwd 文件中存在
1
2
3
4
5
6
7
8
# 变更文件拥有者
chown zookeeper /var/lib/zookeeper/*

# 变更文件的拥有者和属组
chown zookeeper:zookeeper /var/lib/zookeeper/*

# 变更目录下及子目录下的所有文件的拥有者
chown -R zookeeper /var/lib/zookeeper/
  • chgrp:变更文件属组,要被改变的组名必须要在 /etc/group 文件中存在
1
2
3
4
5
# 变更文件属组
chgrp zookeeper /var/lib/zookeeper/*

# 变更目录下及子目录下的所有文件的属组
chown -R zookeeper /var/lib/zookeeper/

文件描述符

文件描述符在形式上是一个非负整数。实际上,它是一个索引值,指向内核为每一个进程所维护的该进程打开文件的记录表。当程序打开一个现有文件或者创建一个新文件时,内核向进程返回一个文件描述符。在程序设计中,一些涉及底层的程序编写往往会围绕着文件描述符展开。

文件描述符概念

Linux 系统中,把一切都看做是文件,当进程打开现有文件或创建新文件时,内核向进程返回一个文件描述符,文件描述符就是内核为了高效管理已被打开的文件所创建的索引,用来指向被打开的文件,所有执行I/O操作的系统调用都会通过文件描述符。

文件描述符、文件、进程间的关系

  1. 描述:
  • 每个文件描述符会与一个打开的文件相对应
  • 不同的文件描述符也可能指向同一个文件
  • 相同的文件可以被不同的进程打开,也可以在同一个进程被多次打开
  1. 系统为维护文件描述符,建立了三个表:

文件描述符-三张表

  1. 通过这三个表,认识文件描述符:

文件描述符-三张表认识文件描述符

  • 在进程 A 中,文件描述符 1 和 30 都指向了同一个打开的文件句柄 #23,这可能是该进程多次对执行打开操作;
  • 进程 A 中的文件描述符 2 和进程 B 的文件描述符 2 都指向了同一个打开的文件句柄 #73,这种情况有几种可能:①进程 A 和进程 B 可能是父子进程关系;②进程 A 和进程 B 打开了同一个文件,且文件描述符相同(低概率事件);③ A、B 中某个进程通过 UNIX 域套接字将一个打开的文件描述符传递给另一个进程。
  • 进程 A 的描述符 0 和进程 B 的描述符 3 分别指向不同的打开文件句柄,但这些句柄均指向 i-node 表的相同条目 #1936,换言之,指向同一个文件。发生这种情况是因为每个进程各自对同一个文件发起了打开请求。同一个进程两次打开同一个文件,也会发生类似情况。

文件描述符限制

文件描述符也是一种资源,于是就有了文件描述符限制的规定。

文件描述符-文件描述符限制

永久修改用户级限制时有三种设置类型:

  1. soft 指的是当前系统生效的设置值
  2. hard 指的是系统中所能设定的最大值
  3. - 指的是同时设置了 soft 和 hard 的值

检查某个进程的文件描述符

  1. 查看 nginx 进程 id:
1
2
3
4
$ ps -ef | grep nginx
root 9066 1 0 Jun16 ? 00:00:00 nginx: master process nginx
nginx 9068 9066 0 Jun16 ? 00:00:21 nginx: worker process
root 27010 26976 0 17:37 pts/0 00:00:00 grep --color=auto --exclude-dir=.bzr --exclude-dir=CVS --exclude-dir=.git --exclude-dir=.hg --exclude-dir=.svn --exclude-dir=.idea --exclude-dir=.tox nginx
  1. 查看进程限制,Max open files 可以看到最大文件描述符的数量限制为 1024 个:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
$ cat /proc/9066/limits 
Limit Soft Limit Hard Limit Units
Max cpu time unlimited unlimited seconds
Max file size unlimited unlimited bytes
Max data size unlimited unlimited bytes
Max stack size 8388608 unlimited bytes
Max core file size 0 unlimited bytes
Max resident set unlimited unlimited bytes
Max processes 3651 3651 processes
Max open files 1024 4096 files
Max locked memory 65536 65536 bytes
Max address space unlimited unlimited bytes
Max file locks unlimited unlimited locks
Max pending signals 3651 3651 signals
Max msgqueue size 819200 819200 bytes
Max nice priority 0 0
Max realtime priority 0 0
Max realtime timeout unlimited unlimited us

# 统计该进程用了多少个文件描述符
$ ll /proc/9066/fd | wc -l
10

实际应用过程中,如果出现 Too many open files, 可以通过增大进程可用的文件描述符数量来解决,但很多时候,并不是因为进程可用的文件描述符过少,而是因为程序 bug 打开了大量的文件连接而没有释放。程序申请的资源在用完后及时释放,才是解决 Too many open files 的根本之道。

Inode

*理解inode *