[笔记]快乐的Linux命令行《九》权限

29 阅读11分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第10天,点击查看活动详情

@TOC

前言

unix、linux 它们不仅是多任务系统,而且也是多用户系统,这意味着多个用户可以在同一时间使用同一台计算机。只有一个键盘和一个监视器,但是它仍然可以被多个用户使用,远程用户可以通过ssh远程登陆操作系统,并且运行图形界面应用程序,并且图形化的输出结果会出现在远端的显示器上。

但多用户行为往往会造成混乱和崩溃,为了解决这些问题,那么必须发明一种方法来阻止用户彼此之间受到影响。毕竟,一个用户的行为不能导致计算机崩溃,也不能乱动属于另一个用户的文件。

在这一章中,我们将看看这一系统安全的本质部分,会介绍以下命令:

  • id –显示用户身份号
  • chmod –更改文件模式
  • umask –设置默认的文件权限
  • su –以另一个用户的身份来运行 shell
  • sudo –以另一个用户的身份来执行命令
  • chown –更改文件所有者
  • chgrp –更改文件组所有权
  • passwd –更改用户密码

一、权限

1.1 拥有者,组成员,和其他人

当我们试图查看一个像/etc/shadow 那样的文件的时候,我们会遇到一个问题:

[me@linuxbox ~]$ file /etc/shadow
/etc/shadow: regular file, no read permission

[me@linuxbox ~]$ less /etc/shadow
/etc/shadow: Permission denied

/etc/shadow: Permission denied

产生这种错误信息的原因是,作为一个普通用户,我们没有权限来读取这个文件。

在 Unix 安全模型中,一个用户可能拥有文件和目录。当一个用户拥有一个文件或目录时,用户对这个文件或目录的访问权限拥有控制权。用户,反过来,又属于一个由一个或多个用户组成的用户组,用户组成员由文件和目录的所有者授予对文件和目录的访问权限。除了对一个用户组授予权限之外,文件所有者可能会给每个人一些权限,在 Unix 术语中,每个人是指整个世界。

可以用 id 命令,来找到关于你自己身份的信息:

[me@linuxbox ~]$ id
uid=500(me) gid=500(me) groups=500(me)

让我们看一下输出结果。

当用户创建帐户之后,系统会给用户分配一个号码,叫做用户 ID 或者 uid,然后,为了符合人类的习惯,这个 ID 映射到一个用户名。系统又会给这个用户分配一个原始的组 ID 或者是 gid,这个gid 可能属于另外的组。

上面的例子来自于 Fedora 系统,比方说 Ubuntu 的输出结果可能看起来有点儿不同:

[me@linuxbox ~]$ id
uid=1000(me) gid=1000(me)
groups=4(adm),20(dialout),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),108(lpadmin),114(admin),1000(me)

正如我们能看到的,两个系统中用户的 uid 和 gid 号码是不同的。

原因很简单,因为Fedora 系统从 500 开始进行普通用户帐户的编号,而 Ubuntu 从 1000 开始。我们也能看到Ubuntu 的用户属于更多的用户组。这和 Ubuntu 管理系统设备和服务权限的方式有关系。

那么这些信息来源于哪里呢? 用户帐户定义在/etc/passwd 文件里面,用户组定义在/etc/group 文件里面。

当用户帐户和用户组创建以后,这些文件随着文件/etc/shadow 的变动而修改,文件/etc/shadow 包含了关于 用户密码的信息。

对于每个用户帐号,文件/etc/passwd 定义了用户(登录)名,uid,gid,帐号的真实姓名,主目录,和登录 shell。

如果你查看一下文件/etc/passwd 和文件/etc/group的内容,你会注意到除了普通用户帐号之外,还有超级用户(uid 0)帐号,和各种各样的系统用户

许多像 Unix 的系统会把普通用户分配到一个公共的用户组中,例如“users”,现在的Linux 会创建一个独一无二的,只有一个成员的用户组,这个用户组与用户同名。这样使某种类型的权限分配更容易些。

1.2 读取,写入,和执行

对于文件和目录的访问权力是根据读访问,写访问,和执行访问来定义的。

看一下 ls 命令的输出结果:

[me@linuxbox ~]$ > foo.txt
[me@linuxbox ~]$ ls -l foo.txt
-rw-rw-r-- 1 me me 0 2008-03-06 14:52 foo.txt

-rw-rw-r-- 1 me me 0 2008-03-06 14:52 foo.txt

列表的前十个字符(标红部分)是文件的属性。

第一个字符 -就表示是普通文件,具体如下表:

image.png

image.png

剩下的九个字符,叫做文件模式,代表着文件所有者文件组所有者,和其他人的读,写,执行权限。

rw-表示文件所有者的读r写w (无执行)

rw-表示文件组所有者的读r写w(无执行)

r--表示其他人只读(无 写权限和执行权限)

当设置文件模式后,r,w,x 模式属性对文件和目录会产生一些影响:

  • 读取权限(r)具有读取\阅读文件内容权限
  1. 只能使用查看类命令cat、head、tail、less、more
  • 写入权限(w)具有新增、修改文件内容的权限
  1. 使用vim编辑会提示权限拒绝, 但可强制保存,会覆盖文件的所有内容
  2. 使用echo命令重定向的方式可以往文件内写入数据, >>可以进行追加
  3. 不能删除文件,因为删除文件看的不是文件的属性, 需要看上级目录是否有w的权限
  • 执行权限(x)具有执行文件的权限
  1. 执行权限什么用都没有
  2. 如果普通用户需要执行文件,需要配合r权限 rx (命令) rw(配置文件) r(单纯的普通只看不改不执行) rx (进入文件,查看文件)删除文件相关看上级目录即使rwx也不能直接删除,移动文件

1.3 chmod -更改文件模式

更改文件或目录的模式(权限),可以利用 chmod 命令。

注意只有文件的所有者或者超级用户才能更改文件或目录的模式。

chmod 命令支持两种不同的方法来改变文件模式:

  • 八进制数字表示法
  • 符号表示法。

八进制数字表示法

首先我们讨论一下八进制数字表示法。 究竟什么是八进制?

八进制:即逢八进一, 在八进制中,逢八进一。 用数字 0 到 7 来计数,像这样:

0, 1, 2, 3, 4, 5, 6, 7, 10, 11, 12, 13, 14, 15, 16, 17, 20, 21. . .

通过八进制表示法,我们使用八进制数字来设置所期望的权限模式。

因为每个八进制数字代表了 3 个二进制数字,这种对应关系,正好映射到用来存储文件模式所使用的方案上。

下表展示了我们所要表达的意思:

image.png

通过使用 3 个八进制数字,我们能够设置文件所有者,用户组,和其他人的权限:

[me@linuxbox ~]$ > foo.txt
[me@linuxbox ~]$ ls -l foo.txt
-rw-rw-r-- 1 me me 0 2008-03-06 14:52 foo.txt
[me@linuxbox ~]$ chmod 600 foo.txt
[me@linuxbox ~]$ ls -l foo.txt
-rw------- 1 me me 0 2008-03-06 14:52 foo.txt

通过传递参数“600”,我们能够设置文件所有者的权限为读写权限,而删除用户组和其他人的所有权限。虽然八进制到二进制的映射看起来不方便,但通常只会用到一些常见的映射关系:7 (rwx),6 (rw-),5 (r-x),4 (r--),and 0 (-–)。

符号表示法

chmod 命令支持一种符号表示法,来指定文件模式。符号表示法分为三部分:更改会影响

谁,要执行哪个操作,要设置哪种权限。通过字符“u”,“g”,“o”,and “a”的组合来指定要影响的对象,

如下所示:

image.png

如果没有指定字符,则假定使用“all”。执行的操作可能是一个“+”字符,表示加上一个权限,一个“-”,表示删掉一个权限,或者是一个“=”,表示只有指定的权限可用,其它所有的权限被删除。

权限由“r”, “w”, and “x”来指定。这里是一些符号表示法的实例:

image.png

符号表示法的优点是:

  1. 允许你设置文件模式的单个组成部分的属性,而没有影响其他的部分。

看一下 chmod 命令的手册页,可以得到更详尽的信息和 chmod 命令的各个选项。

要注意“--recursive”(或 -R)选项:

它可以同时作用于文件和目录,所以它并不是如我们期望的那么有用处,因为我们很少希望文件和目录拥有同样的权限。

1.4 借助 GUI 来设置文件模式(待完善)

通过GUI界面设置权限

1.5 umask -设置默认权限(待完善)

当创建一个文件时,umask 命令控制着文件的默认权限

umask 命令使用八进制表示法来表达从文件模式属性中删除一个位掩码。

大家看下面的例子:

[me@linuxbox ~]$ rm -f foo.txt
[me@linuxbox ~]$ umask
0002
[me@linuxbox ~]$ > foo.txt
[me@linuxbox ~]$ ls -l foo.txt
-rw-rw-r-- 1 me me 0 2008-03-06 14:53 foo.txt

1.6 更改身份

在不同的时候,我们会发现很有必要具有另一个用户的身份。经常地,我们想要得到超级用户特权,来执行一些管理任务,但是也有可能 “变为” 另一个普通用户,比如说测试一个帐号。

有三种方式,可以拥有多重身份:

  1. 注销系统并以其他用户身份重新登录系统。
  2. 使用 su 命令。
  3. 使用 sudo 命令。

su 命令允许你,假定为另一个用户的身份,以这个用户的 ID 启动一个新的 shell 会话,或者是以这个用户的身份来发布一个命令。

sudo 命令允许一个管理员设置一个叫做/etc/sudoers 的配置文件,并且定义了一些具体命令,在假定的身份下,特殊用户可以执行这些命令。

1.7 su -以其他用户身份和组 ID 运行一个 shell

su 命令用来以另一个用户的身份来启动 shell。

命令语法:

su [-[l]] [user]

启动超级用户(root)的 shell,我们可以这样做:

[me@linuxbox ~]$ su -
Password:
[root@linuxbox ~]#

按下回车符之后,shell 提示我们输入超级用户的密码。如果密码输入正确,出现一个新的shell 提示符,这表明这个 shell 具有超级用户特权(提示符的末尾字符是 “#” 而不是”$”),并且当前工作目录是超级用户的主目录(通常是/root)。一旦进入一个新的 shell,我们能执行超级用户所使用的命令。

当工作完成后,输入 “exit”,则返回到原来的 shell:

[root@linuxbox ~]# exit
[me@linuxbox ~]$

以这样的方式使用 su 命令,也可以只执行单个命令,(而不启动一个新的可交互的 shell):

su -c 'command'

使用这种模式,命令传递到一个新 shell 中执行。把命令用单引号引起来很重要,因为我们不想命令在我们的 shell 中展开,但需要在新 shell 中展开:

[me@linuxbox ~]$ su -c 'ls -l /root/*'
Password:
-rw------- 1 root root 754 2007-08-11 03:19 /root/anaconda-ks.cfg
/root/Mail:
total 0
[me@linuxbox ~]$

1.8 sudo-以另一个用户身份执行命令

sudo 命令在很多方面都相似于 su 命令,但是 sudo 还有一些非常重要的功能。

一个重要差异是 管理员能够配置 sudo 命令,从而允许一个普通用户以不同的身份(通常是超级用户),通过一种非常可控的方式来执行命令

尤其是,只有一个用户可以执行一个或多个特殊命令时,(更体现了 sudo 命令的方便性)。

另一个重要差异是 sudo 命令不要求超级用户的密码。使用 sudo 命令时,用户使用他/她自己的密码来认证。

比如说,例如,sudo 命令经过配置,允许我们运行一个虚构的备份程序,叫做 “backup script”,这个程序要求超级用户权限。

通过 sudo 命令,这个程序会像这样运行:

[me@linuxbox ~]$ sudo backup_script
Password:
System Backup Starting...

按下回车键之后,shell 提示我们输入我们的密码(不是超级用户的)。

一旦认证完成,则执行具体的命令。

su 和 sudo 之间的一个重要区别是 sudo 不会重新启动一个 shell,也不会加载另一个用户的 shell 运行环境。

这意味者命令不必用单引号引起来。

注意通过指定各种各样的选项,这种行为可以被推翻。

sudo 命令可以授予哪些权限,使用 “-l” 选项,列出所有权限:

[me@linuxbox ~]$ sudo -l
User me may run the following commands on this host:
(ALL) ALL

Ubuntu

当引进 Ubuntu 的时候,它的创作者们采取了不同的策略。默认情况下,Ubuntu不允许用户登录到 root 帐号(因为不能为 root 帐号设置密码),而是使用 sudo 命令授予普通用户超级用户权限。通过 sudo 命令,最初的用户可以拥有超级用户权限,也可以授予随后的用户帐号相似的权力

1.9 chown-更改文件所有者和用户组

chown 命令被用来更改文件或目录的所有者和用户组。使用这个命令需要超级用户权限。

chown 命令的语法看起来像这样:

chown [owner][:[group]] file...

chown 命令可以更改文件所有者和/或文件用户组,依据于这个命令的第一个参数。

这里有一些例子:

image.png

image.png

比方说,我们有两个用户,janet,拥有超级用户访问权限,而 tony 没有。用户 jant 想要从她的主目录复制一个文件到用户 tony 的主目录。

因为用户 jant 想要 tony 能够编辑这个文件,janet 把这个文件的所有者更改为 tony:

[janet@linuxbox ~]$ sudo cp myfile.txt ~tony
Password:
[janet@linuxbox ~]$ sudo ls -l ~tony/myfile.txt
-rw-r--r-- 1 root root 8031 2008-03-20 14:30 /home/tony/myfile.txt
[janet@linuxbox ~]$ sudo chown tony: ~tony/myfile.txt
[janet@linuxbox ~]$ sudo ls -l ~tony/myfile.txt
-rw-r--r-- 1 tony tony 8031 2008-03-20 14:30 /home/tony/myfile.txt

这里,我们看到用户 janet 把文件从她的目录复制到 tony 的主目录。下一步,janet 把文件所有者从 root(使用 sudo 命令的原因)改到 tony。通过在第一个参数中使用末尾的 “:” 字符,janet 同时把文件用户组改为 tony 登录系统时,所属的用户组,碰巧是用户组 tony。

注意,第一次使用 sudo 命令之后,为什么(shell)没有提示 janet 输入她的密码?

这是因为,在大多数的配置中,sudo 命令会相信你几分钟,直到计时结束。

1.10 chgrp-更改用户组所有权

在旧版 Unix 系统中,chown 命令只能更改文件所有权,而不是用户组所有权。

为了达到目的,使用一个独立的命令,chgrp 来完成。除了限制多一点之外,chgrp 命令与 chown 命令使用起来很相似。

1.11 更改用户密码

总结

这章我们学会了

  • 如何更改文件权限(chmod)
  • 如何更改文件所有者和用户组(chown)
  • 如何更改当前用户身份(su)
  • 如何以另一种身份执行命令(sudo)
  • 如何更改用户组(chgrp)
  • 如何更改用户密码