《Linux就该这么学》学习笔记(五)——用户身份与文件权限

570 阅读17分钟

本次内容

  1. 用户身份与能力
  2. 文件权限与归属
  3. 文件的特殊权限
  4. 文件的隐藏属性
  5. 文件访问控制列表
  6. su 命令与 sudo 服务

1.用户身份与能力

root管理员是所有类UNIX系统中的超级账户;它拥有最高的系统所有权,能够管理系统的各项功能,如添加/删除用户、启动/关闭服务进程、开启/禁用硬件设备等。在 Linux 系统中,每一个用户都有一个身份号码即UID,它像人们的身份证号码一样具有唯一性。Linux 系统的中超级管理员之所以是 root ,是因为此用户的 UID 为0。在 RHEL7 系统中,用户身份是按如下规则分布的:

  • 管理员 UID 为 0:系统的管理员用户(root)
  • 系统用户 UID 为 1~999:Linux 系统中,默认服务程序会有独立的系统用户负责运行
  • 普通用户 UID 从 1000 开始:是由管理员创建的用于日常工作的用户

注意,UID是不能冲突的,管理员创建的普通用户的 UID 默认是从1000开始的(即使前面有闲置的号码)
另外,为了方便管理用户,Linux 系统中还可以通过用户组号码将多个用户放入同一组中以此来为组中用户统一规划权限或指定任务。当我们在 Linux 系统中创建用户时,将自动创建一个与其同名的基本用户组;如果该用户以后被归纳入其他用户组,则这个其他用户组称之为扩展用户组。一个用户只有一个基本用户组,但是可以有多个扩展用户组。

  1. id 命令:此命令用于查询用户信息,格式为 id [参数] [用户名] 。此命令有两种情况,当用户名一项为空时,命令默认查询当前用户的信息;不为空时则查询指定用户的信息。以下为部分常用参数:

    参数 作用
    -g 显示用户的基本组id
    -G 显示用户的扩展用户组id
    -n 显示用户或基本组或拓展用户组的名称,需要与g、G、u参数配合使用,每次只能输出一项
    -u 显示用户的UID
    --help 显示帮助信息
    --version 显示版本信息

    例如查询linuxprobe用户的信息:id linuxprobe,执行这条命令输出的信息如下:

    uid=1000(linuxprobe) gid=1000(linuxprobe) groups=1000(linuxprobe),10(wheel)
    
  2. useradd 命令:此命令用于创建新的用户,格式为 useradd [参数] 用户名 。使用该命令创建用户账户时,默认的用户家目录会被存放在/home 目录中,默认的 Shell 解释器为/bin/bash,部分常用参数如下:

    参数 作用
    -d 指定用户的家目录(默认为/home/username)
    -e 账户的到期时间,格式为 YYYY-MM-DD
    -u 指定该用户的UID
    -g 指定一个初始的用户基本组(必须已存在)
    -G 指定一个或多个扩展用户组
    -N 不创建与用户同名的基本用户组
    -s 指定该用户的默认 Shell 解释器
    -p 指定用户的密码,此时不设置可在之后通过passwd命令设置

    创建一个普通用户并指定家目录的路径、用户的 UID 以及 Shell 解释器:useradd -d /home/linux -u 8888 -s /sbin/nologin linuxprobe。需要注意的是/sbin/nologin,一旦解释器被设置为这个值,则代表该用户不能登录到系统中

  3. groupadd 命令:此命令用于创建用户组,格式为 groupadd [参数] 群组名 。之前已经介绍过用户组的概念,这条命令使用方法也较为简单,如创建一个名为 ronny 的用户组:groupadd ronny

  4. usermod 命令:此命令用于修改用户的属性,格式为 usermod [参数] 用户名 。通常来说,用户信息保存在/etc/passwd文件中,我们可以通过文本编辑器来修改其中的参数;也可以使用此命令来修改用户的属性如用户的 UID、基本/扩展用户组、默认终端等,以下为部分常用参数:

    参数 作用
    -c 填写用户账户的备注信息
    -d -m d用于重新制定用户的家目录,m用于将旧的数据转移到新的家目录,两个参数通常一起使用
    -e 账户的到期时间,格式为 YYYY-MM-DD
    -g 变更所属用户组
    -G 变更扩展用户组
    -L 锁定用户禁止其登录系统
    -U 解锁用户,允许其登录系统
    -s 变更默认终端
    -u 修改用户的 UID

    使用范例:

    • 将用户 linuxprobe 加入到 root 用户组中:usermod -G root linuxprobe
    • 修改 linuxprobe 用户的 UID 号码值:usermod -u 8888 linuxprobe
  5. passwd 命令:此命令用于修改用户密码、过期时间、认证信息等,格式为 passwd [参数] [用户名] 。普通用户只能使用此命令修改自己的用户密码;而root用户可以免密修改所有人的密码。以下为部分常用参数:

    参数 作用
    -l 锁定用户,禁止其登录
    -u 解除锁定,允许用户登录
    --stdin 允许通过标准输入修改用户密码,如 echo "NewPassWord" | passwd --stdin Username
    -d 使该用户可用空密码登录系统
    -e 强制用户在下次登录时修改密码
    -S 显示用户的密码是否被锁定,以及密码所采用的加密算法名称

    使用范例:

    • 修改自己的密码:passwd
    • 修改其他账号的密码:passwd linuxprobe
  6. userdel 命令:此命令令用于删除用户,格式为 userdel [参数] 用户名 。使用此命令执行删除操作时,默认情况下用户的家目录会保留下来,我们可以使用参数 r 将其删除。以下为部分常用参数:

    参数 作用
    -f 强制删除用户,即使当前用户已登录
    -r 同时删除用户及用户家目录

2.文件权限与归属

Linux 系统中有许多类型的文件,它们分别使用不同的字符来加以区分,常见的字符如下:

  • - :普通文件
  • d :目录文件
  • l :链接文件
  • b :块设备文件
  • c :字符设备文件
  • p :管道文件

Linux 系统中,每个文件都可以分别对其所属的所有者、所有组和其他用户设置权限。权限包括可读(r)可写(w)可执行(x) 等;它们可以分别使用数字421来表示。文件权限的字符与数字表示如下图:

使用数字的目的是为了简化权限的表示,如某个文件权限为7(4+2+1)则表示可读可写可执行;权限为764则表示权限为rwxrw-r--,注意,这三个数字并不可相加,它们分别表示文件对于其所有者、所有组和其他用户的权限。下图为我们通过ls -l 文件名命令查看文件详细信息的结果图:

信息包含了文件的类型、访问权限、所有者(属主)、所属组(属组)、占用的磁盘大小、修改时间和文件名称等信息。通过分析可知,该文件的类型为普通文件,所有者权限为可读、可写(rw-),所属组权限为可读(r--),除此以外的其他人也只有可读权限(r--),文件的磁盘占用大小是 34298 字节,最近一次的修改时间为 4 月 2 日的凌晨 23 分,文件的名称为 install.log。

最后需要区分的是一般文件和目录文件的权限含义
一般文件

  • 可读:能够读取文件的实际内容
  • 可写:能够编辑、新增、修改、删除文件的实际内容
  • 可执行:能够运行一个脚本程序

目录文件

  • 可读:能够读取目录内的文件列表
  • 可写:能够在目录内新增、删除、重命名文件
  • 可执行:能够进入该目录

3.文件的特殊权限

有时单纯设置文件的 rwx 权限无法满足我们对安全和灵活性的需求,因此便有了 SUID、SGID 与 SBIT 的特殊权限位。这是一种对文件权限进行设置的特殊功能,可以与一般权限同时使用,以弥补一般权限不能实现的功能。

3.1 SUID

SUID 是一种对二进制程序进行设置的特殊权限,可以让二进制程序的执行者在执行此文件时临时拥有文件所有者的权限(以所有者的身份,理解成所有者的灵魂上身也是可以的哈哈),当然如果普通用户连执行文件的权限都没有,那就完全没有获得文件所属者权限的机会了。下面是一个SUID权限的应用实例,第一次在书上看到这个范例时有点不能理解,在询问同学、查询资料后才明白。

应用实例:
在 Linux 系统中,所有用户都可以通过 passwd 这一命令来修改自己的密码,而用户的密码是保存在 /etc/shadow 这个文件中。因此修改密码其实是对这个文件的修改。我们首先查看此文件发现信息如下:

ls -l /etc/shadow
----------. 1 root root 1004 Jan 3 06:23 /etc/shadow

这个文件的权限为000,也就是说所属者、所属组、其他用户对此文件均没有读、写、执行的权限。但是这里有一个问题,虽然此文件的所属者是root,按道理root账户也不能对其进行读、写、执行操作,但是实际上我可以使用root用户对其进行上述操作。经查阅资料后发现,root 用户并不会被这种权限所限制,有点游离于规则之外的感觉。那么其他普通用户是怎样通过 passwd 命令来修改此文件以达到修改密码的效果的呢?查询 passwd 命令的信息如下:

ls -l /bin/passwd
-rwsr-xr-x. 1 root root 27832 Jan 29 2017 /bin/passwd

可以发现第三个权限位为 s 而不是上面提到过的 x 。这是因为此命令使用了 SUID 权限,当普通用户执行此命令时,会暂时获得文件所属者的权限,也可以理解为暂时以 root 的身份来执行操作、暂时游离于规则之外了。所以才可以对 /etc/shadow 这一文件进行修改操作。

原本的权限为rwx,使用SUID权限后变为rws;原本为rw-,则会变为rwS(大写S)

3.2 SGID

SGID主要实现了如下两种功能:

  1. 让执行者临时拥有所属组的权限(只能对拥有执行权限的二进制程序进行设置)
  2. 在某个目录中创建的文件自动继承该目录的用户组(实现此功能需要在目录上设置SGID权限)

SGID 的第一种功能和 SUID 类似,只不过变成了临时拥有所属组的权限;另外在权限上的显示也有所不同,虽然也是x变s,-变S,但是变化的位置变为了所属组权限的执行位,也就是权限的第六位。第二个功能的使用场景可以是:如果现在需要在一个部门内设置共享目录,让部门内的所有人员都能够读取目录中的内容。那么就可以创建部门共享目录后,在该目录上设置 SGID 特殊权限位。这样,部门内的任何人员在里面创建的任何文件都会归属于该目录的所属组,而不再是自己的基本用户组

3.3 SBIT

SBIT 特殊权限位可确保用户只能删除自己的文件,而不能删除其他用户的文件。换句话说,当对某个目录设置了 SBIT 粘滞位权限后,那么该目录中的文件就只能被其所有者执行删除操作了。例如在 RHEL 7 系统中的/tmp 作为一个共享文件的目录,默认已经设置了 SBIT 特殊权限位,因此除非是该目录的所有者,否则无法删除这里面的文件。与SUID和SGID权限显示方法不同,当目录被设置 SBIT 特殊权限位后,文件的其他人权限部分的 x 执行权限就会被替换成 t 或者 T,原本有 x 执行权限则会写成 t,原本没有 x 执行权限则会被写成 T。

3.4 相关命令

  1. chmod 命令:此命令能够用来设置文件或目录的权限,格式为 chmod [参数] 权限 文件或目录名称 。部分常用参数如下:

    参数 作用
    u 该文件的所属者
    g 该文件的所属组
    o 其他用户
    a 以上三者,相当于ugo
    + 增加权限
    - 取消权限
    = 指定唯一权限
    -c 若该文件权限确实已经更改,才显示其更改动作
    -f 若该文件权限无法被更改也不要显示错误讯息
    -v 显示权限变更的详细资料
    -R 对当前目录下的所有文件与子目录进行相同的权限变更(递归变更)

    使用范例:

    • 为目录文件设置777权限:chmod -Rf 777 testdir/
    • 为目录文件设置SGID权限:chmod -Rf g+s testdir/
  2. chown 命令:此命令设置文件或目录的所有者和所属组,格式为 chown [参数] [所属者][:所属组] 文件或目录名称 ,在此命令中我们也可以使用 -R 参数来表示递归修改。例如修改文件 test 的所属者和所属组:chown root:bin test

4.文件的隐藏属性

Linux 系统中的文件除了具备一般权限和特殊权限之外,还有一种隐藏权限,即被隐藏起来的权限,默认情况下不能直接被用户发觉。

  1. chattr 命令:此命令用于设置文件的隐藏权限,格式为 chattr [参数] 文件。如果想要把某个隐藏功能添加到文件上,则需要在命令后面追加 +参数,如果想要把某个隐藏功能移出文件,则需要追加 -参数 。以下为部分常用参数:

    参数 作用
    i 无法对文件进行修改;若对目录设置了该参数,则仅能修改其中的子文件内容而不能新建或删除文件
    a 仅允许补充(追加)内容,无法覆盖/删除内容
    S 文件内容在变更后立即同步到硬盘
    s 彻底从硬盘中删除,不可恢复
    A 不再修改这个文件或目录的最后访问时间
    b 不再修改文件或目录的存取时间
    D 检查压缩文件中的错误
    d 使用 dump 命令备份时忽略本文件/目录
    c 默认将文件或目录进行压缩
    u 当删除该文件后依然保留其在硬盘中的数据,方便日后恢复
    t 让文件系统支持尾部合并
    X 可以直接访问压缩文件中的内容

    例:为文件设置不允许删除与覆盖权限:chattr +a linuxprobe

  2. lsattr 命令:此命令用于显示文件的隐藏权限,格式为 lsattr [参数] 文件 。文件的隐藏权限必须通过 lsattr 命令来查看

5.文件访问控制列表

在 Linux 系统中,我们不仅可以对某一类用户设置权限;也可以通过文件的访问控制列表(ACL)来对指定用户进行单独的权限控制。

  1. setfacl 命令:此命令用于管理文件的 ACL 规则,格式为 setfacl [参数] 文件名称 。文件的 ACL 提供的是在所有者、所属组、其他人的读/写/执行权限之外的特殊权限控制,使用 setfacl 命令可以针对单一用户或用户组、单一文件或目录来进行读/写/执行权限的控制。当我们对目录文件进行操作时需要使用 -R 递归参数针对普通文件则使用-m 参数删除某个文件的ACL需要使用 -b 参数指定用户需要使用 u指定用户组需要使用 g 。当我们查看文件信息时,被设置了ACL的文件权限的最后一个点(.)会变为加号(+)
    使用范例:
    设置用户linuxprobe对/root文件有读、写、执行权限:setfacl -Rm u:linuxprobe:rwx /root

  2. getfacl 命令:此命令用于显示文件上设置的 ACL 信息,格式为 getfacl 文件名称。如查看/root文件的ACL信息:getfacl /root

6.su 命令与 sudo 服务

  1. su 命令:此命令可以解决切换用户身份的需求,使得当前用户在不退出登录的情况下,顺畅地切换到其他用户。格式为 su [参数] 用户名。当我们在 su 命令与用户名之间添加一个减号(-),则表示完全切换到新的用户,即把环境变量信息也变更为新用户的相应信息,而不是保留原始的信息。建议在切换用户身份时添加这个减号(-)。如su - linuxprobe。另外,从 root 管理员切换到其他用户是不需要密码验证的,但是其他用户就需要验证了。

  2. sudo 命令:此命令用于给普通用户提供额外的权限来完成原本 root 管理员才能完成的任务,格式为 sudo [参数] 命令名称 。以下为部分常用参数:

    参数 作用
    -h 列出帮助信息
    -l 列出当前用户可执行的命令
    -u 以指定的用户身份执行命令
    -k 清空密码的有效时间,下次执行 sudo 时需要再次进行密码验证
    -b 在后台执行指定的命令
    -p 更改询问密码的提示语

    总结来说,sudo 命令具有如下功能:

    • 限制用户执行指定的命令
    • 记录用户执行的每一条命令
    • 配置文件(/etc/sudoers)提供集中的用户管理、权限与主机等参数
    • 验证密码的后 5 分钟内(默认值)无须再让用户再次验证密码

    当然,如果想使用 sudo 命令来获取 root 权限,我们需要去配置 sudo 服务。只有 root 管理员可以通过 visudo 命令编辑 sudo 服务的配置文件。使用此命令配置文件时,其操作方法与 Vim 编辑器中用到的方法一致。在大概99行的位置,写入如下信息 (谁可以使用 允许使用的主机=(以谁的身份) 可执行命令的列表)

    linuxprobe ALL=(ALL) ALL
    

    可以看到,linuxprobe为可以使用的用户,第一个 All 表示所有计算机,第二个 All 表示所有的身份,第三个 All 表示所有命令。当然我们也可以为一个用户组授权如下:

    %admin ALL=(ALL) /usr/bin/cat
    

    这个配置和第一条大致类似,只不过被授权用户变为了 admin 用户组;可执行的命令只有 cat 这一条了,注意在 sudo 的配置文件中填写命令名需要使用命令的全路径名。
    有时我们会认为每隔五分钟验证一次密码较为麻烦,我们可以做配置如下:

    linuxprobe ALL=(ALL) NOPASSWD:ALL
    

    这表示用户在执行 sudo 命令时将不再需要验证密码