用户身份与文件权限—Linux就该这么学(四)
学习总览
- 用户身份与能力
- 文件权限与归属
- 文件的特殊权限
- 文件的隐藏权限
- 文件访问控制列表
- su命令和sudo服务
Linux是一个多用户、多任务的操作系统。
Linux系统是如何高效协调多用户与多文件的n对n对应关系的呢?具体可从以上6个方面,来学习Linux就该这么学的第五章—用户身份与文件权限。
用户身份与能力
我们常提到到的超级管理员root,实际指的是UID(User IDentification)为0的、拥有所有权限的用户。(CentOS7)Linux系统实际上是通过UID(从字面意思就知道,UID具有唯一性,是用户的身份令牌)区分用户的,0是系统管理员,1-999是系统用户,1000-*是普通用户。
所有的用户都是保存在文件/etc/passwd中,用户对应的密码(乱码)保存在/etc/shadow。但直接对文件操作来进行权限控制是不可取的。
useradd命令
useradd命令,创建新用户。
useradd命令常用的参数如下:
参数 | 作用 |
---|---|
-d | 指定用户的家目录(默认为/home/username) |
-e | 账户的到期时间,格式为YYYY-MM-DD |
-u | 指定该用户的默认UID |
-G | 指定一个或多个扩展用户组 |
-s | 指定该用户的默认Shell解释器 |
测试用的命令如下:
# 以root身份登入系统后,默认的家目录是/root
cd $HOME | pwd
# 添加一个用户test1,设置默认参数
useradd test1
# 会发现/home/多出了一个目录test1,这是用户test1的家目录
cd /home/
ll
# 查询test1用户的相关信息
id test1
# 切换为root用户,root用户拥有创建新用户的权限
su - root
# 创建一个test2用户(参数用法)
useradd -d /home/learnusers -G root -s /sbin/nologin test2
# 查询test2用户的相关信息
id test2
# test2的家目录是/home/learnusers
cd /home/
ll
# 由于将test2放在系统白名单中(-s /sbin/nologin),该用户无法登入该系统
su - test2
测试的效果图如下:
groupadd命令
groupadd命令,新建一个用户组。用户组,是用来统一管理部分用户的权限。
# 命令后面跟着的,就是新建的组名。
groupadd ronny
usermod命令
usermod命令,修改用户的属性。
usermod命令常用的参数如下:(很多参数与useradd命令的一样)
参数 | 作用 |
---|---|
-c | 填写用户账户的备注信息 |
-d -m | 重新指定用户的家目录并自动把旧的数据转移过去 |
-L | 锁定用户禁止其登录系统 |
-U | 解锁用户,允许其登录系统 |
userdel命令
userdel命令,删除用户。参数r:删除与用户相关的目录。参数f:强制进行删除操作。
usermod命令与userdel命令的效果图如下:
passwd命令
passwd命令,用于修改用户的密码、过期时间、认证信息。
参数 | 作用 |
---|---|
-l | 锁定用户,禁止其登录 |
-u | 解除锁定,允许用户登录 |
–stdin | 允许通过标准输入修改用户密码 |
-d | 使该用户可用空密码登录系统 |
-e | 强制用户在下次登录时修改密码 |
-S | 显示用户的密码是否被锁定,以及密码所采用的加密算法名称 |
# 重设用户zhenye的密码
passwd zhenye
# 锁定用户zhenye,此时用zhenye这个账号和密码无法登入系统
passwd -l zhenye
# 解锁用户zhenye
passwd -u zhenye
# 显示用户zhenye的锁定状态
pass -S zhenye
该命令的效果如下:
文件权限与归属
Linux系统中,一切都是文件。在Linux系统中,是通过字符来区分文件本身的类型,以及权限类型的。表示一个文件的权限顺序是:文件所有者 + 文件所属组 + 其他。
符号 | 含义 |
---|---|
- | 普通文件 |
d | 目录文件 |
l | 链接文件 |
b | 块设备文件 |
c | 字符设备文件 |
p | 管道文件 |
r | 具备读权限,可用数字4表示 |
w | 具备写权限,可用数字2表示 |
x | 具备执行权限,可用数字1表示 |
如下图所示:
# 查与hello相关的文件
cd /home/learnCSPP | ll | grep hello
# 结果如下:
-rwxr-xr-x. 1 root root 8512 3月 17 16:27 hello
-rw-r--r--. 1 root root 72 3月 17 16:27 hello.c
# !!! 对于hello这一条记录的解读如下:
# 第一个-,这是一个普通文件
# 文件所有者的权限是rwx,文件所属组的权限是r-x,其他用户的权限是r-x
# 文件的总数目为1
# 第一个root是文件所有者,第二个root是文件所属组
# 文件在磁盘中占8512字节
# 上次更改时间为3月17日16:27
# 文件的名称为hello
文件的特殊权限
站在文件的角度,有三种不同用户,所以有三种特殊权限—基于文件创建者的SUID、基于文件创建者所属组的SGID、基于其他用户的SBIT。
chmod和chown是更改权限的两个命令。chmod:change mode即更改的是用户对文件的权限。chown:change own即更改的是文件的所有者(创建者、属组者都可以更改)。对目录更改权限,加参数-Rf,大写的R:recurision递归,f:force强制;对一般文件更改权限,可不加参数。
添加或删除特殊权限的测试命令如下:
cd /home/linuxprobe/
# 新建看测试效果的目录test1和文件test2
mkdir test1 | touch test2
ll
# 开放test1和test2的所有权限
chmod 777 -Rf test1
chmod 777 test2
ll
# SUID权限(变化的文件所有者的执行权限 x | s)
# 为文件test2添加SUID权限
chmod u+s test2
ll
# 为文件test2删除SUID权限
chmod u-s test2
ll
# GUID权限(变化的文件创建者所属组的执行权限 x | s)
# 为目录test1添加GUID权限
chmod -Rf g+s test1
ll
# 为目录test1删除GUID权限
chmod -Rf g-s test1
ll
# SBIT权限(变化的其他用户的执行权限 x | t)
# 为目录test1添加SBIT权限
chmod -Rf o+t test1
ll
# 为目录test1删除SBIT权限
chmod -Rf o-t test1
ll
该测试命令的效果图如下:
SUID
SUID,set UID。 是一种对二进制程序进行设置的特殊权限,可以让二进制程序的执行者临时拥有属主的权限(仅对拥有执行权限的二进制程序有效)。
测试命令如下:
# 查看文件(/etc/shadow)的信息
ll /etc/shadow
# 查看文件(/bin/passwd)的信息
# !!! 文件所有者的执行权限(x 变为 s)后,即代表拥有SUID权限
ll /bin/passwd
测试效果图如下:
该命令的解释如下:
- 首先,我们知道文件(/etc/shadow),是保存所有用户密码的文件。而通过passwd命令,我们可以修改用户的密码即修改文件(/etc/shadow)中的内容。
- 然后,我们查看这两个文件的权限详情。我们会发现,文件(/etc/shadow)对用户不开放任何权限,文件(/bin/passwd)的文件所有者权限是(rws)。这里面的s就是SUID权限。
- 总结:文件(/etc/shadow)存放的是用户的密码,对root以外的所有用户不开放权限这是安全正确的做法。但文件所有者必须能够修改密码即(具备/etc/shadow文件的w权限)。文件(/bin/passwd的s权限)就是让执行该命令的用户在执行该命令前后,临时具备与root一样的权限。
SGID
SGID,set GID。它有两种功能。一种与SUID类似,让执行者临时具备属组的权限;另外一种是,让新建的目录自动继承母目录的属组权限。
测试命令如下:
cd /tmp/
# 在/tmp/下新建一个testdir目录(当前用户为root)
mkdir testdir
# 查看testdir的权限详情
ls -ald testdir/
# 为该目录赋予所有的rwx权限
chmod -Rf 777 testdir/
# 为该目录添加SGID权限
# !!!文件所有组的执行权限(x 变为 s)后,即代表拥有SGID权限
chmod -Rf g+s testdir/
# 切换用户为linuxprobe
su - linuxprobe
# 新建一个test文件,并追加内容learn SGID
echo "learn SGID" >> test
# 查看到test的组权限为root,而不是创建者linuxprobe!!!
ls -al test
测试效果图如下:
SBIT
SBIT, Sticky Bit.粘滞位,起保护作用。对某个文件夹设置了SBIT后,只有root和创建者才能够删除该文件夹下的文件。tmp默认带有粘滞作用。
测试命令如下:
# 新建一个不在/tmp下的新目录,作为测试目录
mkdir /home/learnlinux
cd /home/learnlinux
# 执行该命令后,发现root用户新建的目录,所属组和其他用户没有更改(w)权限
ls -ald /home/learnlinux
# 开放该目录的所有权限
chmod -Rf 777 /home/learnlinux/
ls -ald /home/learnlinux/
# 添加两个HOME为测试目录的普通用户
useradd -d /home/learnlinux/ user1
useradd -d /home/learnlinux/ user2
# 切换到用户user1
su - user1
pwd
# 新建待测试的两个文件夹和文件
mkdir test1 test2
touch test1/test3 test2/test4
# 执行该命令后,发现普通用户新建的目录及其文件,其他用户没有更改(w)权限
ls -al test1 test2
# 开放所有文件的所有权限
chmod 777 test1 test1/test3 test2 test2/test4
ls -al test1 test2
exit
# root用户,设置目录test1有SBIT权限
chmod -Rf o+t /home/learnlinux/test1
# 执行该命令后,发现test1和test1/test3其他用户的权限rwx变成了rwt,说明设置SBIT权限成功
ls -al test1 test2
# 切换到用户user2
su - user2
# 对于test2,其他用户(user2)有w权限,删除成功
rm -rf test2
#对于test1以及其下的文件,虽然其他用户也有w权限,但它还有t即SBIT权限,所以无法删除成功。即设置了SBIT权限后,只有文件的创建者和root能删除该目录及其下的文件。
rm -f test1/test3
rm -rf test1
exit
# root用户,删除test1的SBIT权限
chmod -Rf o-t test1
# 执行该命令后,发现test1和test1/test3其他用户的权限rwt变成了rwx,说明成功删除SBIT权限
ls -al test1
# 切换到用户user2
su - user2
# 能够成功删除test1及其下的文件
rm -f test1/test3
rm -rf test1
该测试命令的效果图如下:
文件的隐藏权限
Linux系统的文件除了一般权限和特殊权限外,还有一种隐藏权限。
chattr命令
chattr命令,改变文件的隐藏权限。
常用的参数如下:(+:add -:delelte =:only)
参数 | 作用 |
---|---|
i | 文件无法更改;目录无法新建或删除其子文件,但能修改子文件的内容 |
a | 仅允许追加内容,无法覆盖或删除文件(Append Only) |
S | 文本内容变更后立即同步到磁盘(sync) |
s | 彻底从硬盘中删除,无法恢复 |
测试命令如下:
# 新建测试目录
mkdir test
# 新建两个普通文件,并加入内容
echo "learn how to use chattr" > file1.txt
echo "learn how to use chattr" > test/file2.txt
# 给普通文件添加隐藏权限a
chattr +a file1.txt
# 发现创建者拥有普通文件的w权限,但无法删除该文件
ll
rm -f file1.txt
# 但是可以向该文件中追加内容
echo "append only" >> file1.txt
cat file1.txt
# 删除隐藏权限a后,能删除该文件
chattr -a file1.txt
rm -f file1.txt
# 给目录添加隐藏权限i
chattr +i test
# 能编辑该目录下文件的内容
echo "i can edit the content of it" > test/file2.txt
cat test/file2.txt
# 但是无法新建文件,也无法删除文件
touch test/file3.txt
rm -f test/file2.txt
# 删除隐藏权限a后,能删除文件
chattr -i test/
rm -f test/file2.txt
测试命令效果图如下:
lsattr命令
lsattr命令,查看文件的隐藏权限。通过上个命令的学习,发现ll命令无法显示文件是否具备隐藏权限。
测试命令如下:
# 新建一个测试文件
touch test
# 用ll命令无法查看文件的隐藏权限
ll test
# lsattr命令发现文件没有任何隐藏权限
lsattr test
# 添加或删除相应的隐藏权限后,再次查看效果
chattr +a test
lsattr test
chattr +i test
lsattr test
chattr -a -i test
lsattr test
测试命令效果图如下:
文件访问控制列表
一般权限、特殊权限、隐藏权限是针对某一类用户设置的。如果需要对某个特定用户设置单独的权限控制,就需要用到文件访问控制列表(ACL:access control list)。
setfacl命令
setfacl命令,设置文件访问控制列表。基于目录,用参数R;基于普通文件,用参数m;删除该权限,用参数b。
测试命令如下:
# 切换到普通用户linuxprobe,无法访问root
su - linuxprobe
cd /root
exit
# 基于目录/root,设置用户linuxprobe的访问控制列表为rwx
setfacl -Rm u:linuxprobe:rwx /root
# 切换到linuxprobe用户,发现可以访问root
su - linuxprobe
cd /root
exit
# 权限字符串(.变成+),说明设置访问控制列表
ll /root
# 基于目录/root,删除其访问控制列表
setfacl -b /root
# 切换到普通用户linuxprobe后,发现无法访问root
su - linuxprobe
cd /root
exit
测试命令的效果图如下:
getfacl命令
getfacl命令,获取文件的访问权限列表。格式为:getfacl + 文件名。
效果如下图:
su命令和sudo服务
前面我们用了很多次su命令,就是用来切换用户。su命令加-,就是完全切换到新用户,环境变量也会跟着变。sudo服务也是这种用途,但他更加安全,不会暴露root账号的密码。
sudo命令用于给普通用户提供额外的权限来完成原本root管理员才能完成的任务,可用的参数如下:
参数 | 作用 |
---|---|
-h | 列出帮助信息 |
-l | 列出当前用户可执行的命令 |
-u | 用户名或UID值,以指定的用户身份执行命令 |
-k | 清空密码的有效时间,下次执行sudo时需要再次进行密码验证 |
-b | 在后台执行指定的命令 |
-p | 更改询问密码的提示语 |
测试命令如下:
# 新建一个测试用的用户learnsudo
useradd learnsudo
# 设置该用户的密码
passwd learnsudo
# 切换到用户learnsudo
su - learnsudo
# 输入密码后,发现该用户目前还不支持sudo
sudo -l
exit
# 以root身份编辑sudo的配置文件
visudo
# 在root ALL=(ALL) ALL后,加上一下配置(大约93行)
learnsudo ALL=(ALL) ALL
# 保存退出后,再切换到用户learnsudo
su - learnsudo
# 输入密码后,发现该用户能用sudo的全部命令
sudo -l
# 直接访问/root,发现权限不足
ls /root
# 加上sudo,能访问
sudo ls /root
exit
# 我们知道让一个普通用户,拥有等同root的权限,在实际开发中肯定是不对的,比如我们这个普通用户这具备查看所有文件的权限,配置如下:
# 查看cat命令的路径
whereis cat
# 用root修改sudo配置文件中,让用户learnsudo只具备使用cat命令的权限如下:
visudo
# (大约在93行)
learnsudo ALL=(ALL) /usr/bin/cat
# 保存退出后,再切换到用户learnsudo
su - learnsudo
# 发现用sudo能执行cat命令(/etc/shadow是存放所有用户密码的文件,只有root能看)
sudo cat /etc/shadow
# 发现不能使用其他不合权限的命令(即配置成功)
sudo cd /root
测试效果图如下: