理解Linux文件权限

7.1 Linux的安全性

用户权限是通过创建用户时分配的用户ID (User ID ,UID)来跟踪的。 UID 时数值,每个用户都有唯一的UID。

7.1.1 /etc/passwd 文件

Linux 系统使用了一个专门的文件来讲用户的登录名匹配到对应的UID值。 这个文件就是 /etc/passwd ,它包含了一些于用户有关的信息。

UID

Linux系统中,有三类用户,分别是:普通用户、根用户、系统用户

Linux采用了32位整数跟用户分配不同的id,即userid,也就是 UID。 这意味着,理论上一个计算机系统最多默认支持了40亿个不同用户。

通常普通用户的UID 大于500,因此默认的,在添加普通用户时,系统默认用户ID从500开始编号。

根用户,即root用户,在Redhat系列系统下,用户的ID范围时1 ~ 499。root 用户就是一个Linux操作系统中上帝一样的存在,能删一切(by@jayce)。

系统用户是指,系统运行时必须有的用户,但是并不是真实的使用者。例如apache,mysql相关服务,就需要使用系统用户apache和mysql。

下文中有讲到shadow文件,可以cat /usr/shadow 就会发现除了注册过的用户和root,还有很多用户,很多以news,mail等服务命令的用户,这些用户都是系统用户。

jayce@DESKTOP-JASQLDM:~$ cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
.
.
.

GID

GID,即Group ID ,用户组id。

UID 和 GID 是什么关系? 是从属关系,Linux下,每个用户至少属于有一个组。

确定用户id 使用 id 命令

$id #显示当前用户的id相关信息
$id username #显示某用户的id信息

确定某用户所属的用户组,使用 groups 命令

$groups #显示当前用户所属用户组
$groups username #显示某用户所属用户组

查看当前用户名,可以使用 whoami 命令

查询当前在线用户,可以使用 who 命令

??一个系统中,不能存在重复的username,也就是用户名不能重复,但是,多个用户名可能共用一个UID !!!

7.1.2 用户名和密码 /etc/passwd 和 /etc/shadow

系统用来记录用户名、密码最重要的两个文件就是/etc/passwd 和 /etc/shadow

passwd和shadow什么关系?

最早在UNIX系统中用于记录密码的文件就是passwd(第2列的x),但是有一个问题:每个用户都需要有读取这个文件的权限,随着现代密码破解技术的发展,即便是加密的密码,也有被破解的可能。所以将密码从这个文件中剥离出去是非常必要的。
目前Linux的做法是将密码相关的信息保存在 /etc/shadow 中。而默认,只有root用户才有读取权限。其他人完全没有读取这个文件的可能。这种保存密码的方式,被称之为“影子密码”。

/etc/passwd 内容格式说明

列数 含义 说明
1 用户名 是UID的字符串标记方式,方便阅读
2 密码 在旧的UNIX系统中,该字段使用户加密之后的密码,现在已经不再使用,而是将密码放在 etc/shadow 中,所以此处都只是一个字母 x
3 UID 系统用来区分不同用户的整数
4 GID 系统用来区分不同用户组的整数
5 说明栏 类似于“注释”,现在已经不再使用
6 家目录 用户登录之后,所在的目录,即用户的家目录
7 登录Shell 用户登录之后,所使用的Shell

/etc/shadow 内容格式说明

列数 含义 说明
1 用户名 是UID的字符串标记方式,方便阅读
2 密码 经过加密之后的密码
3 密码的最近修改日期 这个数组是从 1970 年 1 月 1 日至密码修改日的天数
4 密码不可修改的天数 修改密码之后,几天内不可修改密码,如果是0,则随时可以修改
5 密码重新修改的天数 考虑到密码使用一段时间后可能会泄露,可以设置一个修改时间,在密码到期之前,系统就会提醒用户修改密码。一般默认99999可以认为是永久
6 密码失效前提前警告的天数 设定密码到期前几天内开始提醒用户修改密码
7 密码失效宽限天数 如果密码到期,过了几天之后将会失效,无法登录系统
8 密码失效日期 一般为空
9 保留字段 暂时没有使用

7.1.3 添加新用户 useradd

useradd 命令,用于向Linux系统添加新的用户。

useradd 使用系统的默认值以及命令行参数来设置用户账户。

系统默认值被设置在 /etc/default/useradd 文件中。 可以使用 useradd -D 查看所用Linux系统中的这些默认值:

jayce@DESKTOP-JASQLDM:~$ useradd -D
GROUP=100
HOME=/home
INACTIVE=-1
EXPIRE=
SHELL=/bin/sh
SKEL=/etc/skel
CREATE_MAIL_SPOOL=no

本章节部分内容摘录自:《Linux系统命令及Shell脚本实践指南》

在创建新用户的时候,如果你不在命令行中指定具体的值,useradd 命令就会使用 -D选项所显示的那些默认值。也就是:

  • 新用户会被添加到GID为100的公共组;

  • 新用户的HOME目录将会位于 /home/loginname;

  • 新用户账户密码在过期之后不会被禁用;

  • 新用户账未被设置过日期;

  • 新用户账户将sh shell 作为默认shell;(sh 指向的是dash)

    • root@DESKTOP-JASQLDM:/bin# ls -la sh
      lrwxrwxrwx 1 root root 4 Aug  5 05:39 sh -> dash
      
  • 系统会将 /etc/skel 目录下的内容赋值到用户的HOME目录下;

  • 系统不会为该用户账户在mail目录下创建一个用于接受邮件的文件。

因为发行版本的不同这些都可能不同

倒数第二个值,useradd命令允许管理员创建一份默认的HOME目录配置,然后作为新用户创建的家目录模板。

jayce@DESKTOP-JASQLDM:/bin$ ls -lah /etc/skel
total 20K
drwxr-xr-x  2 root root 4.0K Aug  5 05:40 .
drwxr-xr-x 92 root root 4.0K Oct  8 07:21 ..
-rw-r--r--  1 root root  220 Feb 25  2020 .bash_logout
-rw-r--r--  1 root root 3.7K Feb 25  2020 .bashrc
-rw-r--r--  1 root root  807 Feb 25  2020 .profile

第六章说过了, 这些文件,是bash shell 环境的标准启动文件。

##测试,使用默认参数创建一个新用户账户,检查HOME目录
root@DESKTOP-JASQLDM:~# useradd -m test
root@DESKTOP-JASQLDM:~# ls -lah /home/test
total 20K
drwxr-xr-x 2 test test 4.0K Oct 10 07:39 .
drwxr-xr-x 5 root root 4.0K Oct 10 07:39 ..
-rw-r--r-- 1 test test  220 Feb 25  2020 .bash_logout
-rw-r--r-- 1 test test 3.7K Feb 25  2020 .bashrc
-rw-r--r-- 1 test test  807 Feb 25  2020 .profile
root@DESKTOP-JASQLDM:~#

useradd -m 选项,是“创建用户家目录”。

参数 描述
-c comment 给新用户添加备注
-d home_dir 为主目录指定一个名字(如果不指定,就会和登录名一致)
-e expire_date 用YYYY-MM-DD格式指定一个账户过期的日期
-f inactive_days 指定这个账户密码过期后多少天这个账户被禁用;0表示密码一过期就立即禁用,1表示禁用这个功能
-g initial_group 指定用户登录组的GID或者组名
-G group ... 指定用户除了登陆组之外所属的一个或者多个附加组
-k 必须和-m一起使用,将/etc/skel目录的内容复制到用户的HOME目录
-m 创建用户的HOME目录
-M 不创建用户的HOME目录(当默认设置里要求创建时,才会使用这个选项)
-n 创建一个与用户登录名同名的新组
-r 创建系统账户
-p passwd 为用户账户指定默认密码
-s shell 指定默认的登录shell
-u uid 对账户指定唯一的UID

在创建新用户的时候,使用命令行参数可以更改系统指定的默认值。但是如果总是需要修改某个值的话,最好还是修改一下系统的默认值配置

可以在 -D 选项后跟上一个指定的值,来修改系统默认的新用户设置。

参数 描述
-b default_home 更改默认的创建用户HOME目录的位置
-e expiration_date 更改默认的新账户的过期日期
-f inactive 更改默认的新用户从密码过期到账户被禁用的天数
-g group 更改默认的组名称或者GID
-s shell 更改默认的登录shell
##示例修改新用户默认的登录shell
root@DESKTOP-JASQLDM:/bin# useradd -D -s /bin/bash
root@DESKTOP-JASQLDM:/bin# useradd -D
GROUP=100
HOME=/home
INACTIVE=-1
EXPIRE=
SHELL=/bin/bash
SKEL=/etc/skel
CREATE_MAIL_SPOOL=no

7.1.4 删除用户 userdel

usesdel 命令用于从系统中删除用户,但是,默认情况下,保险起见,userdel命令只会删除/etc/passwd 文件中的用户信息, 而不会删除系统中属于该账户的任何文件。
如果,加上 -r 参数, userdel 命令会删除用户的HOME目录以及邮件目录。 然而,系统上仍然可能存在已删除用户的其他文件。 这在有些环境中会造成问题。

##用户删除示例
root@DESKTOP-JASQLDM:/bin# userdel -r test
userdel: test mail spool (/var/mail/test) not found
root@DESKTOP-JASQLDM:/bin# ls -al /home/test
ls: cannot access ‘/home/test‘: No such file or directory

7.1.5 修改用户

Linux提供了一些不同的工具来修改已经有用户账户的信息。

命令 描述
usermod 修改用户账户的字段,还可以指定主要组以及附加组的所属关系
passwd 修改已有用户的密码
chpasswd 从文件中读取登录名密码对,并更新密码
chage 修改密码的过期日期
chfn 修改用户账户的备注信息
chsh 修改用户账户的默认登录shell
1. usermod

该命令是用户账户修改工具中最强大的一个。 更用于修改 /etc/passwd文件中的大部分字段,著需要与想修改的字段对应的命令行参数就可以了。 参数大部分和useradd 命令的参数一样(-c 修改备注、-e 修改过期日期,更多见手册)。

此外,该命令还有一些可能派上用场的选项

  • -l 修改用户账户的登录名。

  • -L锁定账户,使用户无法登录

  • -p 修改账户的密码

  • -U 解除锁定,使用户能够登录。

    -L-U 选项是比较常用的选项

2. passwd 和 chpasswd

Linux系统上的任何用户都能改自己的密码。但是,只有root用户才有权限改别人的密码。

passwd username

-e 选项能强制用户下次登录的时候,修改密码。 可以先给用户设置一个简单的默认密码。然后用户自己下次登录的时候,就会被强制要求修改密码。

为系统中大量的用户修改密码,chpasswd 命令可以事半功倍。

chpasswd 命令能从标准输入自动读取登录名和密码对(由冒号分割)列表。给密码加密,然后为用户账户设置。 你也可以用重定向命令来将含有userid:passwd 对的文件重定向给该命令。

chapasswd < users.txt
3. chsh、chfn 和 chage

这三个工具专门用来修改特定的账户信息。

chsh 命令用于快速修改默认的用户登录shell。 使用时,必须用shell的全路径作为参数,不能只用shell名。

chsh -s /bin/csh username

chfn 命令提供了在 /etc/passwd 文件的备注字段中存储信息的标准方法。 chfn 命令会 将用于 Unix 的finger命令的信息存进备注字段。 finger 命令可以非常方便的查看Linux 系统上的用户信息。

 finger username

?? 处于安全性的考虑,很多Linux系统管理员会在系统上禁用finger命令, 不少发行版甚至都没有默认安装该命令。可以直接查看 /etc/passwd 文件即可。

如果在使用chfn 命令的时候,没有参数,他会引导你输入默认的备注字段。

root@DESKTOP-JASQLDM:~# tail -n 1 /etc/passwd
jayce:x:1000:1000:,,,:/home/jayce:/bin/bash
root@DESKTOP-JASQLDM:~# chfn jayce
Changing the user information for jayce
Enter the new value, or press ENTER for the default
        Full Name []: SunZhongyi
        Room Number []: -
        Work Phone []: 13407135362
        Home Phone []: -
        Other []: -
root@DESKTOP-JASQLDM:~# tail -n 1 /etc/passwd
jayce:x:1000:1000:SunZhongyi,-,13407135362,-,-:/home/jayce:/bin/bash

chage 命令 用来帮助管理用户账户的有效期。

参数 描述
-d 设置上次修改密码到现在的天数
-E 设置密码过期的日期
-I 设置密码过期到锁定账户的天数
-m 设置修改密码之间最少要多少天
-W 设置密码过期前多久开始出现提醒信息

该命令的时间日期值的指定可以有两种任意格式:

  • YYYY-MM-DD
  • 1970/01-01 到既定日期的天数

chage命令中,有个好用的功能就是可以设定账户的过期日期。 也就是可以是定临时的用户,不需要记住删除用户了。

7.2 使用Linux 用户组

组的概念 ,使得所有组员用了这个特定组的共同权限。

不同的发行版,在处理组的成员关系的时候,略有差异。 有些发行版会创建一个组,把所有的用户都当作这个组的成员。 这种情况要特别小心,因为文件很有可能对其他用户也是可读的。 有些发行版会为每个用户创建单独的一个组, 这样可以更安全 。

每个组都有唯一ID ——GID, 还有一个唯一的组名。

7.2.1 /etc/group 文件

与用户账户类似,组信息也保存在系统的一个文件中。 /etc/group 文件包含系统上用到的每个组的信息。

root@DESKTOP-JASQLDM:~# head /etc/group
root:x:0:
daemon:x:1:
bin:x:2:
sys:x:3:
adm:x:4:syslog,jayce
tty:x:5:
disk:x:6:
lp:x:7:
mail:x:8:
news:x:9:

和UID一样,GID 在分配的时候也采用了特定的格式。 系统账户用的组通常会 分配低于500 的GID 值,而用户组的 GID 则会从500 开始分配。 /etc/group 文件有四个字段:

  • 组名
  • 组密码
  • GID
  • 属于该组的用户列表(用逗号隔开)

组密码允许非组内成员通过它临时成为该组成员,功能并不普遍,但存在。

?? 千万不能通过直接修改 /etc/group 文件来添加用户到一个组。 要用 usermod 命令。

说明 用户账户列表某种意义上有些误导人。你会发现,在列表中,有些组并没有列出用户。这并不是说这些组没有成员。当一个用户在/etc/passwd文件中指定某个组作为默认组时,用户账户不会作为该组成员再出现在/etc/group文件中。多年以来,被这个问题难倒的系统管理员可不是一两个呢。

7.2.2 创建新组

groupadd 命令用于在系统上创建新组。

root@DESKTOP-JASQLDM:~# groupadd test_group
root@DESKTOP-JASQLDM:~# tail -n 1 /etc/group
test_group:x:1001:

添加用户到组

在创建新的组是,默认没有用户被分配到该组。 groupadd 命令没有提供将用户添加到组中的选项,但是可以用usermod 命令来弥补这一点。

root@DESKTOP-JASQLDM:~# usermod -G test_group jayce
root@DESKTOP-JASQLDM:~# tail -n 1 /etc/group
test_group:x:1001:jayce

root@DESKTOP-JASQLDM:~# id jayce
uid=1000(jayce) gid=1000(jayce) groups=1000(jayce),1001(test_group)

如果更改了已登录系统账户所属的用户组,该用户必须登出系统后再登录,组关系的更改才能生效。

?? 为用户账号分配组时要格外小心, 如果加了 -g 选项, 指定的组名会替换掉改账户的默认组。 -G 选项则将该组添加到用户的属组的列表里,不会影响到默认组。

更普遍的是同时使用 -G -a 的选项,意思是把某用户附加到某组

7.2.3 修改组

在 /etc/group 文件中,可以看到,需要修改的组信息并不多, groupmod 命令可以修改已有组的 GID (加 -g 选项),或者组名 (加-n 选项)。

root@DESKTOP-JASQLDM:~# tail -n 1 /etc/group
test_group:x:1001:jayce
root@DESKTOP-JASQLDM:~# groupmod -n test_group_changed test_group
root@DESKTOP-JASQLDM:~# tail -n 1 /etc/group
test_group_changed:x:1001:jayce
groupmod -[option] new_value old_value

所有的安全权限都是基于GID 的,你可以随意的改变组名而不会影响到文件的安全性。

7.3 理解文件权限

jayce@DESKTOP-JASQLDM:/dev$ ls -la
total 4
drwxr-xr-x  8 root root     2740 Oct  8 07:21 .
drwxr-xr-x 19 root root     4096 Oct  8 07:21 ..
crw-r--r--  1 root root  10, 235 Oct  8 07:21 autofs
drwxr-xr-x  2 root root       40 Oct  8 07:21 block
drwxr-xr-x  2 root root       60 Oct  8 07:21 bsg
crw-------  1 root root  10, 234 Oct  8 07:21 btrfs-control
crw-------  1 root root   5,   1 Oct  8 07:21 console
crw-------  1 root root  10,  62 Oct  8 07:21 cpu_dma_latency
crw-------  1 root root  10, 203 Oct  8 07:21 cuse
lrwxrwxrwx  1 root root       13 Oct  8 07:21 fd -> /proc/self/fd
crw-rw-rw-  1 root root   1,   7 Oct  8 07:21 full
crw-rw-rw-  1 root root  10, 229 Oct  8 07:21 fuse
crw-r--r--  1 root root   1,  11 Oct  8 07:21 kmsg
crw-------  1 root root  10, 237 Oct  8 07:21 loop-control
brw-------  1 root root   7,   0 Oct  8 07:21 loop0
brw-------  1 root root   7,   1 Oct  8 07:21 loop1
brw-------  1 root root   7,   2 Oct  8 07:21 loop2
brw-------  1 root root   7,   3 Oct  8 07:21 loop3
brw-------  1 root root   7,   4 Oct  8 07:21 loop4

输出结果的第一个字段,就是描述文件和目录权限的编码。 这个字段的第一个字符代表了对象的类型:

  • -代表了文件
  • d代表了目录
  • l代表了链接
  • c代表字符型设备
  • b代表块设备
  • n代表网络设备

之后,有3组三字符的编码,每一组定义了3种访问权限:

  • r代表对象是可读的
  • w代表对象是可写的
  • x代表对象是可执行的

若没有某种权限,在该权限位会出现单破折线。 这3组权限分别对应对象的3个安全级别:

  • 对象的属主
  • 对象的属组
  • 系统其他用户

![image-20201010100837803](第七章 理解Linux文件权限.assets/image-20201010100837803.png)

7.3.2 默认文件权限 umask

这些文件的权限从何而来? ——umaskumask 命令用来设置所创建文件和目录的默认权限。

理解Linux文件权限

jayce@DESKTOP-JASQLDM:~/test$ touch newfile
jayce@DESKTOP-JASQLDM:~/test$ ls -la newfile
-rw-rw-r-- 1 jayce jayce 0 Oct 10 10:32 newfile

touch 命令用分配给我的用户的默认权限创建了这文件。 umask 命令可以显示和设置这个默认的权限。

jayce@DESKTOP-JASQLDM:~/test$ umask
0002

umaks 命令。工作原理稍有复杂。

这四位值种,首位,代表的是一项特别的安全特性, 叫做黏着位(sticky bit) 。

而后面的三位是表示文件或者目录对应的 umask 八进制值。

如果要理解 umask 是怎么工作的,得先理解八进制模式的安全性设置。

八进制模式的安全性设置先获取这3个 rwx 权限的值,然后将其转换成 3位二进制值,用一个 八进制来表示。

在这个二进制表示中,每个位置,代表了一个二进制位。 因此,如果读权限是唯一置位的权限,权限值就是 r--,转换成二进制就是 100 ,代表的八进制值就是 4。

可能会遇到的组合

权限 二进制值 八进制值 描述
--- 000 0 没有任何权限
--x 001 1 只有执行权限
-w- 010 2 只有写入权限
-wx 011 3 有写入和执行权限
r-- 100 4 只有读取权限
r-x 101 5 有读取和执行权限
rw- 110 6 有读取和写入权限
rwx 111 7 有全部权限

因此,八进制模式的值664代表了:属主和属组成员都有读取和写入的权限,而其他用户都只有读取权限。

上面的列出的文件:-rw-rw-r-- ,转译成二进制就是:110110100,转译成8进制就是,664。

jayce@DESKTOP-JASQLDM:~/test$ ls -la newfile
-rw-rw-r-- 1 jayce jayce 0 Oct 10 10:32 newfile

那,这个八进制的 664 和 umask的输出是怎么联系的?

jayce@DESKTOP-JASQLDM:/$ umask
0002

umask值只是一个掩码。它会屏蔽掉不想授予该安全级别的权限。

要把 umask 值从对象的全权限值中减掉。 对文件来说,全权限的值 是 666 (所有用户都有读和写的权限) ; 对目录来说,则是 777 (所有用户都有读、写、执行的权限)。

所以,在上个例子中,对于文件 newfile 来说,其全权限值为666, 全权限值减去 八进制模式值 664 ,就是002 了。 加上首位的黏着位,就是 0002

在大多数发行版中,umask值通常会设置在 /etc/profile 启动文件中,不过有一些设置在 /etc/login.defs 文件中。可以使用 umask 命令为默认umask 设置指定一个新的值。

通过上面的介绍分析,可知,如果要设定umask 值,遵循计算规则。

umask值 = 文件/文件夹的全权限值 - 八进制权限值组合

这是上面分析过程的一个逆过程,

例如,想要设定默认的文件权限是,属主可读可写,属组用户仅可读,其他用户无任何权限,那么其二进制值就是110100000,换算成8进制权限值组合就是640 。

所以,umask 值 = 666 - 640 = 026

?? 特别注意,此时,由于目录不同于文件,其全权限值为777, 所以目录的权限此时是:

目录全权限值 - umask值 = 777 - 026 = 751 (二进制:111101001)

也就是默认的目录权限是:属主可读可写可执行,属组用户可读可执行,其他用户仅可执行。

7.4 改变安全性设置

如果你已经创建了一个目录或者文件,需要改变它的安全性设置。 在 Linux系统上有一些工具能够完成这项任务。

7.4.1 改变权限

chmod 命令,可以用来改变文件和目录的安全性设置。 其格式如下 :

chmod options mode file

mode 参数,可以使用八进制模式或者符号模式进行安全性设置。 实例:

jayce@DESKTOP-JASQLDM:~/test$ ls -la newfile
-rw-rw-r-- 1 jayce jayce 0 Oct 10 10:32 newfile
jayce@DESKTOP-JASQLDM:~/test$ chmod 444 newfile
jayce@DESKTOP-JASQLDM:~/test$ ls -la newfile
-r--r--r-- 1 jayce jayce 0 Oct 10 10:32 newfile

将newfile 的安全权限改为全部仅可读。 如果你尝试修改这个文件,系统会提示你这个文件是只读的。 但是你依然可以通过编辑器强制对其进行编辑保存(vi 编辑器wq!):

E45: ‘readonly‘ option is set (add ! to override)

使用符号模式的时候就会复杂一些。

[ugoa…][[+-=][rwxXstugo…]

第一组字符定义了权限作用的对象:

  • u 代表用户
  • g 代表组
  • o 代表其他
  • a 代表上述所有

后面跟的符号:

  • + 表示你想在现有权限的基础上增加权限
  • - 表示你想在现有权限的基础上移除权限
  • = 将权限设置成后面的值

最后,第三个符号代表作用到设置上的权限,这个值 比通常的 rwx 多。 额外的设置有以下几项:

  • X 如果对象是目录或者它已有执行权限,赋予执行权限
  • s 运行时重新设置UID 或者 GID
  • t 保留文件或者目录
  • u 将权限设置为跟属主一样
  • g 将权限设置为跟属组一样
  • o 将权限设置为跟其他用户一样

用例:

##增加权限 +
jayce@DESKTOP-JASQLDM:~/test$ ls -la newfile
-r--r--r-- 1 jayce jayce 6 Oct 10 15:49 newfile
jayce@DESKTOP-JASQLDM:~/test$ chmod u+w newfile
jayce@DESKTOP-JASQLDM:~/test$ ls -la newfile
-rw-r--r-- 1 jayce jayce 6 Oct 10 15:49 newfile
jayce@DESKTOP-JASQLDM:~/test$ chmod g+wx newfile
jayce@DESKTOP-JASQLDM:~/test$ ls -la newfile
-rw-rwxr-- 1 jayce jayce 6 Oct 10 15:49 newfile
jayce@DESKTOP-JASQLDM:~/test$
##移除权限 -
jayce@DESKTOP-JASQLDM:~/test$ ls -la newfile
-rw-rwxr-- 1 jayce jayce 6 Oct 10 15:49 newfile
jayce@DESKTOP-JASQLDM:~/test$ chmod u-w newfile
jayce@DESKTOP-JASQLDM:~/test$ ls -la newfile
-r--rwxr-- 1 jayce jayce 6 Oct 10 15:49 newfile
jayce@DESKTOP-JASQLDM:~/test$ chmod g-wx newfile
jayce@DESKTOP-JASQLDM:~/test$ ls -la newfile
-r--r--r-- 1 jayce jayce 6 Oct 10 15:49 newfile
##直接设定 =
jayce@DESKTOP-JASQLDM:~/test$ ls -la newfile
-r--r--r-- 1 jayce jayce 6 Oct 10 15:49 newfile
jayce@DESKTOP-JASQLDM:~/test$ chmod u=rwx newfile
jayce@DESKTOP-JASQLDM:~/test$ ls -la newfile
-rwxr--r-- 1 jayce jayce 6 Oct 10 15:49 newfile
##将其他用户的权限设定成和属主用户一样
jayce@DESKTOP-JASQLDM:~/test$ ls -la newfile
-rwxr--r-- 1 jayce jayce 6 Oct 10 15:49 newfile
jayce@DESKTOP-JASQLDM:~/test$ chmod o=u newfile
jayce@DESKTOP-JASQLDM:~/test$ ls -la newfile
-rwxr--rwx 1 jayce jayce 6 Oct 10 15:49 newfile

?? 使用ls -F 命令,会在列出的结果中,对可执行文件加上一个*号。

jayce@DESKTOP-JASQLDM:~/test$ ls -F
newfile*
jayce@DESKTOP-JASQLDM:~/test$ cat newfile
echo "hello world"
jayce@DESKTOP-JASQLDM:~/test$ ./newfile
hello world

目前为止,chmod 命令滚还没有使用过 option 选项。 实际chmod提供了一些选项。

例如 chmod -R 更够递归的修改整个文件夹内文件的权限。

7.4.2 改变所属关系 chown chgrp

有的时候,你需要改变文件的属主。 Linux 提供了两个命令来实现 修改文件的属主。

只有root 用户能够改变文件的属主。 任何属主都可以改变文件的属组,但是前提是属主必须是原属组和目标属组的成员。

  • chown:用于改变文件的属主
  • chgrp:用于改变文件的默认属组
chown options owner[.group] file

改变属主:

root@DESKTOP-JASQLDM:/home/jayce/test# chown user_test newfile
root@DESKTOP-JASQLDM:/home/jayce/test# ls -la newfile
-rwxr--rwx 1 user_test jayce 19 Oct 10 16:22 newfile
root@DESKTOP-JASQLDM:/home/jayce/test#

改变属组:

root@DESKTOP-JASQLDM:/home/jayce/test# chown .user_test newfile
root@DESKTOP-JASQLDM:/home/jayce/test# ls -la newfile
-rwxr--rwx 1 user_test user_test 19 Oct 10 16:22 newfile

以上两个步骤, 如果Linux 系统采用和用户登录名匹配的组名。 可以只用一个条目就改变二者

root@DESKTOP-JASQLDM:/home/jayce/test# ls -la newfile
-rwxr--rwx 1 user_test user_test 19 Oct 10 16:22 newfile
root@DESKTOP-JASQLDM:/home/jayce/test# chown jayce. newfile
root@DESKTOP-JASQLDM:/home/jayce/test# ls -la newfile
-rwxr--rwx 1 jayce jayce 19 Oct 10 16:22 newfile

区别就是:

  • 仅改变属主:chown user_name newfile
  • 仅改变属组:chown .group_name newfile
  • 同时改变属主和属组(属组和属主名相同时):chown the_both_name. newfile

7.5 共享文件 chmod g+s

在Linux上,通用的文件共享方法是通过创建组。 但是在一个完整的共享文件的环境下会很复杂。

前面说过,创建文件的时候,Linux 会用你默认的UID 和 GID 给文件分配权限。 想要让其他人也能够访问到文件,要么改变其他用户所在安全组的访问权限,要么就给文件分配一个包含其他用户的新默认组。

在大范围环境中,创建分享文档,会很繁琐。 所以有种简单的方法解决该问题。

Linux还为每个文件和目录存储了3个额外信息位:

  • 设置用户ID(SUID):当文件被用户使用时,程序会以文件属主的权限运行;
  • 设置组ID (SGID):对文件来说,程序会以文件属组的权限运行;对目录来说,目录中创建的新文件会以目录的默认属组作为默认属组。
  • 黏着位:进程结束后,文件还驻留(黏着)在内存中。

SGID 位对文件共享来说,非常重要。 启用SGID之后,你可以强制在一个共享目录下创建的新文件都属于该目录的属组,这个组也就成为了每个用户的属组。

SGID 可以通过chmod命令设置。 它会加到标准3位八进制值之前(组成4位八进制值),或者在符号模式下用符号s

二进制2位置位含义 二进制1位置位含义 二进制0位置位含义
SUID位 SGID位 黏着位
二进制值 八进制值 描述
000 0 所有位都清零
001 1 黏着位置位
010 2 SGID位置位
011 3 SGID位和黏着都置位
100 4 SUID位置位
101 5 SUID位和黏着位都置位
110 6 SUID位和SGID位都置位
111 7 所有位都置位

因此,要创建一个共享目录,使得目录里的新文件都能沿用目录的属组,只需要将该目录的SGID 位置位。

实验:

root权限下操作

实验预备:

先在/home/jayce/test 下创建两个testdir1和testdir2两个文件夹。

root@DESKTOP-JASQLDM:/home/jayce/test# mkdir testdir1 testdir2
root@DESKTOP-JASQLDM:/home/jayce/test# ls -l
total 8
drwxr-xr-x 2 root root 4096 Oct 12 09:44 testdir1
drwxr-xr-x 2 root root 4096 Oct 12 09:44 testdir2

然后修改两个文件夹的属组为之前创建的user_test:

root@DESKTOP-JASQLDM:/home/jayce/test# tail -n 1 /etc/group
user_test:x:1002:
root@DESKTOP-JASQLDM:/home/jayce/test# chgrp user_test *
root@DESKTOP-JASQLDM:/home/jayce/test# ls -l
total 8
drwxr-xr-x 2 root user_test 4096 Oct 12 09:44 testdir1
drwxr-xr-x 2 root user_test 4096 Oct 12 09:44 testdir2

实验开始:

将分别使用chmod g+s 命令使得testdir1文件夹,具备在其内新建文件时能够沿用目录属组的能力。以及对testdir2不做任何授权操作,进行对比验证。

root@DESKTOP-JASQLDM:/home/jayce/test# chmod g+s testdir1 | ls -l
total 8
drwxr-sr-x 2 root user_test 4096 Oct 12 09:44 testdir1
drwxr-xr-x 2 root user_test 4096 Oct 12 09:44 testdir2
root@DESKTOP-JASQLDM:/home/jayce/test# touch ./testdir1/testfile1 ; ls -l ./testdir1
total 0
-rw-r--r-- 1 root user_test 0 Oct 12 10:00 testfile1
root@DESKTOP-JASQLDM:/home/jayce/test# touch ./testdir2/testfile2 ; ls -l ./testdir2
total 0
-rw-r--r-- 1 root root 0 Oct 12 10:00 testfile2

实验可见, 通过chmod g+s testdir1 命令,对文件夹testdir1操作后, 该文件夹的属组权限由r-x变作了r-s。 是r,w,x之外的一个状态。

再分别再这两个文件夹testdir1、testdir2 下创建新文件时。 发现新文件的属组也不同。

testdir1/testfile1 属组沿用了其父目录 testdir1 。

而尽管testdir2 同样是修改了属组为user_test, 但是其属组却是操作者的属组,也就是root。

chmod g+s [file/folder ] 到底有什么用?

实际上,我们起初讨论的文件共享并没有在实验中提及,Linux中文件共享还是通过属组圈定用户实现。 但是,如果不通过chmod g+s 把属组权限状态改为**s 。 那么被共享文件夹下的每个文件都需要一一去设定属组权限,因为默认的文件的属组会是文件创建者,需要把所有文件都改成共享的属组,才能被共享属组中的成员操作使用。

而这个命令,是指大大的简化了这个过程,只需要对根目录施加权限。 再当不论是谁在该目录下新建文件,文件的属组都是会沿用被设定的共享属组。 可以理解为一个递归的自动化授权实现。

在继续之前,目前为止,还存在一些问题需要注意:

  • user_test 这个测试用于设定为共享组中,仅有 user_test 一个用户。
root@DESKTOP-JASQLDM:/home/jayce/test# tail -n 1 /etc/group
user_test:x:: ##7.2.1 最后说明了,/etc/group会不显示初始组用户,也就是用户名为user_test的用户,所以这里看到的是空的
  • testdir1 文件夹对属组用户没有w权限,也就是不能在内创建文件夹
drwxr-sr-x 2 root user_test 4096 Oct 12 10:00 testdir1

所以,为了测试, 需要添加一个用户到 user_test 这个组。:

root@DESKTOP-JASQLDM:/home/jayce/test# id jayce
uid=1000(jayce) gid=1000(jayce) groups=1000(jayce)
root@DESKTOP-JASQLDM:/home/jayce/test# tail -n 1 /etc/group
user_test:x:1002:
root@DESKTOP-JASQLDM:/home/jayce/test# usermod -a -G user_test jayce
root@DESKTOP-JASQLDM:/home/jayce/test# id jayce
uid=1000(jayce) gid=1000(jayce) groups=1000(jayce),1002(user_test)
root@DESKTOP-JASQLDM:/home/jayce/test# tail -n 1 /etc/group
user_test:x:1002:jayce

还有授予testdir1 这个文件夹写权限。

root@DESKTOP-JASQLDM:/home/jayce/test# chmod g+w testdir1 | ls -l
total 8
drwxrwsr-x 2 root jayce 4096 Oct 12 10:00 testdir1
drwxr-xr-x 2 root jayce 4096 Oct 12 10:00 testdir2
root@DESKTOP-JASQLDM:/home/jayce/test#

切换到 jayce用户,创建文件,测试属组是否还是user_test

jayce@DESKTOP-JASQLDM:~/test/testdir1$ ls -l
total 0
-rw-rw-r-- 1 jayce user_test 0 Oct 12 11:08 testfile@jayce

理解Linux文件权限

上一篇:Linux 常用命令


下一篇:linux中shell命令