第五章 用户身份与文件权限
5.1 用户身份与能力
Linux系统有三种用户身份:
管理员UID为0:系统的管理员用户。
系统用户UID为1~999: Linux系统为了避免因某个服务程序出现漏洞而被黑客提权至整台服务器,默认服务程序会有独立的系统用户负责运行,进而有效控制被破坏范围。(RHEL5/6时UID为1-499)
普通用户UID从1000开始:是由管理员创建的用于日常工作的用户。(RHEL5/6时UID为500-65535)
- 为了方便管理属于同一组的用户,Linux系统中还引入了用户组的概念。通过使用用户组号码(GID,Group IDentification),我们可以把多个用户加入到同一个组中,从而方便为组中的用户统一规划权限或指定任务。假设有一个公司中有多个部门,每个部门中又有很多员工,如果只想让员工访问本部门内的资源,则可以针对部门而非具体的员工来设置权限。
- 在Linux系统中创建每个用户时,将自动创建一个与其同名的基本用户组,而且这个基本用户组只有该用户一个人。如果该用户以后被归纳入其他用户组,则这个其他用户组称之为扩展用户组。
基本组是与生俱来的,只能有一个,扩展组可以有多个。
5.1.1 id
- 作用:显示用户详细信息;
- 格式:
id 用户名
- 示例:
[root@localhost ~]$ id root
uid=0(root) gid=0(root) groups=0(root)
5.1.2 useradd
- 作用:创建新的用户账户;使用该命令创建用户账户时,默认的用户家目录会被存放在/home目录中,默认的Shell解释器为/bin/bash,而且默认会创建一个与该用户同名的基本用户组。这些默认设置可以根据下表中的useradd命令参数自行修改。
- 格式:
useradd [参数] 用户名
参数 | 作用 |
---|---|
-d | 指定用户的家目录(默认为/home/username) |
-e | 账户的到期时间,格式为YYYY-MM-DD. |
-u | 指定该用户的默认UID |
-g | 指定一个初始的用户基本组(必须已存在) |
-G | 指定一个或多个扩展用户组 |
-N | 不创建与用户同名的基本用户组 |
-s | 指定该用户的默认Shell解释器 |
su - 用户:切换用户,root切换到普通用户不需要输入密码,反之则需要;
/bin/bash:默认能管理系统的解释器
/sbin/nologin:默认不能登录到系统
- 示例:
[root@localhost home]$ useradd -d /home/linuxtest -u 8888 -s /sbin/nologin linuxtest
5.1.3 groupadd
- 作用:创建新的用户组;
- 格式:
groupadd [参数] 群组名
-g参数用来修改组gid,但不推荐 - 示例:
[root@localhost home]$ groupadd ronny
5.1.4 usermod
- 作用:修改用户的属性(user modify);
- 格式:
usermod [参数] 用户名
参数 | 作用 |
---|---|
-c | 填写用户账户的备注信息 |
-d -m | 参数-m与参数-d连用,可重新指定用户的家目录并自动把旧的数据转移过去 |
-e | 账户的到期时间,格式为YYYY-MM-DD |
-g | 变更所属用户组(基本组) |
-G | 变更扩展用户组(扩展组) |
-L | 锁定用户禁止其登录系统 |
-U | 解锁用户,允许其登录系统(Unlock) |
-s | 变更默认终端 |
-u | 修改用户的UID(不建议) |
- 示例:
[root@localhost home]$ usermod -G ronny -u 8877 linuxtest
[root@localhost home]$ id linuxtest
uid=8877(linuxtest) gid=8888(linuxtest) groups=8888(linuxtest),8889(ronny) # 展示基本组和扩展组
5.1.5 passwd
- 作用:修改用户的密码、过期时间等信息,
管理员可以重置所有用户密码,
普通用户只能修改自己密码; - 格式:
passwd [参数] 用户名
,直接使用passwd则修改当前用户密码;
参数 | 作用 |
---|---|
-l(小写L) | 锁定用户,禁止其登录 |
-u | 解除锁定,允许用户登录 |
–stdin | 允许通过标准输入修改用户密码,如echo “NewPassWord” | passwd --stdin Username |
-d | 使该用户可用空密码登录系统 |
-e | 强制用户在下次登录时修改密码 |
-S | 显示用户的密码是否被锁定,以及密码所采用的加密算法名称 |
[root@localhost home]$ passwd linuxtest # 修改其他用户密码
Changing password for user linuxtest.
New password:
BAD PASSWORD: The password is shorter than 8 characters
Retype new password:
passwd: all authentication tokens updated successfully.
5.1.6 userdel
- 作用:删除已有的用户账户;默认不会删除用户的家目录;
- 格式:
userdel [参数] 用户名
- 示例:
参数 | 作用 |
---|---|
-f | 强制删除用户 |
-r | 同时删除用户及用户家目录 |
5.2 文件权限与归属
5.2.1 文件类型、权限查看
通过ls -l
命令,每个文件详情第一个字母,就代表着当前的文件类型:
- -:普通文件
- d:目录文件
- l:链接文件
- b:块设备文件(硬件设备)
- c:字符设备文件
- p:管道文件
查看单个文件属性:
ls -l 文件名
查看文件夹属性:ls -ld 文件夹
[root@localhost ~]# ls -l
total 108604
drwxr-xr-x. 3 root root 15 Jan 15 00:23 a
-rw-------. 1 root root 1395 Jan 9 01:00 anaconda-ks.cfg
5.2.2 文件读写执行权限
文件类型后九位如rwxr-xr-x
,代表着:文件的所有者、所有组以及其他人对文件所拥有的读(r)、写(w)、执行(x)等权限。
这里要注意,对于文件和文件夹的读、写、执行权限,含义是有差异的:
r | w | x | |
---|---|---|---|
文件 | 读取文件的实际内容 | 编辑、新增、修改、删除文件的实际内容 | 若文件是脚本可以执行的权力 |
文件夹 | 读取目录内的文件列表 | 可以在目录内新增、删除、重命名文件 | 可以进入该目录 |
从读写执行权限,表示能否对文件或目录执行命令的角度理解,则如下:
完整九位文件权限的字符与数字表示:
文件权限的数字法表示基于字符(rwx)的权限计算而来,其目的是简化权限的表示方式。例如,若某个文件的权限为7则代表可读、可写、可执行(4+2+1);若哪一位权限没有,则要用"-"占位,而不能空格,如rw-r---wx;
5.2.3 修改文件权限与属性
- chmod
作用:设置文件的一般权限及特殊权限(change mode);
格式:chmod [参数] 文件名
,若修改的是文件夹这添加-R
参数
示例:
[root@localhost ~]# ls -l initial-setup-ks.cfg
-rw-r--r--. 1 root root 1550 Jan 9 01:22 initial-setup-ks.cfg
[root@localhost ~]# chmod 555 initial-setup-ks.cfg # 修改文件一般权限
[root@localhost ~]# ls -l initial-setup-ks.cfg
-r-xr-xr-x. 1 root root 1550 Jan 9 01:22 initial-setup-ks.cfg
- chown
作用:设置文件的所有者和所有组(change own);
格式:chown 所有者:所有组 文件名
示例:
[root@localhost ~]# ls -l initial-setup-ks.cfg
-r-xr-xr-x. 1 root root 1550 Jan 9 01:22 initial-setup-ks.cfg
[root@localhost ~]# chown linuxtest:linuxtest initial-setup-ks.cfg # 修改文件所有者和所有组
[root@localhost ~]# ls -l initial-setup-ks.cfg
-r-xr-xr-x. 1 linuxtest linuxtest 1550 Jan 9 01:22 initial-setup-ks.cfg
5.3 文件的特殊权限
文件单纯的rwx权限是有一定的局限性的,不够灵活,因此特殊权限作为一种补充:
5.3.1 SUID
-
含义:SUID是一种对二进制程序进行设置的特殊权限,可以让二进制程序的执行者临时拥有所有者的权限(仅对拥有执行权限的二进制程序有效)。
-
添加SUID权限:
chmod u+s 文件
设置后,会在文件所有者rwx
的执行权限位x
做修改,如果文件原本有可执行权限,就会变为s
,否则变为S
-
示例:
[root@linuxprobe ~]# ls -l /etc/shadow # 用户密码保存在此文件中,除了root用户以外,所有用户都没有rw的权限
----------. 1 root root 1312 Jul 21 05:08 /etc/shadow
[root@localhost ~]# ls -l /usr/bin/passwd # passwd命令文件拥有了SUID权限,普通用户使用passwd即可临时拥有文件所有者root的权限,
# 将变更的密码信息写入其中
-rwsr-xr-x. 1 root root 34512 Aug 13 2018 /usr/bin/passwd
5.3.2 SGID
-
含义:
①对二进制程序进行设置时,可以让执行者临时获取到文件所有组的权限;
②对目录进行设置时,则是让目录内新创建的文件自动继承该目录原有用户组的名称。 -
添加SGID权限:
chmod g+s 文件
,chmod -R g+s 目录
设置后,会在文件所有组rwx
的执行权限位x
做修改,如果文件原本有可执行权限,就会变为s
,否则变为S
-
示例:
①在早期的Linux系统中,/dev/kmem是一个字符设备文件,用于存储内核程序要访问的数据,权限为:
cr--r----- 1 root system 2, 1 Feb 11 2017 kmem
除了root管理员或属于system组成员外,所有用户都没有读取该文件的权限。由于在平时我们需要查看系统的进程状态,为了能够获取到进程的状态信息,可在用于查看系统进程状态的ps命令文件上增加SGID特殊权限位。查看ps命令文件的属性信息:
-r-xr-sr-x 1 bin system 59346 Feb 11 2017 ps
这样一来,由于ps命令被增加了SGID特殊权限位,所以当用户执行该命令时,也就临时获取到了system用户组的权限,从而可以顺利地读取设备文件了。
②创建一个目录,对其添加SGID权限,这样即使换用户在目录中创建的文件会自动继承文件夹所属组:
[root@localhost ~]# cd /tmp/
[root@localhost tmp]# mkdir sgiddir
[root@localhost tmp]# ls -ld sgiddir/
drwxr-xr-x. 2 root root 6 Jan 17 22:28 sgiddir/
[root@localhost tmp]# chmod 777 sgiddir/ # 使所有用户都能写入文件
[root@localhost tmp]# chmod g+s sgiddir/ # 给目录添加SGID权限
[root@localhost tmp]# ls -ld sgiddir/
drwxrwsrwx. 2 root root 6 Jan 17 22:28 sgiddir/ # 查看权限均已添加
[root@localhost tmp]#
[root@localhost tmp]#
[root@localhost tmp]# su - linuxprobe # 切换用户
[linuxprobe@localhost ~]$ cd /tmp/sgiddir/
[linuxprobe@localhost sgiddir]$ touch test
[linuxprobe@localhost sgiddir]$ ls -l test # 切换到sgiddir目录下创建文件,发现文件所属组依旧是root
-rw-rw-r--. 1 linuxprobe root 0 Jan 17 22:31 test
5.3.3 SBIT
- 含义:当对某个目录设置了SBIT粘滞位权限后,那么该目录中的文件就只能被其所有者(文件所有者)执行删除操作了。
其实,文件能否被删除并不取决于自身的权限,而是看其所在目录是否有写入权限
-
添加SBIT权限:
chmod -R o+t 目录
设置后,会在其他人rwx
的执行权限位x
做修改,如果文件原本有可执行权限,就会变为t
,否则变为T
-
示例:
[root@localhost ~]# cd /tmp/
[root@localhost tmp]# mkdir sbitdir
[root@localhost tmp]# ls -ld sbitdir/
drwxr-xr-x. 2 root root 6 Jan 17 22:45 sbitdir/
[root@localhost tmp]# chmod 777 sbitdir/ # 使所有用户都能写入文件
[root@localhost tmp]# chmod -R o+t sbitdir/ # 给目录添加SBIT权限
[root@localhost tmp]# ls -ld sbitdir/
drwxrwxrwt. 2 root root 6 Jan 17 22:45 sbitdir/ # 查看权限均已添加
[root@localhost tmp]# cd sbitdir/
[root@localhost sbitdir]# touch testfile # 进入目录新增文件testfile
[root@localhost sbitdir]#
[root@localhost sbitdir]#
[root@localhost sbitdir]# su - linuxprobe
[linuxprobe@localhost ~]$ cd /tmp/sbitdir/ # 切换用户进入sbitdir目录
[linuxprobe@localhost sbitdir]$ ls
testfile
[linuxprobe@localhost sbitdir]$ rm -f testfile # 尝试删除文件testfile
rm: cannot remove 'testfile': Operation not permitted # 无法删除
[linuxprobe@localhost sbitdir]$ ls -l testfile
-rw-r--r--. 1 root root 0 Jan 17 22:51 testfile # 文件所有者是root,无法被root以外的其他用户删除
PS:
root用户是不受普通权限和特殊权限限制的;
满权限其实是 7777,特殊权限位于普通权限前的
SUID 4,SGID 2,SBIT 1
例如:6543代表着----- r-sr-S-wx
5.4 文件的隐藏属性
Linux系统中的文件除了具备一般权限和特殊权限之外,还有一种隐藏权限,即被隐藏起来的权限,默认情况下不能直接被用户发觉;
可以实现如:即使用户有对文件有充足的权限,依旧无法删除的情况;或是使用户只能对文件进行追加写入的操作,而不能修改或删除;
通过如下命令来增删和查看文件的隐藏属性:
5.4.1 chattr
- 作用:添加或移除文件的隐藏权限(change attributes);
- 格式:添加隐藏属性:
chattr +[参数] 文件名称
,移除隐藏属性chattr -[参数] 文件名称
参数 | 作用 |
---|---|
i | 无法对文件进行修改;若对目录设置了该参数,则仅能修改其中的子文件内容而不能新建或删除文件 |
a | 仅允许补充(追加)内容,无法覆盖/删除内容(Append Only),可对日志文件添加 |
S | 文件内容在变更后立即同步到硬盘(sync) |
s | 彻底从硬盘中删除,不可恢复(用0填充原文件所在硬盘区域) |
A | 不再修改这个文件或目录的最后访问时间(atime) |
b | 不再修改文件或目录的存取时间 |
D | 检查压缩文件中的错误 |
d | 使用dump命令备份时忽略本文件/目录 |
c | 默认将文件或目录进行压缩 |
u | 当删除该文件后依然保留其在硬盘中的数据,方便日后恢复 |
t | 让文件系统支持尾部合并(tail-merging) |
x | 可以直接访问压缩文件中的内容 |
- 示例:见
lsattr
综合示例
5.4.2 lsattr
- 作用:查看文件的隐藏权限(list attributes);
- 格式:
lsattr [参数] 文件名称
- 示例:
# PS:考题:文件无法删除,先用lsattr查看隐藏权限,再chattr去除隐藏权限,最后删除。
[root@localhost a]# lsattr testfile
----ia------------ testfile # 前面的这一列都是隐藏权限,全部去除然后再删除文件
[root@localhost a]# chattr -ia testfile
[root@localhost a]# lsattr testfile
------------------ testfile
[root@localhost a]# rm testfile
rm: remove regular empty file 'testfile'? y
[root@localhost a]# ls # 删除成功
a sgiddir test.sh
5.5 文件访问控制列表FACL
一般权限、特殊权限、隐藏权限其实有一个共性——权限是针对某一类用户设置的,能够对很多人同时生效。如果希望对某个指定的用户进行单独的权限控制,就需要用到文件的访问控制列表(FACL,File Access Control Lists)了。
基于普通文件或目录设置ACL访问控制其实就是针对指定的用户或用户组设置文件或目录的操作权限,更加精准的派发权限。另外,如果针对某个目录设置了ACL,则目录中的文件会继承其权限;若针对文件设置了ACL,则文件不再继承其所在目录的权限。
通过如下命令来增删和查看文件的ACL:
5.5.1 setfacl
- 作用:管理文件的ACL权限规则;
- 格式:
setfacl [参数] 文件名称
用户u
应该不是参数,不加-
参数 | 作用 |
---|---|
-m | 修改权限 |
-M | 从文件中读取权限 |
-x | 删除某个权限 |
-b | 删除全部权限 |
-R | 递归子目录(修改目录全新要加) |
- 示例:
[root@localhost ~]# setfacl -Rm u:linuxtest:rwx /root # 给linuxtest用户单独添加 /root 目录的rwx权限
5.5.2 getfacl
- 作用:查看文件的ACL权限规则;
- 格式:
getfacl [参数] 文件名称
- 示例:
[root@localhost ~]# getfacl /root
ggetfacl: Removing leading '/' from absolute path names
# file: root
# owner: root
# group: root
user::r-x
user:linuxtest:rwx # 可以看到对于linuxtest用户单独加了root目录的rwx权限
group::r-x
mask::rwx
other::---
5.6 su命令与sudo服务
5.6.1 su
- 作用:切换用户身份;su命令与用户名之间有一个减号(-),这意味着完全切换到新的用户,即把环境变量信息也变更为新用户的相应信息,而不是保留原始的信息。强烈建议在切换用户身份时添加这个减号(-)。
- 格式:
su - 用户
- 示例:
[root@localhost ~]# su - linuxfirst
[linuxfirst@localhost ~]$
5.6.1 sudo
- 作用:给普通用户提供额外的权限;把特定命令的执行权限赋予给指定用户,这样可保证普通用户能够完成特定的工作;
授权原则:在保证普通用户完成相应工作的前提下,尽可能少地赋予额外的权限。
使用sudo命令可以给普通用户提供额外的权限来完成原本只有root管理员才能完成的任务。可以限制用户执行指定的命令、记录用户执行过的每一条命令、集中的管理用户与权限(/etc/sudoers)以及验证密码后一段时间内免验证的方便措施。
- 格式:
sudo [参数] 用户名
参数 | 作用 |
---|---|
-h | 列出帮助信息 |
-l | 列出当前用户可执行的命令 |
-u 用户名或UID值 | 以指定的用户身份执行命令 |
-k | 清空密码的有效时间,下次执行sudo时需要再次进行密码验证 |
-b | 在后台执行指定的命令 |
-p | 更改询问密码的提示语 |
如果担心直接修改配置文件会出现问题,则可以使用sudo命令提供的visudo
命令来配置用户权限。
visudo命令用于编辑配置用户sudo权限文件,语法格式为:visudo [参数]
,此命令会自动调用vi编辑器来配置/etc/sudoers权限文件的命令,能够解决多个用户同时修改权限而导致的冲突问题,不仅如此,visudo命令还可以对配置文件内的参数进行语法检查,在发现参数错误时进行报错提醒,比用户直接修改文件更友好、安全、方便。
# 在文件的99行位置,添加权限配置
99 ## Allow root to run any commands anywhere
100 root ALL=(ALL) ALL
101 linuxfirst ALL=(ALL) /usr/bin/cat # 为linuxfirst用户配置在使用cat命令时获取最高权限
102 linuxsecond ALL=(ALL) NOPASSWD:/usr/bin/cat,/usr/sbin/reboot # 设置使用sudo命令调用cat时,无需再输入密码
配置的格式是:
谁可以使用 允许使用的主机=(以谁的身份) 可执行命令的列表
谁可以使用:稍后要为那位用户进行命令授权。
允许使用的主机:可以填写ALL代表不限制来源主机,亦可填写如192.168.10.0/24的网段限制来源地址,只有从允许网段登录时才能使用sudo命令。
以谁的身份:可以填写ALL代表系统最高权限,也可以是另外一位用户的名字(默认是root)。
可执行命令的列表:可以填写ALL代表不限制命令的列表,亦可填写如/usr/bin/cat的文件名称来限制命令列表,多个命令文件之间用逗号(,)间隔。
(PS:crontab
和visudo
配置命令时,都要使用命令的绝对路径,可以用whereis
命令来获取绝对路径)
- 示例:
[linuxsecond@localhost ~]$ sudo reboot # 配置见上方,使用sudo命令即可使用配置的权限执行reboot,且无需输入密码