Linux 命令行与 shell 脚本编程大全 7 理解 Linux 文件权限

了解如何利用 Linux 文件安全系统和共享数据

更多精彩

  • 更多技术博客,请移步 IT人才终生实训与职业进阶平台 - 实训在线

7.1 Linux 的安全性

  1. Linux 安全系统的核心是用户账户

7.1.1 /etc/passwd 文件

  1. /etc/passwd 是 Linux 中用于存放用户登录信息的文件,如下图
    • 在该文件中将用户的登录名与对应的 UID 进行匹配
  2. 在该文件中通常会存在很多账户,但有些账户并不是真的用户,例如 mail
    • 这类账户是 Linux 为各种功能创建的用户账户,叫做 系统账户
    • 这类账户用于运行对应服务进程,及访问对应服务资源
    • 所有运行在后台的服务都需要使用这样的 系统账户 进行访问
    • 使用 系统账户 操作对应后台服务的原因是为了防止服务被攻陷时,被非法拿到过多的系统控制权
  3. 系统账户 的 UID 一般都是在 500 以内,这是 Linux 为 系统账户 预留的范围
  4. 每个用户信息的各种内容使用冒号分隔,每个冒号之间内容的具体含义如下


  5. /etc/passwd 是一个标准的文本文件,所以其实可以手动在文件内部对用户进行增加或删除
    • 但及其不推荐这样做,因为如果因为操作错误导致文件损坏,会直接影响到这个系统的用户管理,甚至 root 用户都无法登录

7.1.2 /etc/shadow 文件

  1. /etc/passwd 中看到的用户密码都是一个符号 x ,这是因为该文件是所有登录用户都有权访问的文件,处于安全考虑,将真正的密码存放在了只有 root 用户才能访问的 /etc/shadow
  2. 文件的完整内容如下图


  3. 每个用户密码的各种内容使用冒号分隔,每个冒号之间的内容具体含义如下


7.1.3 useradd 命令添加新用户

  1. useradd 命令可以一次性创建新用户账户,以及设置用户 HOME 目录结构
    • 如果在执行命令时不添加任务指令,就会直接调用系统默认值对新用户进行配置
  2. 系统默认值被存放在 /etc/default/useradd 文件中,如下图
    • 使用 useradd -D 也可以查看系统默认值
  3. 对于上述这些默认值的解释,如下图


  4. 关于上图中的第 6 条,/etc/skel 目录下有哪些文件,如下图
    • 可以看到,这些就是在第 6 章中介绍过的 用户启动文件
    • 所以这个操作是为了将系统默认的 用户启动文件 直接给予新用户

7.1.3.1 useradd 命令直接创建用户

  1. 使用 useradd username 直接创建用户,如下图
    • 书中提到说如果直接创建用户,系统不会为用户创建 HOME 目录,需要使用 useradd -m username 才会创建 HOME 目录
    • 但实测发现即时不加 -m 指令,新用户的 HOME 目录也被创建了,并且目录下被复制了 /etc/skel 中的文件
  2. 需要注意的是,这样创建的用户默认没有配置密码,所以也无法直接登录,目前只能先用 root 账户登录,再通过 su username 切换到该用户,后续会介绍如何在创建用户后,为新用户指定密码

7.1.3.2 useradd -D 命令查看并修改新建用户默认值

  1. 使用 useradd -D 命令可以查看新建用户的默认值,这一点在上文中已经演示过
  2. 如果在 useradd -D 命令后再添加指令,则可以实现对这些默认值的修改,如下图
    • 通过 -s 指令,将新建用户的默认 shell 改成了 dash shell
  3. useradd -D 命令可使用的指令列表如下图

7.1.4 userdel 命令删除用户

  1. 使用 userdel username 命令可以直接删除用户,但只会删除 /etc/passwd 中的用户信息,该用户对应的 HOME 目录以及其他相关的文件,都不会删除
  2. 使用 userdel -r username 命令则可以再删除用户的时候,将该用户对应的 HOME 目录以及邮件都删除
    • 但除了这两个目录之外的其他和这个用户相关的文件、目录依旧不会被删除
    • 例如由这个用户创建的文件、目录,依旧会存在于系统中
  3. 如下图,就是使用 userdel asing1elife 命令来删除刚刚创建的用户
    • 直接使用 userdel asing1elife 命令删除用户后,依旧可以查询到该用户的 HOME 目录
    • 但再次使用 userdel -r asing1elife 命令删除用户时,提示用户不存在,说明用户在 /etc/passwd 中的信息确实被删除了
    • 之后再次创建用户,直接使用 userdel -r asing1elife 命令删除用户,并再次查询用户的 HOME 目录,则找不到该目录

7.1.5 修改用户

7.1.5.1 usermod 命令修改用户信息

  1. 使用 usermod 命令可以修改用户在 /etc/passwd 中的大部分信息,如下图
  2. 使用 usermod -c comment username 命令就可以修改用户的备注信息,如下图
  3. 使用 usermod -p password username 命令更改用户密码,但实际不行,如下图
    • 使用 passwd asing1elife 命令可以对用户密码进行更改,之后查看 /etc/shadow 可以看到该用户加密后的密码信息
    • 使用 usermod -p teamnote asing1elife 命令再次对用户密码进行更改,之后查看 /etc/shadow 可以看到该用户的密码信息变成了明文的 teamnote
    • 这是因为 usermod -p 命令需要指定的是加密后的用户密码,所以这非常不实用,一般修改密码还是会用 passwd 命令
  4. 使用 usermod -L username 命令可以锁定指定用户,禁止用户登录,使用 usermod -U username 命令则可以解锁指定用户,允许用户登录,如下图
    • 可以看到,左侧通过 root 用户使用 usermod -L asing1elife 命令锁定了该用户,右侧该用户尝试登录时就算密码输入正确,依旧提示 Permission denied ,表示无法登录
    • 之后左侧通过 root 用户使用 usermod -U asing1elife 命令解锁勒该用户,右侧该用户再次尝试登录就可以顺利登录成功
  5. usermod -g 命令和 usermod -G 命令在使用上存在本质区别,如下图
    • usermod -g 命令用于修改用户的默认组
    • usermod -G 命令用于为用户添加新组
    • 使用 useradd asing1elife 命令创建新用户后,可以查看该用户的 主要用户组 是随用户一起创建的 GID 是 1001 的 asing1elife 组
    • 使用 usermod -g shared asing1elife 命令将用户的 主要用户组 修改为 GID 是 1000 的 shared 组
    • 使用 usermod -G asing1elife asing1elife 命令将 asing1elife 用户组重新赋予该用户,查看 /etc/group 可以看到 asing1elife 组中有一个组成员是 asing1elife 用户
    • 至于为什么在 /etc/group 中,shared 组最后没有显示组成员信息,而 asing1elife 组显示了组成员信息,在后续 7.2.1 /etc/group 文件 章节中会有详细解析

7.1.5.2 passwd 修改用户密码

  1. 每个用户都可以修改自己的密码,但只有 root 用户可以修改其他用户的密码
  2. 使用 passwd username 命令可以直接修改指定用户的密码,如下图
    • 可以看到,在修改密码时会给予非常友好的操作步骤和提示
    • 密码必须大于等于 8 个字符
    • 密码不能太简单,比如 12345678 就无法通过验证
    • 密码不能和用户名一样
    • 一次修改最多尝试三次就会被中止


  3. 使用 passwd -e username 命令可以强行终止用户的密码使用期限,具体表现为用户下次登录时系统会提示必须修改密码,如下图
    • 左侧通过 root 用户使用 passwdw -e asing1elife 命令终止了该用户的密码使用期限
    • 右侧当该用户尝试使用当前密码进行登录时,虽然登录成功,但系统强制弹出了修改密码的操作
    • 首先需要输入一遍当前的密码,验证正确后,再输入新密码
    • 并且新密码会有基本验证,不能和之前的密码太相似,也不能和之前的密码一样
    • 新密码修改成功后,用户的当前连接会被终止,需要使用新密码再次登录


7.1.5.3 chpasswd 批量修改用户密码

  1. 使用 chpasswd < fileName 命令,可以从指定文件中批量读取用户的 username:password 键值对,然后修改这些用户的密码,如下图
    • 左侧通过 root 用户创建了 userpwd 文件,并写入了两个 username:password 键值对
    • 之后使用 chpasswd < userpwd 命令执行了该文件,相当于同时修改了这两个用户的密码
    • 右侧这两个用户通过新密码顺利登录成功


7.1.5.4 chsh 命令修改用户的默认 shell

  1. 使用 chsh -s absolutePathShell username 命令可以修改用户的默认 shell ,如下图
    • absolutePathShell 表示指定的 shell 必须是完整路径,例如 /bin/zsh ,不能只是 shell 的名称,例如 zsh
    • 可以看到,一开始在 /etc/passwd 中,用户 asing1elife 的默认 shell 是 /bin/bash
    • 之后在 /etc/shells 中查看了当前系统可用的 shell 类型,找到了 /bin/zsh
    • 使用 chsh -s /bin/zsh asing1elife 将用户的 shell 类型修改为 zsh
    • 提示修改成功后再次查看 /etc/passwd 可以看到用户的默认 shell 确实是 /bin/zsh

7.1.5.5 chfn 命令修改用户备注信息

  1. 使用 chfn asing1elife 命令可以修改用户备注信息,你可能会问这和 usermod -c comment asing1elife 命令有什么区别?
  2. 区别在于 chfn 命令可以会详细的询问该用户的信息,如下图,而 usermod -c 命令只接受填入一个字符串
    • 在修改成功后,系统提示 Finger information changed ,这是因为 chfn 命令其实是将用于 Unix 的finger 命令的信息存入了备注字段
    • 之后尝试使用 finger asing1elife 命令查看对应信息,被告知该命令不存在,因为大部分 Linux 系统默认都没有安装该命令
  3. 可以使用 yum intall -y finger 命令在线安装该命令到当前系统中,之后再使用 finger asing1elife 命令就可以看到上述通过 chfn 命令输入的用户备注信息了,如下图
    • 这里输入 yum intall -y finger 命令后提示已安装,是因为我刚才装的,本身下图中的 Linux 系统是没有安装该命令的

7.1.5.6 chage 命令管理用户有效期

  1. 使用 chage 命令可以通过各种指令改变用户在 /etc/shadow 中的各种信息,如下图
  2. 使用 chage -d 20 asing1elife 命令可以将用户上次修改密码的天数改为 20 天,如下图
    • 同时,使用 chage -d 2019-12-01 asing1elife 命令可以将用户上次修改密码的天数改为自 1970-01-01 到 2019-12-01
    • 可以看到第三个字段一直在变化,这个字段就是用来记录用户自上次修改密码后经过的天数,默认是从 1970-01-01 开始计算
    • chage 命令的日期值可以使用天数( 需要从 1970-01-01 开始计算才有意义,但不是强制的 )或者 YYYY-MM-DD 格式的日期值
  3. 使用 chage -E 2019-12-01 asing1elife 命令可以设置用户密码过期的日期,也就是账户被禁用的日期,如下图
    • 可以看到 /etc/shadow 中用户信息的倒数第二个字段发生了变化,和正数第三个字段之间只差一天,说明这个用户明天就过期了
  4. 使用 chage -E 命令可以实现为系统创建临时用户的效果,如下图
    • 左侧 root 用户使用 chage -E 2019-11-30 asing1elife 命令为该用户设置了一个在今天之前的日期,表示该用户已经过期了
    • 右侧该用户尝试登录时系统就会告知账户已经过期,请联系系统管理员,并自动关闭连接


  5. 使用 chage -I 3 asing1elife 命令可以设置用户密码过期多少天后禁止用户登录,如下图
    • 可以看到倒数第三个字段发生了变化,变成了命令设置的数字
    • 我本来认为这个字段控制的日期应该为影响到通过 -E 指令指定的过期日期
    • 比如通过 -E 指令指定 2019-11-30 日过期,之后再通过 -I 指令指定密码过期 3 天后禁止登录,那么实际的禁止用户登录的日期应该是 2019-12-03
    • 但实测发现不是,用户依旧无法登录


  6. 使用 chage -m 10 asing1elife 命令可以设置用户自上次修改密码后,至少需要经过 10 天才能再次更改密码,如下图
    • 左侧 root 用户使用 chage -m 10 asing1elife 命令设置用户 10 天后才能更改密码
    • 右侧用户登录后尝试修改密码,被告知需要等待更长时间才能更改密码


  7. 使用 chage -W 8 asing1elife 命令可以设置密码过期后多久出现提示信息,如下图
    • 可以看到倒数第 4 个字段发生了变化


  8. 完整的 chage 命令指令列表可以参考下图

7.2 使用 Linux 组

  1. 组权限允许多个用户对系统中的文件、目录共享访问
  2. 每个组都有唯一的 GID ,这在 /etc/passwd 的第四个字段中有体现
  3. 每个组除了 GID 唯一,还有唯一的组名,和用户名类似
  4. 用户名和 UID 的信息存放在 /etc/passwd 中,组名和 GID 的信息则存放在 /etc/group

7.2.1 /etc/group 文件

  1. /etc/group 中包含系统中用到的每个组的信息,如下图
  2. 系统账户 一样,系统组 的 GID 通常也被限制在 500 以下,而用户组的 GID 则从 500 之后开始分配
  3. 每组的信息具体如下图


  4. 对于最后一个字段:属于该组的用户列表 ,这个值得好好探讨一下,如下图
    • /etc/passwd 查看 asing1elife 用户的组信息,可以看到该用户属于 GID 为 1000 的组,对应的组名也是 asing1elife 组
    • 但是在 /etc/group 的 asing1elife 组最后一个字段中没有出现该用户的名字
    • 之后新建一个用户,默认在 GID 为 1001 的组,使用 usermod -g asing1elife 3umb1ebee 将用户 3umb1ebee 切换到 asing1elife 组
    • 再次查看 /etc/group 的 asing1elife 组,发现最后一个字段依旧没有值,这是为什么呢???
  5. 这是因为,当一个用户将某个组作为默认组时,这个用户就不会出现在 /etc/group 中对应组的组成员列表下
    • 用户 asing1elife 和 3umb1ebe 的默认组都是 GID 为 1000 的 asing1elife 组,所以在该组的组成员列表中这两个用户都不会出现
  6. 依据上面的描述,还有一点需要注意的,不要直接在 /etc/group 中对将用户加入到对应组的组成员中 ,应该使用 usermod -g 命令来修改对应用户的组信息

7.2.2 groupadd 命令创建新组

  1. 使用 groupadd 命令可以创建一个新的用户组,如下图
    • 在创建新组时,默认没有用户被分配到该组
    • groupadd 命令也没有提供添加用户到指定组中的指令
    • 要添加用户到指定组中,需要使用 usermod -G 命令,这个在 7.1.5.1 usermod 命令修改用户信息 章节中有详细解析

7.2.3 groupmod 命令修改组

  1. 使用 groupmod 命令可以修改指定的组的信息,如下图
    • -g 指令可以修改指定组的 GID
    • -n 指令可以修改指定组的名称
    • -p 指令和 usermod -p 命令一样不实用
  2. 使用 groupmod -g 命令修改指定组的 GID 时,属于该组的用户对应的组信息也会随之更改,如下图
    • 可以看到 asing1elife 用户的默认组是 shared ,同时也属于 asing1elife 组
    • 使用 groupmod -g 1002 asing1elife 命令将 asing1elife 组的 GID 从 1001 修改为 1002 后,asing1elife 用户依旧属于该组
    • 使用 groupmod -g 1001 shared 命令将 shared 组的 GID 从 1000 修改为 1001 后,asing1elife 用户的默认组信息也随之修改为 1001

7.3 理解文件权限

7.3.1 使用文件权限符

  1. 使用 ls -l 命令获取文件信息列表时,信息的第一个字段就是 文件权限符 ,如下图
    • ll 命令是使用 alias 命令做的 ls -l 命令的别名
  2. 文件权限符 看上去很难懂,详细解析如下图
    • 通过下图的解析,可以得知上图中的 teamnote 是一个目录
    • teamnote 目录的所属用户对该目录拥有可读、可写、可执行的完整权限
    • teamnote 目录的所属用户组对该目录拥有可读、可执行的部分权限
    • 当前系统中的其他用户( 既不是 root 用户,也不属于 root 用户组 )对于 teamnote 目录拥有可读、可执行的部分权限


7.3.2 umask 命令设置默认文件权限

  1. 使用 umask 命令可以设置创建文件或目录时的默认权限,但设置方式比较复杂,当我们直接使用 umask 命令尝试获取当前系统的默认文件权限时,得到的数值仅仅只是一个 掩码 ,想用从这个掩码中得到真正的文件权限需要经过好几次换算
  2. 查看系统默认文件权限的方式如下图


  3. 那么 0022 和上述新建文件、目录的权限之间是如何关联起来的,如下图
  4. 完整的 Linux 文件权限码对照图如下


7.3.2.1 使用 umask 命令修改默认文件权限

  1. 通过上述图示了解了 umask 值的转换规则后,可以来尝试修改默认文件权限
  2. 现在已经可以知道,默认的 022 掩码表示的文件权限是 644 ,目录权限是 755
  3. 那么如果想要把默认的文件权限改成 640 ,具体权限为 rw-r----- ,需要设置的掩码是多少?
  4. 使用文件的完整权限 666 ,减去真实的文件权限 640 ,得到的掩码值是 026
  5. 所以使用 umask 026 命令就可以实现预期效果,如下图
    • 可以看到,testFile 文件的权限值和我们预期的一模一样
    • 同时需要注意的是,目录和文件使用的掩码是同一个,所以当通过文件的真实权限得到对应掩码后,其实默认目录的权限也会随之更改
    • 比如下图中 testDir 目录的权限是 rwxr-x--x ,对应的真实权限是 751 ,其实也就是目录的完整权限 777 ,减去掩码 026 后得出的值

7.4 改变安全性设置

7.4.1 chmod 命令改变权限

  1. 使用 chmod 命令可以改变文件或目录的权限,如下图
    • umask 命令不同的是,chmod 命令可以直接通过对应权限的八进制值进行设置,不需要使用掩码
    • chmod 777 命令就是赋予对象完整权限
  2. 上述对 chmod 命令的使用方式其实是 八进制模式
  3. chmod 命令还支持另外一种 符号模式

7.4.1.1 chmod 命令使用符号模式改变权限

  1. 符号模式 相对于 八进制模式 要复杂的多,可选指令组合如下图
  2. 了解 符号模式 对应的指令组合之后,可以尝试修改一下文件权限,如下图
    • testFile 文件本来拥有完整权限,现在使用 chmod o=r testFile 命令将其他用户的权限指定为只读,之后使用 ll 命令可以看到生效了
    • 再使用 chmod o+wx testFile 命令重新加可写、可执行权限赋予其他用户,之后使用 ll 命令可以看到生效了,说明可以同时操作指定对象的多个权限

7.4.1.2 chmod -R 命令递归改变权限

  1. 使用 chmod -R 命令可以实现递归的改变目录权限,也就是在改变根目录权限的同时,目录中所有的文件、目录都会被赋予相同的权限,如下图
    • testDir 目录原始的权限是 751 ,使用 chmod 711 testDir 命令后,该目录的权限发生了更改
    • 但查看目录内部的 testFile1 文件的权限,并没有发生任何变化,还是 640
    • 再次使用 chmod -R 755 testDir 命令修改目录权限,可以看到目录和目录内部的文件的权限变成一样的了,都是 755

7.4.2 chown 命令和 chgrp 命令改变所属关系

  1. 使用 chown 命令可以改变文件、目录所属的用户,如下图
    • 使用 chown asing1elife testFile 命令将该文件的所属用户从 root 改为 asing1elife
    • 使用 chown 1000 testDir 命令将该目录的所属用户从 root 改为 asing1elife
    • 说明 chown 命令可以使用用户名或 UID 来改变所属用户
  2. 使用 chown user.group fileName 命令还可以同时改变文件或目录的所属用户和所属用户组,如下图
    • 用户和用户组并不一定要有所属关联,例如 asing1elife 用户并不属于 root 用户组,但依旧可以通过 asing1elife.root 来实现将 testFile 的所属关系修改为属于 asing1elife 用户,以及 root 用户组
  3. 使用 chown -R 命令也可以实现递归修改目录的所属关系,如下图
  4. chown 命令的完整功能是即可改变文件、目录的所属用户,也可以改变其所属用户组
    • 但只有 root 用户可以使用完整的功能
    • 其他用户只能改变属于自己的文件、目录的所属用户组,而且还必须是准备改变的目标用户组的组成员

7.4.2.1 chgrp 命令改变文件、目录的所属用户组

  1. 使用 chgrp 命令可以改变文件、目录的所属用户组,如下图
    • 相比 chown 命令的强大,chgrp 命令就要弱鸡很多
  2. 由于其他用户在使用 chown 命令时,也只能得到和 chgrp 命令一样的效果,所以 chgrp 命令更推荐非 root 用户使用

7.5 共享文件

  1. Linux 实现共享文件的方式是将需要共享的文件放置在相同的共享组中
  2. 然后属于这个共享组的用户都可以共享访问这个文件
  3. 具体设置太纠结了,我觉得使用场景也不丰富,所以就不实践了

7.6 小结

  1. Linux 通过 UID 和 GID 来限制对文件、目录的访问权限
  2. /etc/passwd 文件用户存放用户信息
  3. /etc/group 文件用户存放用户组信息
  4. /etc/shadow 文件用户存放用户密码信息
  5. useradd 命令可以创建用户
  6. usermod 命令可以修改用户
  7. userdel 命令可以删除用户
    • 通常会加上 -r 指令,用于在删除用户时,删除该用户对应的 HOME 目录
  8. groupadd 命令可以创建用户组
  9. groupmod 命令可以修改用户组
  10. groupdel 命令可以删除用户组
  11. 每个文件、目录都可以为以下三个对象设置权限
    • 所属用户
    • 所属用户组
    • 系统中其他用户
  12. 每个对象的权限都可以细分为以下三个等级,如果都不具备,则是用符号 - 作为占位符
    • 可读 r
    • 可写 w
    • 可执行 x
  13. umask 命令可以查看和设置默认的文件、目录权限
    • 但设置过程比较复杂,需要先将掩码转换为真实的八进制值
    • 再将三位八进制值拆分后与三个对象一一对应,找到真实的权限码
  14. chmod 命令可以修改文件、目录的权限
    • 可以使用简单的 八进制模式
    • 也可以使用复杂的 符号模式
  15. chown 命令可以修改文件、目录的所属用户和所属用户组
    • 只有 root 用户可以修改文件、目录的所属用户
    • 其他用户只能修改属于自己的文件、目录的所属用户组,而且自己还必须是目标用户组的组成员
  16. chgrp 命令可以修改文件、目录的所属用户组

你可能感兴趣的:(Linux 命令行与 shell 脚本编程大全 7 理解 Linux 文件权限)