第五章 Linux用户组和权限管理
1 Linux用户介绍
1.1 什么是用户
用户对硬件资源的操作都需要通过操作系统,比如用户要读取硬盘中的一份关键数据
出于安全考虑,操作系统的开发者们都专门开发了安全机制,要使用操作系统必须事先输入正确的用户名与密码
这便是用户的由来
1.2 为何要有用户
# 主要就是权限问题
1、系统上的每一个进程,都需要一个特定的用户运行,一个用户拥有特定的权限,该用户运行的进程与用户权限一致
2、通常在公司是使用普通用户管理服务器,因为root权限过大,容易出问题
1.3 如何查看用户相关信息
#查看当前用户
[23:46:51 root@nginx-18 ~]# id
uid=0(root) gid=0(root) 组=0(root) 环境=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
#查看当前用户是谁
[11:01:38 root@nginx-18 ~]# whoami
root
#查看某个指定的用户
[11:01:52 root@nginx-18 ~]# id xujun
uid=1001(xujun) gid=1001(xujun) 组=1001(xujun)
#查看所有登录的用户
[11:01:53 root@nginx-18 ~]# who
root pts/0 2022-04-30 22:37 (10.0.0.1)
root pts/1 2022-05-01 23:38 (10.0.0.1)
#每一个进程都有其用户
[11:01:56 root@nginx-18 ~]# ps aux|grep sshd
root 835 0.0 0.2 105996 4108 ? Ss 5月01 0:00 /usr/sbin/sshd -D
root 26228 0.0 0.2 145772 5236 ? Ss 04:23 0:00 sshd: root@pts/0
root 26439 0.0 0.2 145772 5236 ? Ss 10:51 0:00 sshd: root@pts/1
root 26505 0.0 0.0 112824 988 pts/1 S+ 11:02 0:00 grep --color=auto sshd
1.4 Linux系统中用户角色划分
在linux系统中的用户分为管理员用户与其他用户
管理员用户拥有最高权限
其他用户根据管理员的分配拥有不同的权限
# 需要强调的是:
对于linux系统来说,用户的角色是通过UID和GID识别的;用户系统帐号的名称(如xujun)其实给人(管理员)看的,linux系统能够识别的仅仅是UID和GID这样的数字。
# uid与gid
1. UID (User Identify)用户ID,唯一标识一个系统用户的帐号,uid在系统中是唯一的。uid相当于一个人的身份证,用户名就相当于这个人的名字
2. GID (Group Identify)组ID,如果把一个操作系统当成一家公司,uid相当于这个人的员工号,gid相当于他的部门编号。
centos7系统之前约定
uid: 0 由超级用户或具备超级用户权限的用户创建的用户(类似于古代的皇帝)
uid: 1~499 系统虚拟用户:UID范围1-499,存在满足文件或服务启动的需要。一般不能登录,只是傀儡
uid: 500-65535 普通用户
centos7系统约定:
0 超级管理员,最高权限,有着极强的破坏能力
1~200 系统用户,用来运行系统自带的进程,默认已创建
201~999 系统用户,用来运行安装的程序,所以此类用户无需登录系统
1000+ 普通用户,正常可以登录系统的用户,权限比较小,能执行的任务有限
# 用户和组的关系:
一对一,多对一,一对多,多对多
1.5 超级用户
默认是root用户,其UID和GID均为0。root用户在每台unix/linux操作系统中都是唯一且真实存在的,通过它可以登录系统,可以操作系统中任何文件和命令,拥有最高的管理权限。
举个例子:
- 1、操作系统=》一个国家
- 2、root用户=》国王
- 3、root用户的家目录=》皇宫
需要注意的是:
- 1、在生产环境中,一般会禁止root帐号通过SSH远程连接服务器(保护好皇帝),当然了,也会更改默认的SSH端口(保护好皇宫),以加强系统安全。
- 2、企业工作中:没有特殊需求,应该尽量不要登录root用户进行操作,应该在普通用户下操作任务,然后用sudo管理普通用户的权限,可以细到每个命令权限分配。
- 3、在linux系统中,uid为0的用户就是超级用户。但是通常不这么做,如果确实有必要在某一操作上用到管理的权限的话,那就用sudo单独授权,也不要直接用uid为0的用户
1.6 扩展阅读
# Linux/Unix是一个多用户、多任务的操作系统
# windows是一个单用户多任务操作系统
多用户不是说可以创建多个用户,而是指一次可以登录多个用户
多任务指的是可以并发执行多个进程
回忆之前讲过的linux发展史:
multics-》unix-》linux,所以linux是多用户的,天然支持多个连机终端,连机终端在没有互联网的情况下是有意义的,多个人可以用不同的连机终端连到一台机器/服务器上使用,而有了互联网之后,多个人可通过网络访问服务器,这个时候多用户or单用户的概念就不再那么重要
2 用户与组相关文件
2.1 和用户、组相关的文件
/etc/passwd
/etc/shadow
/etc/group
/etc/gshadow
/etc/passwd
root:x:0:0:root:/root:/bin/bash
第一字段:用户名(也被称为登录名);
第二字段:口令;在例子中我们看到的是一个x,其实密码已被映射到/etc/shadow 文件中;
第三字段:UID ;请参看本文的UID的解说;
第四字段:GID;请参看本文的GID的解说;
第五字段:描述信息,可选
第六字段:用户的家目录所在位置;
第七字段:用户所用SHELL的类型
/etc/shadow
xujun:$1$VE.Mq2Xf$2c9Qi7EQ9JP8GKF8gH7PB1:13072:0:99999:7:::
第一字段:用户名(也被称为登录名),在/etc/shadow中,用户名和/etc/passwd 是相同的,这样就把passwd 和shadow中用的用户记录联系在一起;这个字段是非空的;
第二字段:密码(已被加密),如果是有些用户在这段是x,表示这个用户不能登录到系统;这个字段是非空的;
第三字段:上次修改口令的时间;这个时间是从1970年01月01日算起到最近一次修改口令的时间间隔(天数),您可以通过passwd 来修改用户的密码,然后查看/etc/shadow中此字段的变化;
第四字段:两次修改口令间隔最少的天数;如果设置为0,则禁用此功能;也就是说用户必须经过多少天才能修改其口令;此项功能用处不是太大;默认值是通过/etc/login.defs文件定义中获取,PASS_MIN_DAYS 中有定义;
第五字段:两次修改口令间隔最多的天数;这个能增强管理员管理用户口令的时效性,应该说在增强了系统的安全性;如果是系统默认值,是在添加用户时由/etc/login.defs文件定义中获取,在PASS_MAX_DAYS 中定义;
第六字段:提前多少天警告用户口令将过期;当用户登录系统后,系统登录程序提醒用户口令将要作废;如果是系统默认值,是在添加用户时由/etc/login.defs文件定义中获取,在PASS_WARN_AGE 中定义;
第七字段:在口令过期之后多少天禁用此用户;此字段表示用户口令作废多少天后,系统会禁用此用户,也就是说系统会不能再让此用户登录,也不会提示用户过期,是完全禁用;
第八字段:用户过期日期;此字段指定了用户作废的天数(从1970年的1月1日开始的天数),如果这个字段的值为空,帐号永久可用; www.hackdig.com
第九字段:保留字段,目前为空,以备将来Linux发展之用;
/etc/group:组文件
/etc/gshadow:组密码文件
还有一些文件目录,如下:
/etc/skel/用户的模板
/home/xxx 用户家目录
/var/spool/mail/xxx 用户邮箱文件
3 用户管理命令
useradd #添加用户
userdel #删除用户
usermod #修改用户信息
3.1 创建用户
useradd 创建用户
主要选项:
-u 指定uid 列子:useradd -u 504 xujun (重要)
-c 新账号password的说明栏
-d 设置新账号每次登入时使用的家目录
-e 账号终止日期。日期格式为MM/DD/YY
-g 指定属于的主组
-G 定义此用户为多个不同的组成员,每个用户组使用,逗号来分隔
-s 指定登录shell (重要)
-m 创建家目录
-M 不创建用户家目录
-r 创建系统用户
-D 显示或修改用户的默认配置 修改的结果保存与/etc/default/useradd文件中
主要案例:
useradd -s /sbin/nologin -M xujun
useradd -u 504 xujun
3.2 查看用户
id 查看用户和用户组的信息
主要选项:
-u 仅显示用户的uid
-g 仅显示用户的gid
-G 仅显示用户所属的所有组ID
-n 仅显示名字而非ID
主要案例:
[root@db02 ~]# id john
uid=511(john) gid=511(john) groups=511(john)
who 查看当前用户登录情况
主要选项:
-b 系统此次启动的时间
-r 运行级别
主要案例:
[root@web01 ~]# who
root pts/0 2017-03-14 22:12 (192.168.203.1)
root pts/1 2017-03-13 21:25 (192.168.203.1)
#注意pts代表虚拟终端(用xshell等),而tty代表本机终端(即直接在服务器上登录)
whoami 查看当前用户是什么
主要案例:
[root@web01 ~]# whoami
root
3.3 删除用户
userdel 删除用户
主要选项:
-r 删除用户的家目录(此选项慎用)
主要案例:
userdel -r xujun
建议不删除用户,还是用注释/etc/passwd中用户的方法 *****
[root@iflytek-30 ~]# tail -1 /etc/passwd
#alex:x:1000:1000::/home/alex:/bin/bash
[root@iflytek-30 ~]# su - alex
su: user alex does not exist
3.4 usermod命令
usermod 更改用户属性
主要选项:
-c 注释
-d 更新用户新的家目录。如果给定-m选项,用户旧的家目录会搬到新的家目录去,如旧的家目录不存在则建个新的
-e 加上用户账号停止日期
-g 更新用户新的起始登入用户组
-G 定义用户为多个用户组
-s 指定新登入的shell
-u 指定用户的UID
-a 和-G配合使用,表示追加新的用户组,不覆盖
-m只能与-d选项一同使用,用于将原来的家目录移动为新的家目录
主要案例:
usermod -c "Handsomeboy" -u 806 -G root,oldboy -s /bin/sh -md /oldboy6 oldboy6
3.5 设定与修改密码
passwd 创建用户密码或修改密码
主要选项:
--stdin 非交互式设置密码
-n 指定最短使用期限
-x 最大使用期限
-w 提前多少天开始警告
-i 非活动期限
-e 过期期限
主要案例:
#centos7无交互式创建用户密码
echo “123456”|passwd --stdin xujun
#Ubuntu非交互式修改用户密码
root@Ununtu-08:~# echo -e '123456\n123456' |passwd xujun
Enter new UNIX password: Retype new UNIX password: passwd: password updated successfully
3.6 切换用户
su 切换用户
主要选项:
-c 变更账号为USER的使用者,并执行指令后再变回原来的使用者
- 加载环境变量
切换用户的方式:
su username:非登录式切换,即不会读取目标用户的配置文件,不改变当前工作目录,即不完全切换
su - username:登录式切换,会读取目标用户的配置文件,切换至自己的家目录,即完全切换
说明:root用户su - username的时候,是不需要密码的,非root用户切换时需要密码
主要案例:
su - xujun
3.7 故障案例
useradd创建用户时,对于未指定的选项(-u、-g等等),会以/etc/login.defs、/etc/default/useradd两个配置文件中的配置作为参照物
#配置文件/etc/login.defs详解
[root@egon ~]# grep -Ev "^#|^$" /etc/login.defs
MAIL_DIR /var/spool/mail
PASS_MAX_DAYS 99999 #密码最大有效期
PASS_MIN_DAYS 0 #两次修改密码的最小间隔时间
PASS_MIN_LEN 5 #密码最小长度,对于root无效
PASS_WARN_AGE 7 #密码过期前多少天开始提示
UID_MIN 1000 #用户ID的最小值
UID_MAX 60000 #用户ID的最大值
SYS_UID_MIN 201 #系统用户ID的最小值
SYS_UID_MAX 999 #系统用户ID的最大值
GID_MIN 1000 #组ID的最小值
GID_MAX 60000 #组ID的最大值
SYS_GID_MIN 201 #系统用户组ID的最小值
SYS_GID_MAX 999 #系统用户组ID的最大值
CREATE_HOME yes #使用useradd的时候是可以创建用户家目录
UMASK 077 #创建家目录时umask的默认控制权限
USERGROUPS_ENAB yes #删除用户的时候是否同时删除用户组
ENCRYPT_METHOD SHA512 #密码加密规则
#配置文件/etc/default/useradd详解
[root@egon ~]# cat /etc/default/useradd
GROUP=100 #依赖于/etc/login.defs的USERGRUUPS_ENAB参数,如果为no,则在此处控制
HOME=/home #把用户的家目录建在/home中。
INACTIVE=-1 #是否启用账号过期停权,-1表示不启用。
EXPIRE= #账号终止日期,不设置表示不启用。
SHELL=/bin/bash #新用户默认所有的shell类型。
SKEL=/etc/skel #配置新用户家目录的默认文件存放路径。
CREATE_MAIL_SPOOL=yes #创建mail文件。
当使用useradd创建用户时,创建的用户家目录下会存在.bash_* 环境变量相关的文件,这些环境变量文件默认
从/etc/skel目录中拷贝。这个默认拷贝环境变量位置是由/etc/default/useradd配置文件中定义的。
#故障案例,在当前用户家目录下执行了rm -rf .*命令,下次登录系统时出现-bash-4.1$,如何解决!
-bash-4.1$ cp -a /etc/skel/.bash* ./
-bash-4.1$ exit
[root@xujun ~]# #重新连接即可恢复
4 组管理
groupadd #设置组
groupmod #修改组
groupdel #删除组
gpasswd # 设置组密码
newgrp # 切换主组
4.1 创建组
groupadd 创建一个组用户
主要选项:
-g 创建组的gid
-r 创建系统组
主要案例:
groupadd -g 504 oldboy
4.2 修改组
groupmod 组属性修改
主要选项:
-n 修改组名
-g 新的GID
主要案例:
groupmod -g 1000 oldboy
4.3 删除组
groupdel 删除用户组
注意:删除有用户的组,需要先删除用户,然后在删除组
主要案例:
[root@db02 ~]# groupdel john
4.4 设置组密码
gpasswd 组密码修改
主要选项:
-a 将用户添加至指定组中
-d 从组中移除用户
-A 设置有管理权限的用户列表(设置之后,在sudo管理文件可以看见)
-M 添加多个用户到一个组
主要案例:
gpasswd -a oldboy test
gpasswd -A oldboy oldgirl root
4.5 切换组
newgrp 临时切换基本组
注意:如果用户不属于此组,则需要组密码
主要选项:
- 会模拟用户重新登陆以实现重新初始化其工作环境
主要案例:
newgrp test
5 文件权限管理
上图就是一个文件的元数据。
5.1 基本权限介绍
基本权限类型
- r:可读 数字表示为4
- w:可写 数字表示为2
- x:可执行 数字表示为1
权限的归属
- 属主:u
- 属组:g
- 其他人:o
[root@aliyun ~]# ls -l a.txt
-rw-r--r-- 1 root root 1146 Jul 16 18:42 a.txt
文件类型:
-:文本文档
d:目录
b:设备block
c:字符设备
s:套接字文件
l:软链接
权限
硬链接个数
属主
属组
文件所占用的空间(以字节为单位)
文件(目录)最近访问(修改)时间
文件名
5.2 设置权限
修改属主、属组
chown 改变文件和目录的所有者
主要选项:
-R 递归改变目录下所有子目录和文件的所有者
案例:
[root@aliyun ~]# chown alice.hr file1 # 改属主、属组
[root@aliyun ~]# chown alice file1 # 只改属主
[root@aliyun ~]# chown .hr file1 # 只改属组
[root@aliyun ~]# chown -R /test # 递归修改
修改u、g、o对应的权限
chmod 改变文件权限
主要选项:
-R 递归改变目录下所有子目录和文件的权限
主要案例:
# 加减法
chmod u+x,g-w,o+r a.txt
# 赋值
chmod a=rwx a.txt
chmod a=- a.txt
chmod ug=rw,o=r file1
# 数字
chmod 644 file1
chmod -R 777 xxx/
注意:把某一个非属主用户添加到文件的属组里,他就拥有了该组的权限,而不再是其他人
5.3 权限对文件or目录的意义
文件:ls -l 文件名
- r:可以读取文件内容
- w:可以修改文件
- x:可以执行文件代码,如果该文件的代码是编译好的结果,那么只有x权限即可执行,但如果该文件的代码是一个解释型的脚本程序,则需要配合r权限才可执行
目录:ls -ld 文件名
- r:可以ls浏览文件下的内容
- w:可以在目录下创建新文件or目录
- x:
- 可以执行目录下的程序,除了对目录可执行权限外,还要对程序文件有执行权限才行
- 可以正常切换到目录下
- 涉及到多层目录如/a/b/c,需要对每一级都有x权限才可以正常走到下一级
一:对文件夹的操作(不操作文件内容),需要当前用户具备的权限
1、对沿途所有文件夹有x权限
2、对目标文件夹有r或w权限
r-》可以浏览
w-》可以创建、删除、移动子文件和子目录
二:对文件的操作(操作文件内容),需要当前用户具备的权限
1、对沿途所有文件夹有x权限
2、对目标文件有r或w权限
r-》可以读取文件内容
w-》可以修改文件内容
!!!注意!!!
储备知识:vim修改的原理是将源文件删掉,然后再将内容的内容覆盖写入了新文件,新文件名重命名为原文件名
例子:
1、当前用户对沿途所有文件夹都有x权限
2、并且当前用户对目标文件夹有w权限
3、但是当前用户对目标文件没有w权限
此时当前用可以vim编辑文件内容,并且可以wq!强制保存退出完成文件修改,其实是将源文件删掉了,可以通过查看前后操作的文件inode号来确定
列1:在目录下创建或删除内容:对目录的x权限+对目录的w权限
# 1、设置权限
[root@aliyun ~]# mkdir -p /a/b/c
[root@aliyun ~]# chmod -R o=x /a # 其他人o对当前目录及其子目录都有x权限
[root@aliyun ~]# chmod o+w /a/b/c # 其他人o对/a/b/c目录有w权限
# 2、查看权限
[root@aliyun ~]# ls -dl /a
drwxr-x--x 3 root root 4096 Aug 11 16:24 /a
[root@aliyun ~]# ls -dl /a/b
drwxr-x--x 3 root root 4096 Aug 11 16:24 /a/b
[root@aliyun ~]# ls -dl /a/b/c
drwxr-x-wx 2 root root 4096 Aug 11 16:25 /a/b/c
# 3、验证
[root@aliyun ~]# su - gg
Last login: Tue Aug 11 16:17:28 CST 2020 on pts/2
[gg@aliyun ~]$ touch /a/b/c/1.txt
[gg@aliyun ~]$ exit
logout
[root@aliyun ~]# ls /a/b//c/
1.txt
列2:要浏览目录下内容:对目录的x权限+对目录的r权限
[root@aliyun ~]# mkdir -p /a/b/c
[root@aliyun ~]# chmod -R o=x /a
[root@aliyun ~]# chmod o+r /a/b/c
[root@aliyun ~]# touch /a/b/c/{1..3}.txt
[root@aliyun ~]# su - gg
Last login: Tue Aug 11 16:27:33 CST 2020 on pts/2
[gg@aliyun ~]$ ls /a/b/c
1.txt 2.txt 3.txt
列3:要执行目录下程序:对目录的x权限+对文件的x权限,如果文件是解释型语言的脚本程序,还需要对文件有r权限
[root@aliyun ~]# mkdir -p /a/b/c
[root@aliyun ~]# chmod -R o=x /a/b/c
[root@aliyun ~]# cp /bin/echo /a/b/c
[root@aliyun ~]# chmod o=x /a/b/c/echo
[root@aliyun ~]# su - gg
Last login: Tue Aug 11 16:30:17 CST 2020 on pts/2
[gg@aliyun ~]$ /a/b/c/echo "hello egon"
hello egon
6 文件权限管理之特殊权限
suid:数字表示为4
sgid:数字表示为2
sticky:数字表示为1
6.1 SUID
普通用户不是root也不属于root组,于是它对/etc/shadow文件没有任何权限
[11:25:59 root@nginx-18 ~]# ls -l /etc/shadow
----------. 1 root root 669 5月 2 11:25 /etc/shadow
但是普通用户却可以用passwd命令修改密码,而修改密码都是在修改/etc/shadow文件,如何实现的呢?
[14:59:06 root@nginx-18 ~]# ls -l /bin/passwd
-rwsr-xr-x. 1 root root 27832 6月 10 2014 /bin/passwd
可以看到一个s权限,s权限的特殊之处
- SUID权限仅对二进制可执行文件有效
- 如果执行者对于该二进制可执行文件具有x的权限,执行者将具有该文件的所有者的权限
- 本权限仅在执行该二进制可执行文件的过程中有效
范例:
[root@localhost ~]# ls -l /usr/bin/cat
-rwxr-xr-x. 1 root root 54160 10月 31 2018 /usr/bin/cat
[root@localhost ~]# chmod 4755 /usr/bin/cat # 或者 chmod u+s /usr/bin/cat
[root@localhost ~]# ls -l /usr/bin/cat
-rwsr-xr-x. 1 root root 54160 10月 31 2018 /usr/bin/cat
[root@localhost ~]# su - xujun
[xujun@localhost ~]$ cat /etc/shadow # 可以看到内容
6.2 SGID
- 当SGID作用于普通文件时,和SUID类似,在执行该文件时,用户将获得该文件所属组的权限
- 当SGID作用于目录时,意义就非常重大了:
- 当一个用户对某一目录有写和执行权限时,该用户就可以在该目录下建立文件
- 如果该目录同时用SGID修饰,则该用户在这个目录下建立的文件都是属于这个目录所属的组
[root@localhost ~]# mkdir /test
[root@localhost ~]# chmod g+s /test/ # 等同于chmod 2755 /test/
[root@localhost ~]# ll -dl /test/
drwxr-sr-x 2 root root 6 8月 11 17:06 /test/
[root@localhost ~]#
[root@localhost ~]# chown .xujun /test/ # 后期任何人在该目录下创建的文件or目录的属组都是xujun
6.3 SBIT
其实SBIT与SUID和SGID的关系并不大。
SBIT也可以称之为粘滞位。
SBIT目前只对目录有效,用来阻止非文件的所有者删除文件。比较常见的列子就是/tmp目录:
[root@localhost ~]# ls -dl /tmp/
drwxrwxrwt. 13 root root 4096 8月 11 17:09 /tmp/
[root@localhost ~]# chmod o+t /test/ # 或者 chmod 1755 /test
权限信息中最后一位t表示该目录被设置了SBIT权限。SBIT对目录的作用是:当用户在该目录下创建新文件或目录时,仅有自己和root才有权利删除,主要作用于一个共享的文件夹。
6.4 特殊权限总结
suid,sgid,粘滞位
suid知识小结:是针对命令和二进制程序的
1.用户或属主对应的前三位权限的x为上如果有s就表示suid权限
当x位上没有小写x执行权限的时候,suid的权限显示的就是大S
2.suid的作用就是让普通用户可以使用root用户的权限才操作相应的程序或命令
设置小结:
suid:chmod 4755 file或者chmod u+s file
sgid知识小结:sgid既可以针对文件也可以针对目录设置
对于文件来说,sgid的功能如下:
1.sgid仅对二进制命令程序有效
2.二进制命令或程序要有可执行权限x
3.执行命令的任意用户可以获得命令程序执行期间所属组的权限
对于目录来说,sgid的功能如下:
1.linux里默认情况所有用户创建文件,所创建的文件对应的用户和组都是自身
2.sgid可以让用户在此目录下创建的文件的目录,具有此目录相同的用户组
设置小结:
sgid:chmod 2755 file或者chmod g+s file
粘滞位sticky知识小结:开放所有权限
在其他用户位上的x位设置成t
如果对应位有x位,字符权限表现为小写,否则表现为大写
tmp这个目录就是最经典的sticky权限的经典案例
特点:谁都有写权限,但是无法删除不是自己用户的文件。不过这样安全也成为大问题,很多木马就是用这个目录作为第一个跳板
设置小结:
sticky:chmod 1755 file或者chmod o+t file
注意:之所以文件用666去减,表示文件默认不能拥有执行权限。如果减得的结果中有执行权限,则需要将其加一。所以这个对目录而言,是没有任何效果的
7 文件权限管理之umask
新建文件、目录的默认权限是由umask决定的。
默认umask:0022。
umask 修改umask值
当umask值都为偶数,直接相减
如果有奇数,对应为加一
注意:之所以文件用666去减,表示文件默认不能拥有执行权限。如果减得的结果中有执行权限,则需要将其加一。所以这个对目录而言,是没有任何效果的
[15:02:39 root@nginx-18 ~]# umask
0022
Linux中文件默认权限为666、目录权限为777,文件具体算法如下:
目录权限计算方法:直接相减即可
总结:umask设置的越小,权限越大,慎用!不过在生产环境中,我们一般umask是不会去动的,理解umask算法即可。
8 设定文件特殊属性
设置文件的特殊属性,可以让root用户不能删除,改名和更改
chattr 增加隐藏属性
主要选项:
+a 可以增加内容,但是不能减少或删除文件
+i 锁定文件,让其不能增加、删除、修改
主要案例:
chattr -i xujun.txt #取消文件
chattr +i xujun.txt #锁定文件
有了设置,就有查看文件特殊属性
lsattr 查看隐藏属性
主要选项:
-d 只列出目录的详细信息
-R 递归列出目录下的隐藏属性信息
-a 列出目录下包括隐藏文件的隐藏属性信息
主要案例:
[15:25:44 root@nginx-18 ~]# chattr +i xujun.txt
[15:25:51 root@nginx-18 ~]# lsattr xujun.txt
----i----------- xujun.txt
9 ACL访问控制列表
在普通权限中,用户对文件只有三种身份,就是属主、属组和其他人;每种用户身份拥有读(read)、写(write)和执行(execute)三种权限。但是在实际工作中,这三种身份实在是不够用,我们举个例子来看看。
上图的根目录中有一个 /project 目录,这是班级的项目目录。班级中的每个学员都可以访问和修改这个目录,老师也需要对这个目录拥有访问和修改权限,其他班级的学员当然不能访问这个目录。需要怎么规划这个目录的权限呢?应该这样:老师使用 root 用户,作为这个目录的属主,权限为 rwx;班级所有的学员都加入 tgroup 组,使 tgroup 组作为 /project 目录的属组,权限是 rwx;其他人的权限设定为 0。这样这个目录的权限就可以符合我们的项目开发要求了。
有一天,班里来了一位试听的学员 st,她必须能够访问 /project 目录,所以必须对这个目录拥有 r 和 x 权限;但是她又没有学习过以前的课程,所以不能赋予她 w 权限,怕她改错了目录中的内容,所以学员 st 的权限就是 r-x。可是如何分配她的身份呢?变为属主?当然不行,要不 root 该放哪里?加入 tgroup 组?也不行,因为 tgroup 组的权限是 rwx,而我们要求学员 st 的权限是 r-x。如果把其他人的权限改为 r-x 呢?这样一来,其他班级的所有学员都可以访问 /project 目录了。
当出现这种情况时,普通权限中的三种身份就不够用了。ACL 权限就是为了解决这个问题的。在使用 ACL 权限给用户 st 陚予权限时,st 既不是 /project 目录的属主,也不是属组,仅仅赋予用户 st 针对此目录的 r-x 权限。这有些类似于 Windows 系统中分配权限的方式,单独指定用户并单独分配权限,这样就解决了用户身份不足的问题。
ACL是Access Control List(访问控制列表)的缩写,不过在Linux系统中,ACL用于设定用户针对文件的权限,而不是在交换路由器中用来控制数据访问的功能(类似于防火墙)。
Centos7默认创建的xfs和ext4文件系统具有ACL功能
Centos7之前版本,默认手工创建的ext4系统无ACL功能,需手动增加
tune2fs -o acl /dev/sdb1
mount -o acl /dev/sdb1 /mnt/test
9.1 ACL权限设置
1)ACL权限管理命令
[root@localhost ~]# getfacle 文件名
#查看ACL权限
[root@localhost ~]# setfacl 选项 文件名
#设定ACL权限
setfacl 设置ACL权限
命令选项:
-m:设定 ACL 权限。如果是给予用户 ACL 权限,则使用"u:用户名:权限"格式赋予;如果是给予组 ACL 权限,则使用"g:组名:权限" 格式赋予;
-x:删除指定的 ACL 权限;
-b:删除所有的 ACL 权限;
-d:设定默认 ACL 权限。只对目录生效,指目录中新建立的文件拥有此默认权限;
-k:删除默认 ACL 权限;
-R:递归设定 ACL 权限。指设定的 ACL 权限会对目录下的所有子文件生效;
2)给用户和用户组添加ACL权限
举个例子,就来看看图 1 中的权限怎么分配。我们要求 root 是 /project 目录的属主,权限是 rwx;tgroup 是此目录的属组,tgroup 组中拥有班级学员 zhangsan 和 lisi,权限是 rwx;其他人的权限是 0。这时,试听学员 st 来了,她的权限是 r-x。我们来看具体的分配命令
[root@localhost ~]# useradd zhangsan
[root@localhost ~]# useradd lisi
[root@localhost ~]# useradd st
[root@localhost ~]# groupadd tgroup
#添加需要试验的用户和用户组,省略设定密码的过程
[root@localhost ~]# mkdir /project #建立需要分配权限的目录
[root@localhost ~]# chown root:tgroup /project/
#改变/project目录的属主和属组
[root@localhost ~]# chmod 770 /project/
#指定/project目录的权限
[root@localhost ~]# ll -d /project/
drwxrwx--- 2 root tgroup 4096 1月19 04:21 /project/
#查看一下权限,已经符合要求了
#这时st学员来试听了,如何给她分配权限
[root@localhost ~]# setfacl -m u:st:rx /project/
#给用户st赋予r-x权限,使用"u:用户名:权限" 格式
[root@localhost /]# cd /
[root@localhost /]# ll -d project/
drwxrwx---+ 3 root tgroup 4096 1月19 05:20 project/
#使用ls-l査询时会发现,在权限位后面多了一个"+",表示此目录拥有ACL权限
[root@localhost /]# getfacl project
#查看/prpject目录的ACL权限
#file: project <-文件名
#owner: root <-文件的属主
#group: tgroup <-文件的属组
user::rwx <-用户名栏是空的,说明是属主的权限
user:st:r-x <-用户st的权限
group::rwx <-组名栏是空的,说明是属组的权限
mask::rwx <-mask权限
other::--- <-其他人的权限
大家可以看到,st 用户既不是 /prpject 目录的属主、属组,也不是其他人,我们单独给 st 用户分配了 r-x 权限。这样分配权限太方便了,完全不用先辛苦地规划用户身份了。
我想给用户组赋予 ACL 权限可以吗?当然可以,命令如下:
[root@localhost /]# groupadd tgroup2
#添加测试组
[root@localhost /]# setfacl -m g:tgroup2:rwx project/
#为组tgroup2纷配ACL权限,使用"g:组名:权限"格式
[root@localhost /]# ll -d project/
drwxrwx---+ 2 root tgroup 4096 1月19 04:21 project/
#属组并没有更改
[root@localhost /]# getfacl project/
#file: project/
#owner: root
#group: tgroup
user::rwx
user:st:r-x
group::rwx
group:tgroup2:rwx <-用户组tgroup2拥有了rwx权限
mask::rwx
other::--
3)默认ACL权限和递归ACL权限
我们已经给 /project 目录设定了 ACL 权限,那么,在这个目录中新建一些子文件和子目录,这些文件是否会继承父目录的 ACL 权限呢?我们试试吧。
[root@localhost /]# cd /project/
[root@localhost project]# touch abc
[root@localhost project]# mkdir d1
#在/project目录中新建了abc文件和d1目录
[root@localhost project]#ll
总用量4
-rw-r--r-- 1 root root 01月19 05:20 abc
drwxr-xr-x 2 root root 4096 1月19 05:20 d1
#这两个新建立的文件权限位后面并没有"+",表示它们没有继承ACL权限
子文件 abc 和子目录 d1 因为是后建立的,所以并没有继承父目录的 ACL 权限。当然,我们可以手工给这两个文件分配 ACL 权限,但是如果在目录中再新建文件,都要手工指定,则显得过于麻烦。这时就需要用到默认 ACL 权限。
默认 ACL 权限的作用是:如果给父目录设定了默认 ACL 权限,那么父目录中所有新建的子文件都会继承父目录的 ACL 权限。默认 ACL 权限只对目录生效。命令如下:
[root@localhost /]# setfacl -m d:u:st:rx /project/
#使用"d:u:用户名:权限"格式设定默认ACL权限
[root@localhost project]# getfacl project/
# file: project/
# owner: root
# group: tgroup
user:: rwx
user:st:r-x
group::rwx
group:tgroup2:rwx
mask::rwx
other::--
default:user::rwx <-多出了default字段
default:user:st:r-x
default:group::rwx
default:mask::rwx
default:other::--
[root@localhost /]# cd project/
[root@localhost project]# touch bcd
[root@localhost project]# mkdir d2
#新建子文件和子目录
[root@localhost project]# ll 总用量8
-rw-r--r-- 1 root root 01月19 05:20 abc
-rw-rw----+ 1 root root 01月19 05:33 bcd
drwxr-xr-x 2 root root 4096 1月19 05:20 d1
drwxrwx---+ 2 root root 4096 1月19 05:33 d2
#新建的bcd和d2已经继承了父目录的ACL权限
大家发现了吗?原先的 abc 和 d1 还是没有 ACL 权限,因为默认 ACL 权限是针对新建立的文件生效的。
再说说递归 ACL 权限。递归是指父目录在设定 ACL 权限时,所有的子文件和子目录也会拥有相同的 ACL 权限。
[root@localhost project]# setfacl -m u:st:rx -R/project/
#-R递归
[root@localhost project]# ll
总用量8
-rw-r-xr--+ 1 root root 01月19 05:20 abc
-rw-rwx--+ 1 root root 01月19 05:33 bcd
drwxr-xr-x+ 2 root root 4096 1月19 05:20 d1
drwxrwx--+ 2 root root 4096 1月19 05:33 d2
#abc和d1也拥有了ACL权限
总结一下:默认 ACL 权限指的是针对父目录中新建立的文件和目录会继承父目录的 ACL 权限,格式是”setfacl-m d:u:用户名:权限 文件名”;递归 ACL 权限指的是针对父目录中已经存在的所有子文件和子目录继承父目录的 ACL 权限,格式是”setfacl-m u:用户名: 权限 -R 文件名”。
4)删除权限
删除指定的ACL权限:
[root@localhost /]# setfacl -x u:st /project/
#删除指定用户和用户组的ACL权限
[root@localhost /]# getfacl project/
# file:project/
# owner: root
# group: tgroup
user::rwx
group::rwx
group:tgroup2:rwx
mask::rwx
other::--
#st用户的权限已被删除
删除所有ACL权限:
[root@localhost /]# setfacl -b project/
#会删除文件的所有ACL权限
[root@localhost /]# getfacl project/
#file: project/
#owner: root
# group: tgroup
user::rwx
group::rwx
other::--
#所有ACL权限已被删除
9.2 最大有效权限mask
mask 是用来指定最大有效权限的。mask 的默认权限是 rwx,如果我给 st 用户赋予了 r-x 的 ACL 权限,mj 需要和 mask 的 rwx 权限”相与”才能得到 st 的真正权限,也就是 r-x “相与”rwxtj 出的值是 r-x,所以 st 用户拥有 r-x 权限。
如果把 mask 的权限改为 r—,和 st 用户的权限相与,也就是 r—“相与”r-x 得出的值是 r—,st 用户的权限就会变为只读。大家可以这么理解:用户和用户组所设定的权限必须在 mask 权限设定的范围之内才能生效,mask权限就是最大有效权限。
不过我们一般不更改 mask 权限,只要给予 mask 最大权限 rwx,那么任何权限和 mask 权限相与,得出的值都是权限本身。也就是说,我们通过给用户和用户组直接赋予权限,就可以生效,这样做更直观。
补充:逻辑与运算的运算符是”and”。可以理解为生活中所说的”并且”。也就是相与的两个值都为真,结果才为真;有一个值为假,与的结果就为假。比如 A 相与 B,结果入下所示。
A | B | and |
---|---|---|
真 | 真 | 真 |
真 | 假 | 假 |
假 | 真 | 假 |
假 | 假 | 假 |
那么两个权限相与和上面的结果类似,我们以读(r)权限为例,结果如下所示。
A | B | and |
---|---|---|
r | r | r |
r | - | - |
- | r | - |
- | - | - |
所以,”rwx”相与”r-x”,结果是”r-x”;”r—“相与”r-x”,结果是”r—“。
修改最大有效权限的命令如下:
[root@localhost /]# setfacl -m m:rx project/
#设定mask权限为r-x,使用"m:权限"格式
[root@localhost /]# getfacl project/
#file:project/
#owner:root
#group:tgroup
user::rwx
group::rwx #effective:r-x
mask::r-x
#mask权限变为r-x
other::--
10 su与sudo
10.1 介绍
因为root用户的权限太大,破坏力太强,安全风险极高,所以通常情况下公司的服务器对外都是禁止root用户直接登录的,而运维组的小伙伴通常使用的都是普通用户,但是运维组内的小伙伴们在进行日常运维管理的过程中,经常需要获得某些root才有的管理权限才能完成任务,例如需要执行/sbin目录下的命令。
那么如何才能在不使用root用户直接登录操作系统的同时又能保证普通用户完成日常工作呢,有两种方案:
1、su切换用户身份
特点:使用普通用户登录,然后使用su命令切换到root账户下
优点:简单粗暴
缺点:
1、需要知道root密码
2、权限控制不精细:每次都是获取所有root权限
2、sudo提取部分管理员权限
特点:
1、使用普通用户登录,然后sudo命令提取root用户的部分管理权限,注意只是某部分,而不是全部。
2、不需要切换到root账户下
优点:相对复杂
缺点:
1、不需要知道root密码,输入的是用户自己的密码
2、权限控制更为精细:可以控制普通用户只获取部分root权限
10.2 su切换用户
10.2.1 储备知识
Linux中shell可以分两类
登陆shell,需要输入用户名和密码才能进入Shell,日常接触的最多的一种
非登陆shell,不需要输入用户和密码就能进入Shell,比如运行bash会开启一个新的会话窗口
注意:shell的使用方式有两种
交互式,等待用户输入执行的命令(终端操作,需要不断提示)
非交互式,执行shell脚本, 脚本执行结束后shell自动退出
bash shell配置文件介绍(文件主要保存用户的工作环境)
全局配置文件:
/etc/profile
/etc/profile.d/*.sh
/etc/bashrc
个人配置文件:
~/.bash_profile
~/.bashrc
profile类文件, 设定环境变量, 登陆前运行的脚本和命令。
bashrc类文件, 设定本地变量, 定义命令别名
PS: 如果全局配置和个人配置产生冲突,以个人配置为准。
配置文件的应用顺序
如果执行的是登录式shell,那么配置文件执行顺序是:
/etc/profile->/etc/profile.d/*.sh->~/.bash_profile->~/.bashrc->/etc/bashrc
如果执行的是非登录式shell,那么配置文件执行顺序是:
~/.bashrc->/etc/bashrc->/etc/profile.d/*.sh
PS: 验证使用echo在每行添加一个输出即可,注意,要把输出放在文件的第一行。
执行登录与非登录shell
# 执行登录shell:身份与环境都切换
su - 用户
# 执行非登录shell:只切换用户身份
su 用户
# 补充:
# 1、从root往普通用户下切换无需输入密码,反之则需要
# 2、切换身份执行命令:su - 用户 -c “命令”
10.3 sudo提权
在日常的运维工作中,我们不应该把root的密码公开给所有人,因为,一方面,真那样做的话,安全风险就太高了,删库到跑路发生的概率估计会加大,另外一方面,小伙伴们大多数情况下只需要提取某一些权限来使用即可也并不是需要所全部的管理员权限,所以说sudo比su更为靠谱一些。
通过配置sudo,我们可以实现让普通用户输入自己的密码的情况下而获取我们为其配置的特定权限,这样,既保证了普通用户拥有他想要的特定权限,又不至于泄露管理root的密码。
10.3.1 sudo配置
两种编辑方式
- 1、visudo(会提示语法错误,推荐使用)
[root@xujun ~]# visudo -c # 检查配置是否正确
/etc/sudoers:解析正确
- 2、vim /etc/sudoers
# sudo 语法
user MACHINE=COMMANDS
# 示如
# root ALL=(ALL) ALL
1、root:用户
2、ALL:代表用户可以在哪台机器上执行指令,通常设置为ALL,如果设置为localhost代表在本机上执行指令。
也可以设置为本机以外的其他IP地址或主机名,此时该/etc/sudoers虽然是在本机上配置的,但用户登录到本机
后仍然是无法执行命令的,如果把/etc/sudoers这个配置文件赋值到指定ip或主机名的那台机器上,就好用了
配置文件中讲到:
## Next comes the main part: which users can run what software on
## which machines (the sudoers file can be shared between multiple
## systems).
即/etc/sudoers文件可以在多个系统之间共享,如果我们设置成ALL的话就省事了,该文件复制到人任意一台机器
上的完成的权限配置都一样
3、(All):表示允许用户以哪个用户的权限做事情
4、ALL:所有命令
最终解释:root用户可以在所有主机上以任意用户身份执行所有命令
tom ALL=(ALL) ALL # tom用户在任何机器上,可以以任何用户身份执行任何命令等同于root用户
lili ALL=(ALL) NOPASSWD: ALL # 免密
xujun ALL=(ALL) /bin/cp,/bin/touch # 只允许xujun用户以root用户的身份执行cp,touch命令
xujun01 ALL=(ALL) ALL,!/usr/bin/vim /test/a.txt # !代表取反
xujun02 ALL=(ALL) /usr/bin/passwd [a-zA-Z]*,/usr/bin/vim *,!/usr/bin/vim /test/a.txt # 可以编辑所有文件,除了/test/a.txt
# 可以测试
[root@xujun ~]# su - xujun02
上一次登录:二 12月 20 11:21:01 CST 2022pts/0 上
[xujun02@egon ~]$
[xujun02@egon ~]$ sudo vim /test/b.txt
[xujun02@egon ~]$ sudo vim /test/a.txt
对不起,用户 xujun02 无权以 root 的身份在 xujun 上执行 /bin/vim /test/a.txt。
[xujun02@xujun ~]$
测试
[root@xujun ~]# su - xujun
上一次登录:四 9月 10 20:27:09 CST 2020pts/0 上
[xujun@xujun ~]$ ll -d /etc/
drwxr-xr-x. 146 root root 8192 9月 10 20:27 /etc/
[xujun@xujun ~]$ touch /etc/a.txt # =================> 没有权限
touch: 无法创建"/etc/a.txt": 权限不够
[xujun@xujun ~]$ sudo touch /etc/a.txt # =================> 使用sudo提权
我们信任您已经从系统管理员那里了解了日常注意事项。
总结起来无外乎这三点:
#1) 尊重别人的隐私。
#2) 输入前要先考虑(后果和风险)。
#3) 权力越大,责任越大。
[sudo] xujun 的密码:
[xujun@xujun ~]$ ll /etc/a.txt
-rw-r--r-- 1 root root 0 9月 10 20:28 /etc/a.txt
ps: sudo 执行流程
1.普通用户执行sudo命令, 会检查/var/db/sudo是否存在时间戳缓存
2.如果存在则不需要输入密码, 否则需要输入用户与密码
3.输入密码会检测是否该用户是否拥有该权限
4.如果有则执行,否则报错退出
Sudo 常用参数
sudo常用参数:
-l : 登录用户下面,执行sudo -l 显示当前用户有哪些权限
-k :删除/var/db/sudo/下面对应的时间戳的信息,下次执行sudo需要输入当前用户的密码
--> 系统默认也是5分钟失效
--> 配置免密是另一种情况 NOPASSWD: ALL远程sudo(有条件限制的)
其他配置详见配置文件
10.3.2 sudo实例
企业生产环境用户权限集中管理方案实例:
根据角色的不同,给不同的用户分配不同的角色
# 1.创建初级工程师3个,网络工程师1个,中级工程师1个,经理1个
批量创建用户
for user in chuji{01..03} net01 senior01 manager01
> do
> useradd $user
> echo "111111"|passwd --stdin $user
> done;
# 2.创建5个开发人员,属于phpers组
groupadd -g 999 phpers
for n in `seq 5`
do
useradd -g phpers php0$n
done
# 3.创建开发经理,中级phper
for user in kaifaManager seniorPhper
> do
> useradd $user
> echo "111111"|passwd --stdin $user
> done
# 4.编辑配置文件
[root@localhost ~]# vim /etc/sudoers
########################Cmnd_Alias By FTL ###################################
Cmnd_Alias CY_CMD_1=/usr/bin/free, /usr/bin/iostat,/usr/bin/top, /bin/hostname, /sbin/ifconfig, /bin/netstat, /sbin/route
Cmnd_Alias GY_CMD_1=/usr/bin/free, /usr/bin/iostat,/usr/bin/top, /bin/hostname, /sbin/ifconfig, /bin/netstat, /sbin/route, /sbin/iptables, /etc/init.d/network, /bin/nice, /bin/kill, /usr/bin/kill, /usr/bin/killall, /bin/rpm, /usr/bin/updatedb, /usr/bin/yum, /sbin/fdisk, /sbin/sfdisk, /sbin/parted, /sbin/partprobe, /bin/mount, /bin/umount
Cmnd_Alias CK_CMD_1=/usr/bin/tail, /bin/grep, /var/log/messages*
Cmnd_Alias GK_CMD_1=/sbin/service, /sbin/chkconfig, /bin/tail, /var/log/*, /bin/grep, /bin/cat, /bin/ls, /bin/sh
Cmnd_Alias GW_CMD_1= /sbin/route, /sbin/ifconfig, /bin/ping, /sbin/dhclient, /usr/bin/net, /sbin/iptables, /sbin/iwconfig, /sbin/mii-tool, /bin/cat, /var/log/*
########################User Aliases By FTL ###################################
User_Alias CHUJI_YUNWEI_ADMINS=chuji01,chuji02,chuji03
User_Alias CHUJI_KAIFA_ADMINS=php01,php02,php03,php04,php05
User_Alias GAOJI_WANG_ADMINS=net01
########################Runas_Alias By FTL ###################################
Runas_Alias OP = root -->未来切换到某个角色执行任务
########################Config By FTL ###################################
senior01 ALL=(OP) GY_CMD_1
manager01 ALL=(ALL) NOPASSWD:ALL
kaifaManager ALL=(ALL) ALL, /usr/bin/passwd [A-Za-z], !/usr/bin/passwd root, !/usr/sbin/visudo,\
!/usr/bin/vi *sudoer*, !/usr/bin/sudo su -, !/bin/su
seniorPhper ALL=(OP) GK_CMD_1
CHUJI_YUNWEI_ADMINS ALL=(OP) CY_CMD_1
CHUJI_KAIFA_ADMINS ALL=(OP) CK_CMD_1
GAOJI_WANG_ADMINS ALL=(OP) GW_CMD_1
命令的路径要全路径
别名需要大写
超过一行,用"\"换行
排除的命令一定在最后面写
kaifaManager 因为有ALL,所以可以直接su - 切换root,但是 sudo su -切换不了