热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

9.Linux权限管理(2)

目录9.11LinuxSetUID(SUID)特殊权限9.12不要轻易设置SetUID(SUID)权限,否

目录

9.11 Linux SetUID(SUID)特殊权限

9.12 不要轻易设置SetUID(SUID)权限,否则会带来重大安全隐患!

9.13 Linux SetGID(SGID)特殊权限

SetGID(SGID)对文件的作用

SetGID(SGID)对目录的作用

9.14 Linux Stick BIT(SBIT)特殊权限

9.15 Linux文件特殊权限(SUID、SGID和SBIT)的设置

9.16 Linux修改文件或目录的隐藏属性(chattr命令)

9.17 Linux查看文件或目录的隐藏属性(lsattr命令)

9.18 Linux sudo命令(包含和su命令的对比)

sudo命令的配置文件/etc/sudoers

9.19 结合实例分析Linux权限对指令执行的影响




9.11 Linux SetUID(SUID)特殊权限

 

在讲解《权限位》一节时提到过,其实除了 rwx 权限,还会用到 s 权限,例如:


[root@localhost ~]# ls -l /usr/bin/passwd
-rwsr-xr-x. 1 root root 22984 Jan  7  2007 /usr/bin/passwd


可以看到,原本表示文件所有者权限中的 x 权限位,却出现了 s 权限,此种权限通常称为 SetUID,简称 SUID 特殊权限。

SUID 特殊权限仅适用于可执行文件,所具有的功能是,只要用户对设有 SUID 的文件有执行权限,那么当用户执行此文件时,会以文件所有者的身份去执行此文件,一旦文件执行结束,身份的切换也随之消失。

举一个例子,我们都知道,Linux 系统中所有用户的密码数据都记录在 /etc/shadow 这个文件中,通过 ll /etc/shadow 命令可以看到,此文件的权限是 0(---------),也就是说,普通用户对此文件没有任何操作权限。

这就会产生一个问题,为什么普通用户可以使用 passwd 命令修改自己的密码呢?

本节开头已经显示了 passwd 命令的权限配置,可以看到,此命令拥有 SUID 特殊权限,而且其他人对此文件也有执行权限,这就意味着,任何一个用户都可以用文件所有者,也就是 root 的身份去执行 passwd 命令。

Linux 系统中,绝对多数命令的文件所有者默认都是 root。

换句话说,当普通用户使用 passwd 命令尝试更改自己的密码时,实际上是在以 root 的身份执行passwd命令,正因为 root 可以将密码写入 /etc/shadow 文件,所以普通用户也能做到。只不过,一旦命令执行完成,普通用户所具有的 root身份也随之消失。

如果我们手动将 /usr/bin/passwd 文件的 SUID 权限取消,会发生什么呢?观察如下命令的执行过程:


[root@localhost ~]# chmod u-s /usr/bin/passwd
#属主取消SetUID权限
[root@localhost ~]# ll /usr/bin/passwd
-rwxr-xr-x. 1 root root 30768 Feb 22 2012 /usr/bin/passwd
[root@localhost ~]# su - lamp
[lamp@localhost ~]$ passwd

Changing password for user lamp.
Changing password for user.
(current) UNIX password:
#看起来没有什么问题
New passwor:
Retype new password:
password:Authentication token manipulation error  <--鉴定令牌操作错误
#最后密码没有生效


显然&#xff0c;虽然用户有执行 passwd 命令的权限&#xff0c;但无修改 /etc/shadow 文件的权限&#xff0c;因此最终密码修改失败。

注意&#xff0c;实验完成后&#xff0c;一定要再把 /usr/bin/passwd 文件的 SetUID 权限加上。

那么&#xff0c;普通用户可以使用 cat 命令查看 /etc/shadow 文件吗&#xff1f;答案的否定的&#xff0c;因为 cat 不具有 SUID 权限&#xff0c;因此普通用户在执行 cat /etc/shadow 命令时&#xff0c;无法以  root 的身份&#xff0c;只能以普通用户的身份&#xff0c;因此无法成功读取。

我们可以使用下面这张图来描述上述过程&#xff1a;


SUID示意图
图 1 SUID示意图


由此&#xff0c;我们可以总结出&#xff0c;SUID 特殊权限具有如下特点&#xff1a;


  • 只有可执行文件才能设定 SetUID 权限&#xff0c;对目录设定 SUID&#xff0c;是无效的。
  • 用户要对该文件拥有 x&#xff08;执行&#xff09;权限。
  • 用户在执行该文件时&#xff0c;会以文件所有者的身份执行。
  • SetUID 权限只在文件执行过程中有效&#xff0c;一旦执行完毕&#xff0c;身份的切换也随之消失。

 


9.12 不要轻易设置SetUID&#xff08;SUID&#xff09;权限&#xff0c;否则会带来重大安全隐患&#xff01;

 

SetUID权限设置不当&#xff0c;会给 Linux 系统造成重大安全隐患。

前面的例子中&#xff0c;我们试验了将 passwd 命令取消 SUID 权限&#xff0c;这会导致 passwd 命令的功能失效。那么&#xff0c;如果我们手动给默认无 SetUID 权限的系统命令赋予 SetUID 权限&#xff0c;会出现什么情况呢&#xff1f;

比如说&#xff0c;我们尝试给 Vim 赋予 SetUID 权限&#xff1a;


[root&#64;localhost ~]# chmod u&#43;s /usr/bin/vim
[root&#64;localhost ~]# ll /usr/bin/vim

-rwsr-xr-x. 1 root root 1847752 Apr 5 2012 /usr/bin/vim


此时你会发现&#xff0c;即便是普通用户使用 vim 命令&#xff0c;都会暂时获得 root 的身份和权限&#xff0c;例如&#xff0c;很多原本普通用户不能查看和修改的文件&#xff0c;竟然可以查看了&#xff0c;以 /etc/passwd 和 /etc/shadow 文件为例&#xff0c;普通用户也可以将自己的 UID 手动修改为 0&#xff0c;这意味着&#xff0c;此用户升级成为了超级用户。除此之外&#xff0c;普通用户还可以修改例如 /etc/inittab 和 /etc/fstab 这样重要的系统文件&#xff0c;可以轻易地使系统瘫痪。

其实&#xff0c;任何只有管理员可以执行的命令&#xff0c;如果被赋予了 SetUID 权限&#xff0c;那么后果都是灾难性的。普通用户可以随时重启服务器、随时关闭看得不顺眼的服务、随时添加其他普通用户的服务器&#xff0c;可以想象是什么样子。所以&#xff0c;SetUID 权限不能随便设置。

有读者可能会问&#xff0c;如何防止他人&#xff08;例如黑客&#xff09;对 SetUID 权限的恶意篡改呢&#xff1f;这里&#xff0c;给大家提供以下几点建议&#xff1a;


  1. 关键目录要严格控制写权限&#xff0c;比如 "/"、"/usr" 等。
  2. 用户的密码设置要严格遵守密码规范。
  3. 对系统中默认应该有 SetUID 权限的文件制作一张列表&#xff0c;定时检査有没有列表之外的文件被设置了 SetUID 权限。


前面 2 点不再做过多解释&#xff0c;这里就最后一点&#xff0c;给大家提供一个脚本&#xff0c;仅供参考。

首先&#xff0c;在服务器第一次安装完成后&#xff0c;马上查找系统中所有拥有 SetUID 和 SetGID 权限的文件&#xff0c;把它们记录下来&#xff0c;作为扫描的参考模板。如果某次扫描的结果和本次保存下来的模板不一致&#xff0c;就说明有文件被修改了 SetUID 和 SetGID 权限。命令如下&#xff1a;


[root&#64;localhost ~]# find / -perm -4000 -o -perm -2000 > /root/suid.list
#-perm安装权限査找。-4000对应的是SetUID权限&#xff0c;-2000对应的是SetGID权限
#-o是逻辑或"or"的意思。并把命令搜索的结果放在/root/suid.list文件中
接下来&#xff0c;只要定时扫描系统&#xff0c;然后和模板文件比对就可以了。脚本如下&#xff1a;
[root&#64;localhost ~]#vi suidcheck.sh
#!/bin/bash
find / -perm -4000 -o -perm -2000 > /tmp/setuid.check
#搜索系统中所有拥有SetUID和SetGID权限的文件&#xff0c;并保存到临时目录中
for i in $(cat /tmp/setuid.check)
#循环&#xff0c;每次循环都取出临时文件中的文件名
do
    grep $i /root/suid.list > /dev/null
    #比对这个文件名是否在模板文件中
    if ["$?"!&#61;"o"]
    #检测测上一条命令的返回值&#xff0c;如果不为0&#xff0c;则证明上一条命令报错
    then
        echo "$i isn&#39;t in listfile! " >>/root/suid_log_$(date &#43;%F)
        #如果文件名不在模板文件中&#xff0c;则输出错误信息&#xff0c;并把报错写入日志中
    fi
done
rm -rf/tmp/setuid.check
#删除临时文件

[root&#64;localhost ~]# chmod u&#43;s /bin/vi
#手工给vi加入SetUID权限
[root&#64;localhost ~]# ./suidcheck.sh
#执行检测脚本
[root&#64;localhost ~]# cat suid_log_2013-01-20
/bin/vi isn&#39;t in listfile!
#报错了&#xff0c;vi不在模板文件中。代表vi被修改了SetUID权限


这个脚本成功的关键在于模板文件是否正常。所以一定要安装完系统就马上建立模板文件&#xff0c;并保证模板文件的安全。

注意&#xff0c;除非特殊情况&#xff0c;否则不要手工修改 SetUID 和 SetGID 权限&#xff0c;这样做非常不安全。而且就算我们做实验修改了 SetUID 和 SetGID 权限&#xff0c;也要马上修改回来&#xff0c;以免造成安全隐患。

SetGID 特殊权限的相关内容&#xff0c;下节会做详细介绍。

 


9.13 Linux SetGID&#xff08;SGID&#xff09;特殊权限

 

前面学习了 SetUID&#xff0c;那么&#xff0c;什么是 SetGID 呢&#xff1f;很简单&#xff0c;当 s 权限位于所属组的 x 权限位时&#xff0c;就被称为 SetGID&#xff0c;简称 SGID 特殊权限。例如&#xff1a;

[root&#64;localhost ~]# ll /usr/bin/locate
-rwx--s--x. 1 root slocate 35612 8月24 2010 /usr/bin/locate

与 SUID 不同的是&#xff0c;SGID 既可以对文件进行配置&#xff0c;也可以对目录进行配置。


SetGID&#xff08;SGID&#xff09;对文件的作用

同 SUID 类似&#xff0c;对于文件来说&#xff0c;SGID 具有如下几个特点&#xff1a;


  • SGID 只针对可执行文件有效&#xff0c;换句话说&#xff0c;只有可执行文件才可以被赋予 SGID 权限&#xff0c;普通文件赋予 SGID 没有意义。
  • 用户需要对此可执行文件有 x 权限&#xff1b;
  • 用户在执行具有 SGID 权限的可执行文件时&#xff0c;用户的群组身份会变为文件所属群组&#xff1b;
  • SGID 权限赋予用户改变组身份的效果&#xff0c;只在可执行文件运行过程中有效&#xff1b;

其实&#xff0c;SGID 和 SUID 的不同之处就在于&#xff0c;SUID 赋予用户的是文件所有者的权限&#xff0c;而 SGID 赋予用户的是文件所属组的权限&#xff0c;就这么简单。

就以本节开头的 locate 命令为例&#xff0c;可以看到&#xff0c;/usr/bin/locate 文件被赋予了 SGID 的特殊权限&#xff0c;这就意味着&#xff0c;当普通用户使用 locate 命令时&#xff0c;该用户的所属组会直接变为 locate 命令的所属组&#xff0c;也就是 slocate。

我们知道&#xff0c;locate 命令是用于在系统中按照文件名查找符合条件的文件的&#xff0c;当执行搜索操作时&#xff0c;它会通过搜索 /var/lib/mlocate/mlocate.db 这个数据库中的数据找到答案&#xff0c;我们来看看此数据库的权限&#xff1a;

[root&#64;localhost ~]# ll /var/lib/mlocate/mlocate.db
-rw-r-----. 1 root slocate 1838850 1月20 04:29 /var/lib/mlocate/mlocate.db

可以看到&#xff0c;mlocate.db 文件的所属组为 slocate&#xff0c;虽然对文件只拥有 r 权限&#xff0c;但对于普通用户执行 locate 命令来说&#xff0c;已经足够了。一方面&#xff0c;普通用户对 locate命令拥有执行权限&#xff0c;其次&#xff0c;locate 命令拥有 SGID 权限&#xff0c;这使得普通用户在执行 locate 命令时&#xff0c;所属组身份会变为 slocate&#xff0c;而 slocate 对 mlocate.db 数据库文件拥有 r 权限&#xff0c;所以即便是普通用户&#xff0c;也可以成功执行 locate 命令。

再次强调&#xff0c;无论是 SUID&#xff0c;还是 SGID&#xff0c;它们对用户身份的转换&#xff0c;只有在命令执行的过程中有效&#xff0c;一旦命令执行完毕&#xff0c;身份转换也随之失效。


SetGID&#xff08;SGID&#xff09;对目录的作用

事实上&#xff0c;SGID 也能作用于目录&#xff0c;且这种用法很常见。

当一个目录被赋予 SGID 权限后&#xff0c;进入此目录的普通用户&#xff0c;其有效群组会变为该目录的所属组&#xff0c;会就使得用户在创建文件&#xff08;或目录&#xff09;时&#xff0c;该文件&#xff08;或目录&#xff09;的所属组将不再是用户的所属组&#xff0c;而使用的是目录的所属组。

也就是说&#xff0c;只有当普通用户对具有 SGID 权限的目录有 rwx 权限时&#xff0c;SGID 的功能才能完全发挥。比如说&#xff0c;如果用户对该目录仅有 rx 权限&#xff0c;则用户进入此目录后&#xff0c;虽然其有效群组变为此目录的所属组&#xff0c;但由于没有 x 权限&#xff0c;用户无法在目录中创建文件或目录&#xff0c;SGID 权限也就无法发挥它的作用。

举个例子&#xff1a;


[root&#64;localhost ~]# cd /tmp
#进入临时目录做此实验。因为只有临时目录才允许普通用户修改
[root&#64;localhost tmp]# mkdir dtest
#建立测试目录
[root&#64;localhost tmp]# chmod g&#43;s dtest
#给测试目录赋予SetGID权限
[root&#64;localhost tmp]# ll -d dtest
drwxr-sr-x 2 root root 4096 Apr 19 06:04 dtest
#SetGID权限已经生效
[root&#64;localhost tmp]# chmod 777 dtest
#给测试目录赋予777权限&#xff0c;让普通用户可以写
[root&#64;localhost tmp]# su - lamp
[lamp&#64;localhost ~]# grep lamp /etc/passwd /etc/group
/etc/passwd:lamp:x:501:501::/home/lamp:/bin/bash
/etc/group:lamp:x:501:
#切换成普通用户lamp&#xff0c;此用户的所属群组为 lamp
[lamp&#64;localhost ~]$ cd /tmp/dtest/
#普通用户进入测试目录
[lamp&#64;localhost dtest]$ touch abc
[lamp&#64;localhost dtest]$ mkdir zimulu

#在此目录中创建新的文件 abc 和子目录 zimulu
[lamp&#64;localhost dtest]$ ll
total 0
-rw-rw-r--. 1 lamp root 0 Apr 19 06:07 abc
drwxrwsr-x. 2 lamp root 40 Apr 19 06:07 zimulu


可以看到&#xff0c;虽然是 lamp 用户创建的 abc 文件和 zimulu 目录&#xff0c;但它们的所属组都不是 lamp&#xff08;lamp 用户的所属组&#xff09;&#xff0c;而是 root&#xff08;dtest 目录的所属组&#xff09;。

 


9.14 Linux Stick BIT&#xff08;SBIT&#xff09;特殊权限

 

Sticky BIT&#xff0c;简称 SBIT 特殊权限&#xff0c;可意为粘着位、粘滞位、防删除位等。

SBIT 权限仅对目录有效&#xff0c;一旦目录设定了 SBIT 权限&#xff0c;则用户在此目录下创建的文件或目录&#xff0c;就只有自己和 root 才有权利修改或删除该文件。

也就是说&#xff0c;当甲用户以目录所属组或其他人的身份进入 A 目录时&#xff0c;如果甲对该目录有 w 权限&#xff0c;则表示对于 A 目录中任何用户创建的文件或子目录&#xff0c;甲都可以进行修改甚至删除等操作。但是&#xff0c;如果 A 目录设定有 SBIT 权限&#xff0c;那就大不一样啦&#xff0c;甲用户只能操作自己创建的文件或目录&#xff0c;而无法修改甚至删除其他用户创建的文件或目录。

举个例子&#xff0c;Linux 系统中&#xff0c;存储临时文件的 /tmp 目录就设定有 SBIT 权限&#xff1a;


[root&#64;localhost ~]# ll -d /tmp
drwxrwxrwt. 4 root root 4096 Apr 19 06:17 /tmp


可以看到&#xff0c;在其他人身份的权限设定中&#xff0c;原来的 x 权限位被 t 权限占用了&#xff0c;这就表示此目录拥有 SBIT 权限。通过下面一系列的命令操作&#xff0c;我们来具体看看 SBIT 权限对 /tmp 目录的作用。


[root&#64;localhost ~]# useradd lamp
[root&#64;localhost ~]# useradd lamp1

#建立测试用户lamp和lamp1&#xff0c;省略设置密码过程
[root&#64;localhost ~]# su -lamp
#切换为lamp用户
[lamp&#64;localhost ~]$ cd /tmp
[lamp&#64;localhost tmp]$ touch ftest

#建立测试文件
[lamp&#64;localhost tmp]$ll ftest
-rw-rw-r-- 1 lamp lamp Apr 19 06:36 ftest
[lamp&#64;localhost tmp]$ su - lamp1
#省略输入lamp1用户密码的过程&#xff0c;切换成lamp1用户
[lamp1 &#64;localhost ~]$ cd /tmp/
[lamp1 &#64;localhost tmp]$ rm -rf ftest

rm:cannot remove &#39;ftest&#39;:Operation not permitted


可以看到&#xff0c;虽然 /tmp 目录的权限设定是 777&#xff0c;但由于其具有 SBIT 权限&#xff0c;因此 lamp 用户在此目录创建的文件 ftest&#xff0c;lamp1 用户删除失败。

有兴趣的读者也可以尝试使用 lamp1 用户修改 lamp 用户创建的 ftest 文件中的内容&#xff0c;你会发现根本修改不了&#xff0c;这就是 SBIT 权限的作用。

 

 


9.15 Linux文件特殊权限&#xff08;SUID、SGID和SBIT&#xff09;的设置

 

前面已经学习 SUID、SGID、SBIT 特殊权限&#xff0c;以及各自的含义和功能&#xff0c;那么&#xff0c;如何给文件或目录手动设定这些特殊权限呢&#xff1f;

还是要依赖 chmod 命令。我们知道&#xff0c;使用 chmod 命令给文件或目录设定权限&#xff0c;有 2 种方式&#xff0c;分别是使用数字形式和字母形式。例如&#xff1a;


#数字形式
[root&#64;localhost ~]# chmod 755 ftest
#字母形式
[root&#64;localhost ~]# chmod u&#61;rwx,go&#61;rx ftest


给文件或目录设定 SUID、SGID 和 SBIT 特殊权限&#xff0c;也可以使用这 2 种形式。

有关 chmod 命令的用法&#xff0c;可以阅读《Linux chmod命令》一节。

我们知道&#xff0c;给 chmod 命令传递 3 个数字&#xff0c;即可实现给文件或目录设定普通权限。比如说&#xff0c;"755" 表示所有者拥有 rwx 权限&#xff0c;所属组拥有 rx 权限&#xff0c;其他人拥有 tx 权限。

给文件或目录设定特殊权限&#xff0c;只需在这 3 个数字之前增加一个数字位&#xff0c;用来放置给文件或目录设定的特殊权限&#xff0c;就这么简单。

因此&#xff0c;我们有必要知道 SUID、SGID、SBIT 分别对应的数字&#xff0c;如下所示&#xff1a;

4 --> SUID
2 --> SGID
1 --> SBIT

举个例子&#xff0c;如果要将一个文件权限设置为 -rwsr-xr-x&#xff0c;怎么办呢&#xff1f;此文件的普通权限为 755&#xff0c;另外&#xff0c;此文件还有 SUID 权限&#xff0c;因此只需在 755 的前面&#xff0c;加上 SUID 对应的数字 4 即可。也就是说&#xff0c;只需执行chmod 4755 文件名命令&#xff0c;就完成了-rwsr-xr-x 权限的设定。

关于 -rwsr-xr-x 的普通权限是 755&#xff0c;你可以这样理解&#xff0c;标记有 s 和 t 的权限位&#xff0c;隐藏有 x 权限&#xff0c;对此&#xff0c;本节后续会给出更详细的解释。

同样的道理&#xff0c;如果某文件拥有 SUID 和 SGID 权限&#xff0c;则只需要给 chmod 命令传递 6---&#xff08;- 表示数字&#xff09;即可&#xff1b;如果某目录拥有 SGID 和 SBIT&#xff0c;只需要给 chmod 命令传递 3--- 即可。

注意&#xff0c;不同的特殊权限&#xff0c;作用的对象是不同的&#xff0c;SUID 只对可执行文件有效&#xff1b;SGID 对可执行文件和目录都有效&#xff1b;SBIT 只对目录有效。当然&#xff0c;你也可以给文件设置 7---&#xff0c;也就是将 SUID、SGID、SBIT赋予一个文件或目录&#xff0c;例如&#xff1a;


[root&#64;localhost ~]# chmod 7777 ftest
#一次赋予SetUID、SetGID和SBIT权限
[root&#64;localhost ~]# ll ftest
-rwsrwsrwt. 1 root root Apr 19 23:54 ftest


执行过程虽然没有报错&#xff0c;但这样做&#xff0c;没有任何实际意义。

除了赋予 chmod 命令 4 个数字设定特殊权限&#xff0c;还可以使用字母的形式。例如&#xff0c;可以通过 "u&#43;s" 给文件赋予 SUID 权限&#xff1b;通过 "g&#43;s" 给文件或目录赋予 SGID 权限&#xff1b;通过 "o&#43;t" 给目录赋予 SBIT 权限。

举一个例子&#xff1a;


[root&#64;localhost ~]#chmod u&#43;s, g&#43;s, o&#43;t ftest
#设置特殊权限
[root&#64;localhost ~]# ll ftest
-rwsr-sr-t. 1 root root Apr 19 23:54 ftest
[root&#64;localhost ~]# chmod u-s, g-s, o-t ftest
#取消特殊权限
[root&#64;localhost ~]# ll ftest
-rwxr-xr-x. 1 root root Apr 19 23:54 ftest


例子中&#xff0c;通过字母的形式成功给 ftest 文件赋予了 3 种特殊权限&#xff0c;此做法仅为验证字母形式的可行性&#xff0c;对 ftest 文件来说&#xff0c;并无实际意义。

细心的读者可能发现这样一个问题&#xff0c;使用 chmod 命令给文件或目录赋予特殊权限时&#xff0c;原文件或目录中存在的 x 权限会被替换成 s 或 t&#xff0c;而当我们使用 chmod 命令消除文件或目录的特殊权限时&#xff0c;原本消失的 x 权限又会显现出来。

这是因为&#xff0c;无论是 SUID、SGID 还是 SBIT&#xff0c;它们只针对具有 x 权限的文件或目录有效。没有 x 权限的文件或目录&#xff0c;即便赋予特殊权限&#xff0c;也无法发挥它们的功能&#xff0c;没有任何意义。

例如&#xff0c;我们就是要给不具有 x 权限的文件或目录赋予特殊权限&#xff0c;看看有什么效果&#xff1a;


[root&#64;localhost ~]# chmod 7666 ftest
[root&#64;localhost ~]# ll ftest

-rwSrwSrwT. 1 root root Apr 23:54 ftest


可以看到&#xff0c;相应的权限位会被标记为 S&#xff08;大写&#xff09;和 T&#xff08;大写&#xff09;&#xff0c;指的就是设置的 SUID、SGID 和 SBIT 权限没有意义。

 


9.16 Linux修改文件或目录的隐藏属性&#xff08;chattr命令&#xff09;

 

管理 Linux 系统中的文件和目录&#xff0c;除了可以设定普通权限和特殊权限外&#xff0c;还可以利用文件和目录具有的一些隐藏属性。

chattr 命令&#xff0c;专门用来修改文件或目录的隐藏属性&#xff0c;只有 root 用户可以使用。该命令的基本格式为&#xff1a;

[root&#64;localhost ~]# chattr [&#43;-&#61;] [属性] 文件或目录名

&#43; 表示给文件或目录添加属性&#xff0c;- 表示移除文件或目录拥有的某些属性&#xff0c;&#61; 表示给文件或目录设定一些属性。

表 1 列出了常用的一些属性及功能。


表 1 chattr 命令常用的属性选项及功能
属性选项功能
i如果对文件设置 i 属性&#xff0c;那么不允许对文件进行删除、改名&#xff0c;也不能添加和修改数据&#xff1b;
如果对目录设置 i 属性&#xff0c;那么只能修改目录下文件中的数据&#xff0c;但不允许建立和删除文件&#xff1b;
a如果对文件设置 a 属性&#xff0c;那么只能在文件中増加数据&#xff0c;但是不能删除和修改数据&#xff1b;
如果对目录设置 a 属性&#xff0c;那么只允许在目录中建立和修改文件&#xff0c;但是不允许删除文件&#xff1b;
u设置此属性的文件或目录&#xff0c;在删除时&#xff0c;其内容会被保存&#xff0c;以保证后期能够恢复&#xff0c;常用来防止意外删除文件或目录。
s和 u 相反&#xff0c;删除文件或目录时&#xff0c;会被彻底删除&#xff08;直接从硬盘上删除&#xff0c;然后用 0 填充所占用的区域&#xff09;&#xff0c;不可恢复。


【例 1】 给文件赋予 i 属性。


[root&#64;localhost ~]# touch ftest
#建立测试文件
[root&#64;localhost ~]# chattr &#43;i ftest
[root&#64;localhost ~]# rm -rf ftest

rm:cannot remove &#39;ftest&#39;:Operation not permitted
#无法删除"ftesr"&#xff0c;操作不允许
#被赋予i属性后&#xff0c;root不能删除
[root&#64;localhost ~]# echo 111>>ftest
bash:ftest:Permission denied
#权限不够&#xff0c;不能修改文件中的数据


可以看到&#xff0c;设置有 i 属性的文件&#xff0c;即便是 root 用户&#xff0c;也无法删除和修改数据。

【例 2】为目录赋予 i 属性。


[root&#64;localhost ~]# mkdir dtest
#建立测试目录
[root&#64;localhost dtest]# touch dtest/abc
#再建立一个测试文件abc
[root&#64;localhost ~]# chattr &#43;i dtest
#给目录赋予i属性
[root&#64;localhost ~]# cd dtest
[root&#64;localhost dtest]# touch bed

touch: cannot touch &#39;bed&#39;:Permission denied
#无法创建"bcd"&#xff0c;权限不够&#xff0c;dtest目录不能新建文件
[root&#64;localhost dtest]# echo 11>>abc
[root&#64;localhost dtest]# cat abc

11
#可以修改文件内容
[root&#64;localhost dtest]# rm -rf abc
rm: cannot remove &#39;abc&#39;: Permission denied
#无法删除"abc"&#xff0c;权限不够


一旦给目录设置 i 属性&#xff0c;即使是 root 用户&#xff0c;也无法在目录内部新建或删除文件&#xff0c;但可以修改文件内容。

给设置有 i 属性的文件删除此属性也很简单&#xff0c;只需将 chattr 命令中 &#43; 改为 - 即可。


【例 3】演示 a 属性的作用。
假设有这样一种应用&#xff0c;我们每天自动实现把服务器的日志备份到指定目录&#xff0c;备份目录可设置 a 属性&#xff0c;变为只可创建文件而不可删除。命令如下&#xff1a;


[root&#64;localhost ~]# mkdir -p /back/log
#建立备份目录
[root&#64;localhost ~]# chattr &#43;a /back/log
#赋予a属性
[root&#64;localhost ~]# cp /var/log/messages /back/log
#可以复制文件和新建文件到指定目录中
[root&#64;localhost ~]# rm -rf /back/log/messages
rm: cannot remove &#39;/back/log/messages&#39;: Permission denied
#无法删除 /back/log/messages&#xff0c;操作不允许



注意&#xff0c;通常情况下&#xff0c;不要使用 chattr 命令修改 /、/dev/、/tmp/、/var/ 等目录的隐藏属性&#xff0c;很容易导致系统无法启动。另外&#xff0c;chatrr 命令常与 lsattr 命令合用&#xff0c;前者修改文件或目录的隐藏属性&#xff0c;后者用于查看是否修改成功。有关 lsattr 命令&#xff0c;放到下节讲解。

 

 

 


9.17 Linux查看文件或目录的隐藏属性&#xff08;lsattr命令&#xff09;

 

使用 chattr 命令配置文件或目录的隐藏属性后&#xff0c;可以使用 lsattr 命令查看。

lsattr 命令&#xff0c;用于显示文件或目录的隐藏属性&#xff0c;其基本格式如下&#xff1a;

[root&#64;localhost ~]# lsattr [选项] 文件或目录名


常用选项有以下 3 种&#xff1a;


  • -a&#xff1a;后面不带文件或目录名&#xff0c;表示显示所有文件和目录&#xff08;包括隐藏文件和目录&#xff09;
  • -d&#xff1a;如果目标是目录&#xff0c;只会列出目录本身的隐藏属性&#xff0c;而不会列出所含文件或子目录的隐藏属性信息&#xff1b;
  • -R&#xff1a;和 -d 恰好相反&#xff0c;作用于目录时&#xff0c;会连同子目录的隐藏信息数据也一并显示出来。


【例 1】


[root&#64;localhost ~]# touch attrtest
-----------e- attrtest
[root&#64;localhost ~]# chattr &#43;aij attrtest
[root&#64;localhost ~]# lsattr attrtest

----ia---j-e- attrtest


注意&#xff0c;不使用任何选项&#xff0c;仅用于显示文件的隐藏信息&#xff0c;不适用于目录。

【例 2】


[root&#64;localhost ~]#lsattr -a
-----------e- ./.
------------- ./..
-----------e- ./.gconfd
-----------e- ./.bashrc
...



【例 3】


[root&#64;localhost ~]#lsattr -d /back/log
-----a------e- /back/log
#查看/back/log目录&#xff0c;其拥有a和e属性


 

 


9.18 Linux sudo命令&#xff08;包含和su命令的对比&#xff09;

 

我们知道&#xff0c;使用 su 命令可以让普通用户切换到 root 身份去执行某些特权命令&#xff0c;但存在一些问题&#xff0c;比如说&#xff1a;


  • 仅仅为了一个特权操作就直接赋予普通用户控制系统的完整权限&#xff1b;
  • 当多人使用同一台主机时&#xff0c;如果大家都要使用 su 命令切换到 root 身份&#xff0c;那势必就需要 root 的密码&#xff0c;这就导致很多人都知道 root 的密码&#xff1b;


考虑到使用 su 命令可能对系统安装造成的隐患&#xff0c;最常见的解决方法是使用 sudo 命令&#xff0c;此命令也可以让你切换至其他用户的身份去执行命令。

相对于使用 su 命令还需要新切换用户的密码&#xff0c;sudo 命令的运行只需要知道自己的密码即可&#xff0c;甚至于&#xff0c;我们可以通过手动修改 sudo 的配置文件&#xff0c;使其无需任何密码即可运行。

sudo 命令默认只有 root 用户可以运行&#xff0c;该命令的基本格式为&#xff1a;

[root&#64;localhost ~]# sudo [-b] [-u 新使用者账号] 要执行的命令

常用的选项与参数&#xff1a;


  • -b  &#xff1a;将后续的命令放到背景中让系统自行运行&#xff0c;不对当前的 shell 环境产生影响。
  • -u  &#xff1a;后面可以接欲切换的用户名&#xff0c;若无此项则代表切换身份为 root 。
  • -l&#xff1a;此选项的用法为 sudo -l&#xff0c;用于显示当前用户可以用 sudo 执行那些命令。


【例 1】


[root&#64;localhost ~]#  grep sshd /etc/passwd
sshd:x:74:74:privilege-separated SSH:/var/empty/sshd:/sbin.nologin
[root&#64;localhost ~]#  sudo -u sshd touch /tmp/mysshd
[root&#64;localhost ~]#  ll /tmp/mysshd

-rw-r--r-- 1 sshd sshd 0 Feb 28 17:42 /tmp/mysshd


本例中&#xff0c;无法使用 su - sshd 的方式成功切换到 sshd 账户中&#xff0c;因为此用户的默认 Shell 是 /sbin/nologin。这时就显现出 sudo 的优势&#xff0c;我们可以使用 sudo 以 sshd 的身份在 /tmp 目录下创建 mysshd 文件&#xff0c;可以看到&#xff0c;新创建的 mysshd 文件的所有者确实是 sshd。

【例 2】


[root&#64;localhost ~]#  sudo -u vbird1 sh -c "mkdir ~vbird1/www; cd ~vbird1/www; \
>  echo &#39;This is index.html file&#39; > index.html"
[root&#64;localhost ~]#  ll -a ~vbird1/www
drwxr-xr-x 2 vbird1 vbird1 4096 Feb 28 17:51 .
drwx------ 5 vbird1 vbird1 4096 Feb 28 17:51 ..
-rw-r--r-- 1 vbird1 vbird1   24 Feb 28 17:51 index.html


这个例子中&#xff0c;使用 sudo 命令切换至 vbird1 身份&#xff0c;并运行 sh -c 的方式来运行一连串的命令。

前面说过&#xff0c;默认情况下 sudo 命令只有 root 身份可以使用&#xff0c;那么&#xff0c;如何让普通用户也能使用它呢&#xff1f;

解决这个问题之前&#xff0c;先给大家分析一下 sudo 命令的执行过程。sudo命令的运行&#xff0c;需经历如下几步&#xff1a;


  • 当用户运行 sudo 命令时&#xff0c;系统会先通过 /etc/sudoers 文件&#xff0c;验证该用户是否有运行 sudo 的权限&#xff1b;
  • 确定用户具有使用 sudo 命令的权限后&#xff0c;还要让用户输入自己的密码进行确认。出于对系统安全性的考虑&#xff0c;如果用户在默认时间内&#xff08;默认是 5 分钟&#xff09;不使用 sudo 命令&#xff0c;此后使用时需要再次输入密码&#xff1b;
  • 密码输入成功后&#xff0c;才会执行 sudo 命令后接的命令。


显然&#xff0c;能否使用 sudo 命令&#xff0c;取决于对 /etc/sudoers 文件的配置&#xff08;默认情况下&#xff0c;此文件中只配置有 root 用户&#xff09;。所以接下来&#xff0c;我们学习对 /etc/sudoers 文件进行合理的修改。


sudo命令的配置文件/etc/sudoers

修改 /etc/sudoers&#xff0c;不建议直接使用 vim&#xff0c;而是使用 visudo。因为修改 /etc/sudoers 文件需遵循一定的语法规则&#xff0c;使用 visudo 的好处就在于&#xff0c;当修改完毕 /etc/sudoers 文件&#xff0c;离开修改页面时&#xff0c;系统会自行检验 /etc/sudoers 文件的语法。

因此&#xff0c;修改 /etc/sudoers 文件的命令如下&#xff1a;


[root&#64;localhost ~]# visudo
…省略部分输出…
root ALL&#61;(ALL) ALL  <--大约 76 行的位置
# %wheel ALL&#61;(ALL) ALL   <--大约84行的位置
#这两行是系统为我们提供的模板&#xff0c;我们参照它写自己的就可以了
…省略部分输出…


通过 visudo 命令&#xff0c;我们就打开了 /etc/sudoers 文件&#xff0c;可以看到如上显示的 2 行信息&#xff0c;这是系统给我们提供的 2 个模板&#xff0c;分别用于添加用户和群组&#xff0c;使其能够使用 sudo 命令。

这两行模板的含义分为是&#xff1a;


root ALL&#61;(ALL) ALL
#用户名 被管理主机的地址&#61;(可使用的身份) 授权命令(绝对路径)
#%wheel ALL&#61;(ALL) ALL
#%组名 被管理主机的地址&#61;(可使用的身份) 授权命令(绝对路径)


表 1 对以上 2 个模板的各部分进行详细的说明。


表 1 /etc/sudoers 用户和群组模板的含义
模块含义
用户名或群组名表示系统中的那个用户或群组&#xff0c;可以使用 sudo 这个命令。
被管理主机的地址用户可以管理指定 IP 地址的服务器。这里如果写 ALL&#xff0c;则代表用户可以管理任何主机&#xff1b;如果写固定 IP&#xff0c;则代表用户可以管理指定的服务器。如果我们在这里写本机的 IP 地址&#xff0c;不代表只允许本机的用户使用指定命令&#xff0c;而是代表指定的用户可以从任何 IP 地址来管理当前服务器。
可使用的身份就是把来源用户切换成什么身份使用&#xff0c;&#xff08;ALL&#xff09;代表可以切换成任意身份。这个字段可以省略。
授权命令表示 root 把什么命令命令授权给用户&#xff0c;换句话说&#xff0c;可以用切换的身份执行什么命令。需要注意的是&#xff0c;此命令必须使用绝对路径写。默认值是 ALL&#xff0c;表示可以执行任何命令。


【例 3】
授权用户 lamp 可以重启服务器&#xff0c;由 root 用户添加&#xff0c;可以在 /etc/sudoers 模板下添加如下语句&#xff1a;


[root&#64;localhost ~]# visudo
lamp ALL&#61;/sbin/shutdown -r now


注意&#xff0c;这里也可以写多个授权命令&#xff0c;之间用逗号分隔。用户 lamp 可以使用 sudo -l 查看授权的命令列表&#xff1a;


[root&#64;localhost ~]# su - lamp
#切换成lamp用户
[lamp&#64;localhost ~]$ sudo -l
[sudo] password for lamp:
#需要输入lamp用户的密码
User lamp may run the following commands on this host:
(root) /sbin/shutdown -r now


可以看到&#xff0c;lamp 用户拥有了 shutdown -r now 的权限。这时&#xff0c;lamp 用户就可以使用 sudo 执行如下命令重启服务器&#xff1a;

[lamp&#64;localhost ~]$ sudo /sbin/shutdown -r now

再次强调&#xff0c;授权命令要使用绝对路径&#xff08;或者把 /sbin 路径导入普通用户 PATH 路径中&#xff0c;不推荐使用此方式&#xff09;&#xff0c;否则无法执行。

【例 4】
假设现在有 pro1&#xff0c;pro2&#xff0c;pro3 这 3 个用户&#xff0c;还有一个 group 群组&#xff0c;我们可以通过在 /etc/sudoers 文件配置 wheel 群组信息&#xff0c;令这 3 个用户同时拥有管理系统的权限。

首先&#xff0c;向 /etc/sudoers 文件中添加群组配置信息&#xff1a;


[root&#64;localhost ~]# visudo
....(前面省略)....
%group     ALL&#61;(ALL)    ALL
#在 84 行#wheel这一行后面写入


此配置信息表示&#xff0c;group 这个群组中的所有用户都能够使用 sudo 切换任何身份&#xff0c;执行任何命令。接下来&#xff0c;我们使用 usermod 命令将 pro1 加入 group 群组&#xff0c;看看有什么效果&#xff1a;


[root&#64;localhost ~]# usermod -a -G group pro1
[pro1&#64;localhost ~]# sudo tail -n 1 /etc/shadow <&#61;&#61;注意身份是 pro1
....(前面省略)....
Password:  <&#61;&#61;输入 pro1 的口令喔&#xff01;
pro3:$1$GfinyJgZ$9J8IdrBXXMwZIauANg7tW0:14302:0:99999:7:::
[pro2&#64;localhost ~]# sudo tail -n 1 /etc/shadow <&#61;&#61;注意身份是 pro2
Password:
pro2 is not in the sudoers file.  This incident will be reported.
#此错误信息表示 pro2 不在 /etc/sudoers 的配置中。


可以看到&#xff0c;由于 pro1 加入到了 group 群组&#xff0c;因此 pro1 就可以使用 sudo 命令&#xff0c;而 pro2 不行。同样的道理&#xff0c;如果我们想让 pro3 也可以使用 sudo 命令&#xff0c;不用再修改 /etc/sudoers 文件&#xff0c;只需要将 pro3 加入 group 群组即可。

 

 


9.19 结合实例分析Linux权限对指令执行的影响

 

通过本章的学习我们知道&#xff0c;权限对于使用者账号是非常重要的&#xff0c;因为它可以限制使用者是否能读取、建立、删除、修改文件或目录。

本节将结合前面章节学到的有关文件系统管理的指令&#xff0c;通过几个实例向大家说明&#xff0c;权限对 Linux 指令执行的重要性。

【实例 1】
让当前用户进入某指定目录&#xff0c;可以使用什么指令&#xff1f;需要具备何种权限&#xff1f;


用户可以使用 cd 指令&#xff0c;同时要想使此命令成功执行&#xff0c;需要用户对要进入的目录具有 x 权限。另外&#xff0c;如果用户还想要在此目录中使用 ls 命令&#xff0c;还需要对此目录具有 r 权限。



【实例 2】
如果想在某目录内读取一个文件&#xff0c;可以使用什么指令&#xff1f;需要具备何种权限&#xff1f;


用户可以使用 cat、more、less 等指令&#xff0c;并且该用户对此目录至少需要具有 x 权限&#xff0c;对读取的文件需要具有 r 权限。



【实例 3】
如果想修改一个文件&#xff0c;可以使用什么指令&#xff1f;需要具备何种权限&#xff1f;


可以使用 vim 编辑器&#xff0c;对于权限方面&#xff0c;用户至少需要对该文件所在目录具有 x 权限&#xff0c;同时对该文件具有 r、w 权限。



【实例 4】
要想让使用者 Linuxer 能够执行 cp /dir1/file1 /dir2 的指令&#xff0c;则 Linuxer 需要对 dir1、file1、dir2 分别具备哪些权限。


执行 cp 命令时&#xff0c;Linuxer 要能够读取指定文件&#xff0c;并且能够写入目标文件&#xff0c;因此&#xff1a;

  • dir1&#xff1a;至少需要有 x 权限&#xff1b;
  • file1&#xff1a;至少需要有 r 权限&#xff1b;
  • dir2&#xff1a;至少需要有 w&#xff0c;x 权限。


【实例 5】
有一个文件&#xff0c;其绝对路径为 /home/student/www/index.html&#xff0c;其中各个相关文件或者目录的权限分别如下所示&#xff1a;


drwxr-xr-x 23    root     root 4096 Sep 22 12:09 /
drwxr-xr-x  6    root     root 4096 Sep 22 02:09 /home
drwx------  6 student student 4096 Sep 22 02:10 /home/student
drwxr-xr-x  6 student student 4096 Sep 22 02:10 /home/student/www
drwxr--r--  6 student student  369 Sep 22 02:11 /home/student/www/index.html


那么&#xff0c;当使用 test 这个账号&#xff08;不属于 student 群组&#xff09;能够成功读取 index.html 这个文件呢&#xff1f;


因为目录结构是由根目录一层一层读取的&#xff0c;通过分析以上各个目录和文件的权限得知&#xff0c;对于 vbird 账号来说&#xff0c;它可以进入 /home&#xff0c;但却不可以进入 /home/student&#xff0c;因此可以判定&#xff0c;vbird 无法成功读取 index.html 文件中的内容。


 

 

 


推荐阅读
  • 本文介绍了如何使用python从列表中删除所有的零,并将结果以列表形式输出,同时提供了示例格式。 ... [详细]
  • 本文介绍了使用postman进行接口测试的方法,以测试用户管理模块为例。首先需要下载并安装postman,然后创建基本的请求并填写用户名密码进行登录测试。接下来可以进行用户查询和新增的测试。在新增时,可以进行异常测试,包括用户名超长和输入特殊字符的情况。通过测试发现后台没有对参数长度和特殊字符进行检查和过滤。 ... [详细]
  • 数字账号安全与数据资产问题的研究及解决方案
    本文研究了数字账号安全与数据资产问题,并提出了解决方案。近期,大量QQ账号被盗事件引起了广泛关注。欺诈者对数字账号的价值认识超过了账号主人,因此他们不断攻击和盗用账号。然而,平台和账号主人对账号安全问题的态度不正确,只有用户自身意识到问题的严重性并采取行动,才能推动平台优先解决这些问题。本文旨在提醒用户关注账号安全,并呼吁平台承担起更多的责任。令牌云团队对此进行了长期深入的研究,并提出了相应的解决方案。 ... [详细]
  • 本文介绍了在CentOS上安装Python2.7.2的详细步骤,包括下载、解压、编译和安装等操作。同时提供了一些注意事项,以及测试安装是否成功的方法。 ... [详细]
  • 本文讨论了微软的STL容器类是否线程安全。根据MSDN的回答,STL容器类包括vector、deque、list、queue、stack、priority_queue、valarray、map、hash_map、multimap、hash_multimap、set、hash_set、multiset、hash_multiset、basic_string和bitset。对于单个对象来说,多个线程同时读取是安全的。但如果一个线程正在写入一个对象,那么所有的读写操作都需要进行同步。 ... [详细]
  • Spring源码解密之默认标签的解析方式分析
    本文分析了Spring源码解密中默认标签的解析方式。通过对命名空间的判断,区分默认命名空间和自定义命名空间,并采用不同的解析方式。其中,bean标签的解析最为复杂和重要。 ... [详细]
  • Nginx使用(server参数配置)
    本文介绍了Nginx的使用,重点讲解了server参数配置,包括端口号、主机名、根目录等内容。同时,还介绍了Nginx的反向代理功能。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • Centos7.6安装Gitlab教程及注意事项
    本文介绍了在Centos7.6系统下安装Gitlab的详细教程,并提供了一些注意事项。教程包括查看系统版本、安装必要的软件包、配置防火墙等步骤。同时,还强调了使用阿里云服务器时的特殊配置需求,以及建议至少4GB的可用RAM来运行GitLab。 ... [详细]
  • 推荐系统遇上深度学习(十七)详解推荐系统中的常用评测指标
    原创:石晓文小小挖掘机2018-06-18笔者是一个痴迷于挖掘数据中的价值的学习人,希望在平日的工作学习中,挖掘数据的价值, ... [详细]
  • Android工程师面试准备及设计模式使用场景
    本文介绍了Android工程师面试准备的经验,包括面试流程和重点准备内容。同时,还介绍了建造者模式的使用场景,以及在Android开发中的具体应用。 ... [详细]
  • 网卡工作原理及网络知识分享
    本文介绍了网卡的工作原理,包括CSMA/CD、ARP欺骗等网络知识。网卡是负责整台计算机的网络通信,没有它,计算机将成为信息孤岛。文章通过一个对话的形式,生动形象地讲述了网卡的工作原理,并介绍了集线器Hub时代的网络构成。对于想学习网络知识的读者来说,本文是一篇不错的参考资料。 ... [详细]
  • 本文介绍了使用Python编写购物程序的实现步骤和代码示例。程序启动后,用户需要输入工资,并打印商品列表。用户可以根据商品编号选择购买商品,程序会检测余额是否充足,如果充足则直接扣款,否则提醒用户。用户可以随时退出程序,在退出时打印已购买商品的数量和余额。附带了完整的代码示例。 ... [详细]
  • python3 nmap函数简介及使用方法
    本文介绍了python3 nmap函数的简介及使用方法,python-nmap是一个使用nmap进行端口扫描的python库,它可以生成nmap扫描报告,并帮助系统管理员进行自动化扫描任务和生成报告。同时,它也支持nmap脚本输出。文章详细介绍了python-nmap的几个py文件的功能和用途,包括__init__.py、nmap.py和test.py。__init__.py主要导入基本信息,nmap.py用于调用nmap的功能进行扫描,test.py用于测试是否可以利用nmap的扫描功能。 ... [详细]
  • springboot启动不了_Spring Boot + MyBatis 多模块搭建教程
    作者:枫本非凡来源:www.cnblogs.comorzlinp9717399.html一、前言1、创建父工程最近公司项目准备开始重构,框 ... [详细]
author-avatar
abc
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有