用户身份与文件权限
用户的身份与能力
- Linux系统的管理员为什么是root?
是因为该用户的身份号码即UID(User IDentification)的数值为0 - 在RHEL 7系统中,用户身份有下面这些:
- 管理员UID为 0:系统的管理员用户
- 系统用户UID为1~999:Linux系统为了避免因某个服务程序出现漏洞而被黑客提权至整台服务器,默认服务程序会有独立的系统用户负责运行,进而有效控制被破坏范围。
- 普通用户UID从1000开始:是由管理员创建的用于日常工作的用户。
- 为了方便管理属于同一组的用户,Linux系统中还引入了用户组的概念。
- 通过使用用户组号码(GID,Group IDentification),可以把多个用户加入到同一个组中,从而方便为组中的用户统一规划权限或指定任务。
- 在Linux系统中创建每个用户是,将自动创建一个与其同名的**基本用户组,而且这个基本用户组只有该用户一个人。如果该用户以后被归纳其他用户组,则这个其他用户组称之为扩展用户组**。
- 一个用户只有一个**基本用户组,但是可以有多个** 扩展用户组。
useradd 命令
- useradd 命令用于创建新的用户,格式为
useradd [选项] 用户名
- 使用useradd命令创建用户账户时:
- 默认的用户家目录会被存放在 /home 目录中,
- 默认的 Shell 解释器为 /bin/bash,
- 默认会创建一个与该用户同名的**基本用户组**。
- 上述默认设置可以根据下表中的 useradd 命令参数自行修改:
参数 | 作用 |
---|---|
-d | 指定用户的家目录(默认为 /home/username ) |
-e | 账户的到期时间,格式为 YYYY-MM-DD |
-u | 指定该用户的默认 UID |
-g | 指定一个初始的用户基本组(必须已存在) |
-G | 指定一个或多个扩展用户组 |
-N | 不创建与用户同名的基本用户组 |
-s | 指定该用户的默认 Shell 解释器 |
- 示例:
创建一个普通用户并指定家目录的路径、用户的 UID 以及 Shell 解释器。在下面的命令中,请注意 /sbin/nologin ,它是终端解释器中的一员,与 Bash 解释器有着天壤之别。一旦用户的解释器被设置为 nologin,则代表该用户不能登录到系统中:
[root@linuxprobe ~]# useradd -d /home/linux -u 8888 -s /sbin/nologin linuxprobe
[root@linuxprobe ~]# id linuxprobe
uid=8888(linuxprobe) gid=8888(linuxprobe) groups=8888(linuxprobe)
groupadd 命令
- groupadd 命令用于创建用户组,格式为
groupadd [选项] 群组名
- 示例:
使用如下命令创建一个用户组ronny:
[root@linuxprobe ~]# groupadd ronny
usermod 命令
- usermod 命令用于修改用户的属性,格式为:
usermod [选项] 用户名
- 在系统中创建用户也就是修改配置文件的过程
- 用户的信息保存在 /etc/passwd 文件中
- usermod命令的参数以及作用:
参数 | 作用 |
---|---|
-c | 填写用户账户的备注信息 |
-d -m | 参数-m与参数-d连用,可重新指定用户的家目录并自动把旧的数据转移过去 |
-e | 账户的到期时间,格式为 YYYY-MM-DD |
-g | 变更所属用户组 |
-G | 变更扩展用户组 |
-L | 锁定用户禁止其登录系统 |
-U | 解锁用户,允许其登录系统 |
-s | 变更默认终端 |
-u | 修改用户的UID |
- 查看账户linuxprobe 的默认信息:
[root@linuxprobe ~]# id linuxprobe
uid=1000(linuxprobe) gid=1000(linuxprobe) groups=1000(linuxprobe),10(wheel)
- 然后将用户linuxprobe加入到root用户组中,这样扩展组列表中则会出现root用户组的字样,而基本组不会受到影响
[root@bogon ~]# usermod -G root linuxprobe
[root@bogon ~]# id linuxprobe
uid=1000(linuxprobe) gid=1000(linuxprobe) 组=1000(linuxprobe),0(root)
- 再来试试用-u参数修改linuxprobe用户的UID号码值。
[root@bogon ~]# usermod -u 8888 linuxprobe
[root@bogon ~]# id linuxprobe
uid=8888(linuxprobe) gid=1000(linuxprobe) groups=1000(linuxprobe),0(root)
passwd 命令
- passwd命令用于修改用户密码、过期时间、认证信息等,格式为
passwd [选项] [用户名]
- root管理员有权限修改所有人的密码。
- root 管理员在Linux系统中修改自己或他人的密码时不需要验证旧密码。
- passwd 命令中的参数以及作用
参数 | 作用 |
---|---|
- l | 锁定用户,禁止其登录 |
- u | 解除锁定,允许用户登录 |
- - stdin | 允许通过标准输入修改用户密码,如 echo “NewPassWord” |
- d | 使该用户可用空密码登录系统 |
- e | 强制用户在下次登录时修改密码 |
- S | 显示用户的密码是否被锁定,以及密码所采用的加密算法名称 |
- 示例:
使用passwd命令禁止其他用户登录系统:
[root@linuxprobe ~]# passwd -l linuxprobe
locking password for user linuxprobe
passwed: Success
[root@linuxprobe ~]# passwd -S linuxprobe
linuxprobe LK 2017-12-26 0 99999 7 -1 (Password locked.)
[root@linuxprobe ~]# passwd -u linuxprobe
Unlocking password for user linuxprobe.
passwd: Success
[root@linuxprobe ~]# passwd -S linuxprobe
linuxprobe PS 2017-12-26 0 99999 7 -1 (Password set, SHA512 crypt.)
userdel 命令
- userdel 命令用于删除用户,格式为
userdel [选项] 用户名
- userdel 命令的参数以及作用
参数 | 作用 |
---|---|
- f | 强制删除用户 |
- r | 同时删除用户及用户家目录 |
- 示例:
使用userdel 命令将linuxprobe 用户删除:
[root@linuxprobe ~]# id linuxprobe
uid=8888(linuxprobe) gid=1000(linuxprobe) groups=1000(linuxprobe),0(root)
[root@linuxprobe ~]# userdel -r linuxprobe
[root@linuxprobe ~]# id linuxprobe
id: linuxprobe: no such user
文件权限与归属
- Linux系统中文件类型可用不同的字符来加以区分,常见的字符如下:
符号 | 代表文件类型 |
---|---|
- | 普通文件 |
d | 目录文件 |
l | 链接文件 |
b | 块设备文件 |
c | 字符设备文件 |
p | 管道文件 |
- Linux系统中每个文件都有所属的所有者和所有组,并且规定了文件的所有者、所有组以及其他人对文件所拥有的可读(r)、可写(w)、可执行(x) 等权限。
- “可读” 表示能够读取目录内的文件列表
- “可写” 表示能够在目录内新增、删除、重命名文件
- “可执行” 则表示能够进入该目录
- 文件的读、写、执行权限可以简写为rwx,亦可分别用数字4、2、1来表示,所属组及其他用户权限之间无关联
- 文件权限的字符与数字表示
权限分配 | 文件所有者 | 文件所属组 | 其他用户 | ||||||
权限项 | 读 | 写 | 执行 | 读 | 写 | 执行 | 读 | 写 | 执行 |
字符表示 | r | w | x | r | w | x | r | w | x |
数字表示 | 4 | 2 | 1 | 4 | 2 | 1 | 4 | 2 | 1 |
- 文件权限的数字法表示基于字符表示(rwx)的权限计算而来,其目的是简化权限的表示。
- 例如:若某个文件的权限为 7 则代表可读、可写、可执行(4+2+1);若权限为 6 则代表可读、可写(4+2)。
- 示例:一个文件,其所有者拥有可读、可写、可执行的权限,其文件所属组拥有可读、可写的权限;而其他人只有可读的权限。那么这个文件的权限就是rwxrw-r- -,数字法表示即为 764。注意:千万不要再将这三个数字相加,三者之间没有互通关系。
- 练习:
- 分别计算数字表示法 764、642、153、731 所对应的字符表示法:
- 764 : rwxrw-r- -
- 642 : rw-r- - -w-
- 153 : - -xr-x-wx
- 731 : rwx-wx- - x
- 把rwxrw-r- -、rw- -w- -wx、rw-r- -r- -转换成数字表示法
- rwxrw-r- - : 764
- rw- -w- -wx : 623
- rw-r- -r- - : 644
- 分别计算数字表示法 764、642、153、731 所对应的字符表示法:
文件的特殊权限
- SUID、SGID与SBIT是三种特殊权限。这是一种对文件权限进行设置的特殊功能,可以与一般权限同时使用,以弥补一般权限不能实现的功能。
SUID
- SUID是一种对二进制程序进行设置的特殊权限,可以让二进制程序的执行者临时拥有属主的权限(仅对拥有执行权限的二进制程序有效)。
- 查看passwd命令属性时发现所有者的权限由 rwx 变成了rws,其中 x 改变成 s 就意味着改文件被赋予了 SUID 权限。原本权限是 rw- ,权限为上没有 x 执行权的,被赋予特殊权限后, - 则变成大写的 S。
SGID
- SGID主要实现如下两种功能:
- 让执行者临时拥有属组的权限(对拥有执行权限的二进制程序进行设置);
- SGID的第一种功能是参考SUID而设计的,不同点在于执行程序的用户获取的不再是文件所有者的临时权限,而是获取到文件所属组的权限。
- 在某个目录中创建的文件自动继承该目录的用户组(只可以对目录进行设置)。
- 每个文件都有其归属的所有者和所属组,当创建或传送一个文件后,这个文件就会自动归属于执行这个操作的用户(即该用户是文件的所有者)。
- 示例:
- 现在需要在一个部门内设置共享目录,让部门内的所有人员都能够读取目录中的内容,那么就可以创建部门共享目录后,在该目录上设置SGID特殊权限位。这样,部门内的任何人员在里面创建的任何文件都归属于该目录的所属组,而不再是自己的基本用户组。此时,我们用到的就是SGID的第二个功能,即在某个目录中创建的文件自动继承该目录的用户组(只可以对目录进行设置)。
- 让执行者临时拥有属组的权限(对拥有执行权限的二进制程序进行设置);
[root@linuxprobe ~]# cd /tmp
[root@linuxprobe tmp]# mkdir testdir
[root@linuxprobe tmp]# ls -ald testdir/
drwxr-xr-x. 2 root root 6 Feb 11 11:50 testdir/
[root@linuxprobe tmp]# chmod -Rf 777 testdir/
[root@linuxprobe tmp]# chmod -Rf g+s testdir/
[root@linuxprobe tmp]# ls -ald testdir/
drwxrwsrwx. 2 root root 6 Feb 11 11:50 testdir/
- 在使用上述命令设置好目录的777权限(确保普通用户可以向其中写入文件),并为该目录设置了SGID特殊权限位后,就可以切换至一个普通用户,然后尝试在该目录中创建文件,并查看新创建的文件是否会继承新创建的文件所在的目录的所属组名称:
[root@linuxprobe tmp]# su - linuxprobe
Last login: Wed Feb 11 11:49:16 CST 2017 on pts/0
[linuxprobe@linuxprobe ~]$ cd /tmp/testdir/
[linuxprobe@linuxprobe testdir]$ echo "linuxprobe.com" > test
[linuxprobe@linuxprobe testdir]$ ls -al test
-rw-rw-r--. 1 linuxprobe root 15 Feb 11 11:50 test
chmod命令:
- chmod 命令能够用来设置文件或目录的权限,格式为:
chmod [参数] 权限 文件或目录名称
- 示例:
把一个文件的权限设置成其所有者可读可写可执行、所属组可读可写、其他人没有任何权限,则相应的字符法表示为rwxrw- - - -,其对应的数字法表示为760。
[root@linuxprobe ~]# ls -al test
-rw-rw-r--. 1 linuxprobe root 15 Feb 11 11:50 test
[root@linuxprobe ~]# chmod 760 test
[root@linuxprobe ~]# ls -l test
-rwxrw----. 1 linuxprobe root 15 Feb 11 11:50 test
chown命令
- chown命令:除了设置文件或目录的权限外,还可以设置文件或目录的所有者和所属组,格式为:
chown [参数] 所有者:所属组 文件或目录名称
- chmod和chown命令适用于修改文件属性和权限的最常用命令,他们还有一个特别的共性,就是针对目录进行操作时需要加上大写参数-R来表示递归操作,即对目录内所有文件进行整体操作。
[root@linuxprobe ~]# ls -l test
-rwxrw----. 1 linuxprobe root 15 Feb 11 11:50 test
[root@linuxprobe ~]# chown root:bin test
[root@linuxprobe ~]# ls -l test
-rwxrw----. 1 root bin 15 Feb 11 11:50 test
SBIT
- SBIT(Sticky Bit)特殊权限位(也可称之为特殊权限位之粘滞位)可确保用户只能删除自己的文件,而不能删除其他用户的文件。也可以理解为,当对某个目录设置了SBIT粘滞位权限后,该目录中的文件就只能被其所有者执行删除操作了。
- 建议将“粘滞位”换称为“保护位”
- 当目录被设置SBIT特殊权限位后,文件的其他人权限部分的x执行权限就会被替换成 t 或者 T,原本有 x 执行权限则会写成 t,原本没有x执行权限则会被写成 T
[root@linuxprobe tmp]# su - linuxprobe
Last login: Wed Feb 11 12:41:20 CST 2017 on pts/0
[linuxprobe@linuxprobe ~]$ ls -ald /tmp
drwxrwxrwt. 17 root root 4096 Feb 11 13:03 /tmp
[linuxprobe@linuxprobe ~]$ cd /tmp
[linuxprobe@linuxprobe tmp~]$ ls -ald
drwxrwxrwt. 17 root root 4096 Feb 11 13:03
[linuxprobe@linuxprobe tmp~]$ echo "Welcome to linuxprobe.com" > test
[linuxprobe@linuxprobe tmp~]$ chmod 777 test
[linuxprobe@linuxprobe tmp~]$ ls -al test
-rwxrwxrwx. 1 linuxprobe linuxprobe 10 Feb 11 12:59 test
- 其实,文件能否被删除并不取决于自身的权限,而是看其所在目录是否有写入权限。
- 示例:
- 继续上面的示例,将用户切换到另一个普通用户,尝试删除这个其他人创建的文件就会发现,即便读、写、执行权限全开,但是由于SBIT特殊权限位的缘故,依然无法删除该文件:
[root@linuxprobe tmp]# su - blackshield
Last login: Wed Feb 11 12:41:29 CST 2017 on pts/1
[blackshield@linuxprobe ~]$ cd /tmp
[blackshield@linuxprobe tmp]$ rm -f test
rm: cannot remove ‘test’: Operation not permitted
- 要是也想对其他目录设置SBIT特殊权限位,用chmod命令就可以了。对应的参数 o+t 代表设置SBIT粘滞位权限:
[blackshield@linuxprobe tmp]$ exit
Logout
[root@linuxprobe tmp]# cd ~
[root@linuxprobe ~]# mkdir linux
[root@linuxprobe ~]# chmod -R o+t linux/
[root@linuxprobe ~]# ls -ld linux/
drwxr-xr-t. 2 root root 6 Feb 11 19:34 linux/
文件的隐藏属性
- Linux系统中的文件除了具备一般权限和特殊权限之外,还有一种隐藏权限,即被隐藏起来的权限,默认情况下不能直接被用户发觉。
chattr 命令
- chattr 命令用于设置文件的隐藏权限,格式为:
chattr [参数] 文件
- 如果想要把某个隐藏功能添加到文件上,则需要在命令后面追加“+参数”,如果想要把某个隐藏功能移出文件,则需要追加“-参数”。
- chattr 命令中用于隐藏权限的参数及其作用
参数 | 作用 |
---|---|
i | 无法对文件进行修改;若对目录设置了该参数,则仅能修改其中的子文件内容而不能新建或删除文件 |
a | 仅允许补充(追加)内容,无法覆盖/删除内容(Append Only) |
S | 文件内容在变更后立即同步到硬盘(sync) |
s | 彻底从硬盘中删除,不可恢复(用0填充原文件所在硬盘区域) |
A | 不再修改这个文件或目录的最后访问时间(atime) |
b | 不再修改文件或目录的存储时间 |
D | 检查压缩文件中的错误 |
d | 使用dump 命令备份时忽略文件/目录 |
c | 默认将文件或目录进行压缩 |
u | 当删除该文件后依然保留其在硬盘中的数据,方便日后恢复 |
t | 让文件系统支持尾部合并(tail-merging) |
X | 可以直接访问压缩文件中的内容 |
- 示例 :
- 尝试创建普通文件,并为其设置不允许删除与覆盖(+a参数)权限,然后尝试删除这个文件:
[root@linuxprobe ~]# echo "for Test" > linuxprobe
[root@linuxprobe ~]# chattr +a linuxprobe
[root@linuxprobe ~]# rm linuxprobe
rm: remove regular file ‘linuxprobe’? y
rm: cannot remove ‘linuxprobe’: Operation not permitted
lsattr 命令
- lsattr 命令用于显示文件的隐藏权限,格式为:
lsattr [参数] 文件
- 在Linux系统中,文件的隐藏权限必须使用lsattr 命令来查看,平时使用的 ls 之类的命令则看不出端倪:
[root@linuxprobe ~]# ls -al linuxprobe
-rw-r--r--. 1 root root 9 Feb 12 11:42 linuxprobe
- 使用 lsattr 命令后,可以查看文件上被赋予的隐藏权限。此时可按照显示的隐藏权限的类型(字母),使用 chattr 命令将其去掉:
[root@linuxprobe ~]# lsattr linuxprobe
-----a---------- linuxprobe
[root@linuxprobe ~]# chattr -a linuxprobe
[root@linuxprobe ~]# lsattr linuxprobe
---------------- linuxprobe
[root@linuxprobe ~]# rm linuxprobe
rm: remove regular file ‘linuxprobe’? y
文件访问控制列表
- 基于普通文件或目录设置ACL其实就是针对指定的用户或用户组设置文件或目录的操作权限。
- 如果针对某个目录设置了ACL,则目录中的文件会继承其ACL;若针对文件设置额ACL,则文件不再继承其所在目录的ACL。
setfacl 命令
- setfacl 命令用于管理文件的ACL规则,格式为
setfacl [参数] 文件名称
- 文件的ACL提供的是在所有者、所属组、其他人的读/写/执行权限之外的特殊权限控制,使用 setfacl 命令可以针对单一用户或用户组、单一文件或目录来进行读/写/执行权限的控制。
- 其中,针对目录文件需要使用 -R 递归参数;
- 针对普通文件则使用 -m 参数;
- 如果想要删除某个文件的ACL,则可以使用 -b 参数。
- 示例:设置用户在/root 目录上的权限:
[root@linuxprobe ~]# setfacl -Rm u:linuxprobe:rwx /root
[root@linuxprobe ~]# su - linuxprobe
Last login: Sat Mar 21 15:45:03 CST 2017 on pts/1
[linuxprobe@linuxprobe ~]$ cd /root
[linuxprobe@linuxprobe root]$ ls
anaconda-ks.cfg Downloads Pictures Public
[linuxprobe@linuxprobe root]$ cat anaconda-ks.cfg
[linuxprobe@linuxprobe root]$ exit
- 常用的 ls 命令是看不到ACL表信息的,但是却可以看到文件的权限最后一个点(.)变成了加号(+),这就意味着改文件已经设置额ACL了。
[root@linuxprobe ~]# ls -ld /root
dr-xrwx---+ 14 root root 4096 May 4 2017 /root
getfacl 命令
- getfacl 命令用于显示文件上设置的ACL信息,格式为:
getfacl 文件名称
- 要设置ACL,用的是 setfacl 命令;要查看ACL,则用的是 getfacl 命令。
- 示例:使用 getfacl 命令显示在root管理员家目录上设置的所有ACL信息。
[root@linuxprobe ~]# getfacl /root
getfacl: Removing leading '/' from absolute path names
# file: root
# owner: root
# group: root
user::r-x
user:linuxprobe:rwx
group::r-x
mask::rwx
other::---
su 命令与 sudo 服务
- su 命令可以解决切换用户身份的需求,使得当前用户在不退出登录额情况下,顺畅地切换到其他用户,比如从root管理员切换到普通用户
- sudo 命令用于给普通用户提供额外的权限来完成原本root管理员才能完成的任务,格式为
sudo [参数] 命令名称
- sudo 服务中的可用参数以及作用
参数 | 作用 |
---|---|
-h | 列出帮助信息 |
-l | 列出当前用户可执行的命令 |
-u 用户名或UID值 | 以指定的用户身份执行命令 |
-k | 清空密码的有效时间,下次执行 sudo 时需要再次进行密码验证 |
-b | 在后台执行指定的命令 |
-p | 更改询问密码的提示语 |
- 总结,sudo 命令具有如下功能:
- 限制用户执行指定的命令:
- 记录用户执行的每一条命令:
- 配置文件(/etc/sudoers)提供集中的用户管理、权限与主机等参数;
- 验证密码的后5分钟内(默认值)无须再让用户再次验证密码。
- 如果担心直接修改配置文件会出现问题,则可使用 sudo 命令提供的 visudo 命令来配置用户权限。这条命令在配置用户权限时将禁止多个用户同时修改sudoers 配置文件,还可以对配置文件内的参数进行语法检查,并在发现参数错误时进行报错。
- 注意: 只有root管理员才可以使用 visudo 命令编辑 sudo 服务的配置文件。
- 使用 visudo 命令配置 sudo 命令的配置文件时,其操作方法与Vim编辑器中用到的方法一致,因此在编写完成后记得在末行模式下保存并退出。
- 示例:在 sudo 命令的配置文件中,按照下面的格式将第 99 行(大约)填写上指定的信息:
- **谁可以使用 允许使用的主机 = (以谁的身份) 可执行命令的列表 **
- 示例:在 sudo 命令的配置文件中,按照下面的格式将第 99 行(大约)填写上指定的信息:
[root@linuxprobe ~]# visudo
96 ##
97 ## Allow root to run any commands anywhere
98 root ALL=(ALL) ALL
99 linuxprobe ALL=(ALL) ALL
- whereis 命令: 查找命令所对应的保存路径
- 可以添加 NOPASSWD 参数,使得用户执行 sudo 命令时不再需要密码验证:
[linuxprobe@linuxprobe ~]$ exit
logout
[root@linuxprobe ~]# whereis poweroff
poweroff: /user/sbin/poweroff / user/share/man/man8/poweroff.8.gz
[root@linuxprobe ~]# visudo
............省略部分文件内容.............
96 ##
97 ## Allow root to run any commands anywhere
98 root ALL=(ALL) ALL
99 linuxprobe ALL=NOPASSWD: /user/sbin/poweroff
............省略部分文件内容.............