1. Linux安全模型
资源分派:
Authentication: 认证, 验证用户身份
Authorization: 授权, 不同的用户设置不同的权限
Accounting|Audition: 审计
当用户登录成功时, 系统会自动分配令牌TOKEN, 包括: 用户标识和组成员等信息
1.1 用户
Linux中每个用户是通过User ID(UID)来唯一标识的
- 管理员: root, 0
- 普通用户: 1-60000 自动分配
系统用户: 1-499(CentOS6以前), 1-999(CentOS7以后)
对守护进程获取资源进行权限分配
登录用户: 500+(CentOS6以前), 1000+(CentOS7以后)
给用户进行交互式登录使用
- 如何区分root和普通用户?
看用户id, uid=0, 就是root账户, 非0就是普通用户
- 查看当前登录用户uid:
echo $UID
[13:15:24 root@centos8-3 ~]#echo $UID
0
- id USERNAME: 查看用户id, 基本组id, 基本组和附加组信息
[10:36:16 root@centos8-3 ~]#id mysql
uid=27(mysql) gid=27(mysql) groups=27(mysql)
- id - u: 查看当前用户id
[10:36:18 root@centos8-3 ~]#id -u
0
- id -u USERNAME: 查看某个用户的id(无需root权限, 因为/etc/passwd和/etc/group是644权限, 所有用户都可以查看)
[10:37:19 root@centos8-3 ~]#id -u mysql
27
1.2 用户组
Linux中可以将一个或多个用户加入用户组中, 用户组是通过Group ID(GID)来唯一标识的
- 管理员组: root, 0
- 普通组:
系统组: 1-499(CentOS6以前), 1-999(CentOS7以后), 对守护进程获取资源进行权限分配
普通组: 500+(CentOS6以前), 1000+(CentOS7以后), 给用户使用
用户组是通过组id唯一标识, root组是0
1.3 用户和组的关系
用户的主要组,(primary group): 用户必须属于一个且只有一个主组, 默认创建用户时会自动创建和用户名同名的组, 作为用户的主要组, 由于此组只有一个用户, 又称为私有组
用户的附加组,(supplementary group): 一个用户可以属于零个或多个辅助组,附属组
id postfix
# 主组 # 附加组
uid=89(postfix) gid=89(postfix) groups=89(postfix),12(mail)
1.4 安全上下文
Linux安全上下文Context: 运行中的程序, 即进程(process), 以进程发起者的身份
运行, 进程所能够访问资源的权限
取决于进程的运行者的身份
比如: 分别以root和普通用户身份运行, /bin/cat /etc/shadow
, 得到的结果是不同的, 资源能否被访问, 是由运行者
的身份决定, 非程序本身
# 以wang身份, 使用cat命令, 访问/etc/shadow
[wang@demo-c8 ~]$ cat /etc/shadow
cat: /etc/shadow: Permission denied
# 以root身份, 使用cat命令, 访问/etc/shadow
[root@demo-c8 ~]# cat /etc/shadow
root:$6$YD64S7fSNEcHhV6s$cR6V/rj9Te2GdnE.WJQvlVup9cn8cSDsKaDHazCloevgmSvrswUYC9enlpI5CCVPRQZwA58VyUxvCpval6BaW0::0:99999:7:::
bin:*:18358:0:99999:7:::
daemon:*:18358:0:99999:7:::
adm:*:18358:0:99999:7:::
...
用户登录系统, 通过了验证后, 系统会自动给用户发放一个token
令牌, 当用户运行某一程序, 访问系统资源时, 该程序会携带用户的token, 程序把token信息提交给资源, 资源检查这个token是否有相应的权限, 有权限则运行, 没权限则拒绝.
2 用户和组的配置文件
2.1 用户和组的主要配置文件
/etc/passwd: 用户及其属性信息(名称, UID, 主组ID等)
/etc/shadow: 用户密码及其相关属性
/etc/group: 组及其属性信息
/etc/gshadow: 组密码及其相关属性
2.2 /etc/passwd
查看:
cat /etc/passwd
getent passwd
#只显示对应的用户那一行
getent passwd root
[12:01:46 root@centos8-3 ~]#getent passwd root
root:x:0:0:root:/root:/bin/bash
格式:
man 5 passwd
name:password:UID:GID:GECOS:directory:shell
name This is the user's login name. It should not contain capital let‐
ters. ####用户名不能有大写字母
password This is either the encrypted user password, an asterisk (*), or
the letter 'x'. (See pwconv(8) for an explanation of 'x'.)
UID The privileged root login account (superuser) has the user ID 0.
GID This is the numeric primary group ID for this user. (Additional
groups for the user are defined in the system group file; see
group(5)).
GECOS This field (sometimes called the "comment field") is optional and
used only for informational purposes. Usually, it contains the
full username. Some programs (for example, finger(1)) display
information from this field.
GECOS stands for "General Electric Comprehensive Operating Sys‐
tem", which was renamed to GCOS when GE's large systems division
was sold to Honeywell. Dennis Ritchie has reported: "Sometimes we
sent printer output or batch jobs to the GCOS machine. The gcos
field in the password file was a place to stash the information
for the $IDENTcard. Not elegant."
directory This is the user's home directory: the initial directory where the
user is placed after logging in. The value in this field is used
to set the HOME environment variable.
shell This is the program to run at login (if empty, use /bin/sh). If
set to a nonexistent executable, the user will be unable to login
through login(1). The value in this field is used to set the
SHELL environment variable.
name: 登录用户名(wang)
passwd: 密码(x)
UID: 用户身份编号(1000)
GID: 登录默认所在组编号(1000, 主组)
GECOS: 用户全名或注释
home directory: 用户家目录(/home/wang)
shell: 用户默认使用shell(/bin/bash), 系统程序无需登录系统, 所以shell类型是/sbin/nologin
- 老的系统, 直接把密码放在这个文件里, 新的系统, 密码存到了
/etc/shadow
里, 在/etc/passwd中用'x'占位, 表示该用户有密码, 且放在了/etc/shadow文件里 - 如果把x占位删了, 那么用户还是可以用密码登录, 不会造成影响
- 即使用户没有密码, 也会用x占位
#当前用户david有密码, 且存到了/etc/shadow文件
[12:06:13 root@centos8-3 ~]#getent passwd david
david:x:1000:1000::/home/david:/bin/bash
[12:06:18 root@centos8-3 ~]#getent shadow david
david:$6$8d9jd740.1lroUmY$SPOZMn0cdtatKl.21dRoY/05NILIWdeCiGCpAxU..YmjnPcf.hPuL9BagSYshD2R.csft3O0RfPB1h64nRcAs/:18494:0:99999:7:::
#将/etc/passwd中david一行的x占位符删除, shadow文件中, 加密的密码还存在
[12:07:30 root@centos8-3 ~]#vim /etc/passwd
david::1000:1000::/home/david:/bin/bash
[12:07:30 root@centos8-3 ~]#getent shadow david
david:$6$8d9jd740.1lroUmY$SPOZMn0cdtatKl.21dRoY/05NILIWdeCiGCpAxU..YmjnPcf.hPuL9BagSYshD2R.csft3O0RfPB1h64nRcAs/:18494:0:99999:7:::
#david用户也可以正常登录
Last login: Thu Aug 20 12:10:27 2020
[12:11:26 david@centos8-3 ~]$
2.3 /etc/shadow
如果通过root账户把shadow文件权限改了, 那么普通用户也可以查看, 修改该文件内容
格式: man 5 shadow
login name
It must be a valid account name, which exist on the system. #
encrypted password
Refer to crypt(3) for details on how this string is interpreted.
If the password field contains some string that is not a valid result of
crypt(3), for instance ! or *, the user will not be able to use a unix
password to log in (but the user may log in the system by other means).
This field may be empty, in which case no passwords are required to
authenticate as the specified login name. However, some applications which
read the /etc/shadow file may decide not to permit any access at all if
the password field is empty.
A password field which starts with an exclamation mark means that the
password is locked. The remaining characters on the line represent the
password field before the password was locked.
date of last password change
The date of the last password change, expressed as the number of days
since Jan 1, 1970 00:00 UTC.
The value 0 has a special meaning, which is that the user should change
her password the next time she will log in the system.
An empty field means that password aging features are disabled.
minimum password age
The minimum password age is the number of days the user will have to wait
before she will be allowed to change her password again.
An empty field and value 0 mean that there are no minimum password age.
maximum password age
The maximum password age is the number of days after which the user will
have to change her password.
After this number of days is elapsed, the password may still be valid. The
user should be asked to change her password the next time she will log in.
An empty field means that there are no maximum password age, no password
warning period, and no password inactivity period (see below).
If the maximum password age is lower than the minimum password age, the
user cannot change her password.
password warning period
The number of days before a password is going to expire (see the maximum
password age above) during which the user should be warned.
An empty field and value 0 mean that there are no password warning period.
password inactivity period
The number of days after a password has expired (see the maximum password
age above) during which the password should still be accepted (and the
user should update her password during the next login).
After expiration of the password and this expiration period is elapsed, no
login is possible for the user. The user should contact her administrator.
An empty field means that there are no enforcement of an inactivity
period.
account expiration date
The date of expiration of the account, expressed as the number of days
since Jan 1, 1970 00:00 UTC.
Note that an account expiration differs from a password expiration. In
case of an account expiration, the user shall not be allowed to login. In
case of a password expiration, the user is not allowed to login using her
password.
An empty field means that the account will never expire.
The value 0 should not be used as it is interpreted as either an account
with no expiration, or as an expiration on Jan 1, 1970.
reserved field
This field is reserved for future use.
[12:15:25 root@centos8-3 ~]#getent shadow root
root:$6$k2xA4YZard4r8z9L$URnVG1KSzOD4lxneh/1jGOeWllSWRbTrC2OGfkg5nbD5jdQn8NdM2khsXjkyDnX0XvIXM.bVTmx7MsYIoN/sf/::0:99999:7:::
login name: 用户名
encrypted password: 加密的用户密码字符串, 一般用SHA512加密
$6$k2xA4YZard4r8z9L$URnVG1KSzOD4lxneh/1jGOeWllSWRbTrC2OGfkg5nbD5jdQn8NdM2khsXjkyDnX0XvIXM.bVTmx7MsYIoN/sf/
- 6: 表示加密算法, 用户密码使用SHA512哈希算法加密. CentOS5用MD5, 从CentOS6开始, 就是SHA512了
- k2xA4YZard4r8z9L: salt, 随机字符串, 哈希算法, 单项加密时, 如果数据一样, 那么加密结果必定一样, 因此, 在给用户密码加密时, 要添加随机字符串, 也就是salt, 之后会将salt和密码一起加密,存放到shadow文件, 避免由于密码相同造成泄漏
- URnVG1KSzOD4lxneh/1jGOeWllSWRbTrC2OGfkg5nbD5jdQn8NdM2khsXjkyDnX0XvIXM.bVTmx7MsYIoN/sf/: 这是把salt和密码加密后的字符串
范例: 利用openssl生成加密字符串, 对比salt的作用
假设root密码是000000
可以看到, 用相同的salt, k2xA4YZard4r8z9Ll , 采用相同的加密算法, -6: SHA512, 给相同的字符串加密时, 得到的结果是一样的
[12:32:30 root@centos8-3 ~]#getent shadow root
root:$6$k2xA4YZard4r8z9L$URnVG1KSzOD4lxneh/1jGOeWllSWRbTrC2OGfkg5nbD5jdQn8NdM2khsXjkyDnX0XvIXM.bVTmx7MsYIoN/sf/::0:99999:7:::
[12:32:34 root@centos8-3 ~]#openssl passwd -salt k2xA4YZard4r8z9Ll -6 000000
$6$k2xA4YZard4r8z9L$URnVG1KSzOD4lxneh/1jGOeWllSWRbTrC2OGfkg5nbD5jdQn8NdM2khsXjkyDnX0XvIXM.bVTmx7MsYIoN/sf/
- 如果此处是'!!',表示密码被锁定,或者用户没有密码, 那么用户就会无法登录. Ubuntu系统刚装好时, root账号就是显示'!!', 因此root无法登陆, 我们需要登录到普通账户, sudo -i切换到root账号,然后给root重置密码
date of last password change:
密码下一位表示的是最近一次密码的更改时间: 以1970年1月1号开始,到上一次修改密码的天数, 如果设置为0, 那么用户下一次登录就必须修改密码
minimum password age:
下一位: 密码最短有效期, 比如今天改了密码, 那么要过了相应的天数后才能再次修改. 如果数值是0, 表示没有最短使用天数限制, 如果是3, 表示3天后才能修改. 这个只限制了普通用户改自己的密码, 如果是root用户, 可以随时修改任何人的密码
maximum password age:
下一位: 密码最长有效期, 改了密码后, 再过多少天密码就会过期, 以天为单位. 可以修改此项, 限制
password warning period:
下一位: 上一位定义的密码有效期到期前, 提前几天提醒用户修改密码
password inactivity period:
下一位: 密码有效期到了之后, 宽限的天数, 如果超过了这个宽限天数, 还没有修改, 那么账号就被锁定, 用户无法登录
account expiration date:
下一位: 账户有效期, 从1970年1月1号, 到账户失效那天的天数
范例: 修改普通用户david和root用户的id, vim /etc/passwd, 普通用户就会成为超级管理员, root成为普通用户
[13:07:09 root@centos8-3 ~]#getent passwd root david
root:x:0:0:root:/root:/bin/bash
david:x:1000:1000::/home/david:/bin/bash
#修改passwd文档后
[13:07:55 root@centos8-3 ~]#getent passwd root david
root:x:2000:0:root:/root:/bin/bash
david:x:0:1000::/home/david:/bin/bash
#退出终端,重新用root登录
#尝试修改其他用户密码, 发现权限不够
[13:08:36 root@centos8-3 ~]$passwd david
passwd: Only root can specify a user name.
#登录david账户, 发现可以修改原本的root密码
[13:09:44 david@centos8-3 ~]#passwd root
Changing password for user root.
New password:
Retype new password:
passwd: all authentication tokens updated successfully.
#因此, 系统区分root用户和普通用户区别就是看uid
如果passwd文档中, 除了root用户, 还有其他用户uid为0, 那么这些用户也会被当做root用户
#修改了passwd文档, root和david都是uid=0
[13:13:23 root@centos8-3 ~]#getent passwd root david
root:x:0:0:root:/root:/bin/bash
david:x:0:1000::/home/david:/bin/bash
#从root切换到david, 发现还是root用户
[13:14:04 root@centos8-3 ~]#su - david
Last login: Thu Aug 20 13:14:03 AEST 2020 from 10.0.0.1 on pts/0
[13:14:06 root@centos8-3 ~]#
/etc/passwd文件的权限是644, 只有属主owner(root)才有权限修改, 所以不会出现普通用户修改该文件的情况
2.4 /etc/group
- 包含:
组名
组密码: 早期组也有密码, 现在不需要了, 通过x占位. 因为一旦给组制定了密码, 那么普通用户如果知道了组的密码, 就可以把自己加到组里面, 随即拥有了该组对应的权限. 危险. 因此,现在组的添加都是root管理员负责. 如果给组设定了密码, 密码会存在/etc/gshadow文件中
组id
组成员用户名: 这些成员把该组作为附加组. 而用户的主组信息, 存在/etc/passwd里, 用GID表示.
2.5 /etc/gshadow
- 包含:
组名称
组密码
组管理员信息: 把用户设定为该组的管理员, 之后可以管理组的信息, 添加删除用户, 设置组密码
组成员用户名: 这些成员把该组作为附加组. 用户的主组, 在/etc/passwd里, gid.
这些文件里, 对应的信息都要保持一致, 否则会有问题
2.6 文件操作
- vipw和vigr
- pwck和grpck
3 用户和组管理命令
直接修改用户和组配置文件很繁琐, 容易出错, 因此一般通过管理命令来修改
用户管理命令
- useradd 添加
- usermod 修改
- userdel 删除
组账户维护命令
- groupadd 添加
- groupmod 修改
- groupdel 删除
3.1 用户创建
创建一个用户后, 用户和组的四个配置文件都会被修改
格式:
useradd [options] 用户名
选项:
-u 指定UID
-o 配合-u, 不检查UID唯一性, 允许UID重复
-g GID, 指明用户所属的基本组, 可以直接写组名, 也可以写GID, 创建用户时, 默认会创建一个和用户同名的组, 并且把该组作为用户的基本组
-c "COMMENT" 用户注释信息
-d HOME_DIR, 设置用户的家目录, 注意, 该目录必须是不存在的, 无论是普通用户还是系统用户, 若想创建家目录, 并且自定义家目录位置, 就用-d选项. 之后, 该家目录需要手动创建, 如果需要修改目录权限, 就用root账户去修改
-s SHELL, 指明用户的默认shell程序, 可用的shell程序在/etc/shells定义
-G GROUP1[,GROUP2,...], 为用户指明附加组, 注意, 组必须是已经存在的, 可以添加多个附加组
-N 不创建私用组也就是和用户同名的组作为主组, 而是使用users这个组作为主组
[root@demo-c8 ~]# getent group users
users:x:100:
-r 创建系统用户, CentOS6之前, 系统用户UID为1-499, CentOS7之后, 系统用户UID为1-999, 如果没有指定UID, 那么会在1-999自动分配一个
-m 创建用户家目录, 用于系统用户, 默认不会给系统用户创建家目录, 使用-m会在/home下给系统用户创建家目录
-M 不创建用户家目录, 用于非系统用户, 普通用户在创建时会自动在/home下创建家目录, 通过-M, 可以不创建家目录
范例: 创建普通用户, useradd lala
[13:21:34 root@centos8-3 ~]#useradd lala
l[13:32:56 root@centos8-3 ~]#ll /etc/passwd /etc/group /etc/shadow /etc/gshadow
-rw-r--r-- 1 root root 576 Aug 20 13:32 /etc/group
---------- 1 root root 452 Aug 20 13:32 /etc/gshadow
-rw-r--r-- 1 root root 1393 Aug 20 13:32 /etc/passwd
---------- 1 root root 911 Aug 20 13:32 /etc/shadow
[13:33:15 root@centos8-3 ~]#stat !*
stat /etc/passwd /etc/group /etc/shadow /etc/gshadow
File: /etc/passwd
Size: 1393 Blocks: 8 IO Block: 4096 regular file
Device: 802h/2050d Inode: 134677492 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2020-08-20 13:32:56.596705520 +1000
Modify: 2020-08-20 13:32:56.588705521 +1000
Change: 2020-08-20 13:32:56.589705521 +1000
Birth: -
File: /etc/group
Size: 576 Blocks: 8 IO Block: 4096 regular file
Device: 802h/2050d Inode: 134677440 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2020-08-20 13:32:56.664705516 +1000
Modify: 2020-08-20 13:32:56.645705517 +1000
Change: 2020-08-20 13:32:56.646705517 +1000
Birth: -
File: /etc/shadow
Size: 911 Blocks: 8 IO Block: 4096 regular file
Device: 802h/2050d Inode: 134677475 Links: 1
Access: (0000/----------) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2020-08-20 13:32:56.612705519 +1000
Modify: 2020-08-20 13:32:56.612705519 +1000
Change: 2020-08-20 13:32:56.634705518 +1000
Birth: -
File: /etc/gshadow
Size: 452 Blocks: 8 IO Block: 4096 regular file
Device: 802h/2050d Inode: 134677484 Links: 1
Access: (0000/----------) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2020-08-20 13:32:56.650705517 +1000
Modify: 2020-08-20 13:32:56.650705517 +1000
Change: 2020-08-20 13:32:56.651705517 +1000
Birth: -
useradd lala
创建了用户后, 除了在四个配置文件里, 添加用户名, uid, 基本组, gid,等账号密码信息, 还会在/home下创建以用户名为目录的家目录, 以及给用户分配默认shell类型, 同时还会在/var/spool/mail下创建属于该用户的邮箱
[13:33:25 root@centos8-3 ~]#ls /home
david lala
[13:35:29 root@centos8-3 ~]#ll /var/spool/mail
total 0
-rw-rw---- 1 david mail 0 Aug 20 10:37 david
-rw-rw---- 1 lala mail 0 Aug 20 13:32 lala
-rw-rw----. 1 rpc mail 0 Aug 12 20:07 rpc
范例: 创建系统账户, 指定各种属性
useradd -r -u 48 -g apache -s /sbin/nologin -d /var/www -c "Apache" apache
-r: 创建系统账户, 如果是系统用户, 那么默认就不会在/home创建用户家目录, 也不会在其他位置创建家目录, 想要创建家目录的话,需要在-d选项指明, 并且-d选项不会自动创建指定的家目录, 需要手动创建该目录
-u: UID
-g: 基本组, 必须已经存在, 如果不存在, 默认会创建一个和用户同名的组,作为其基本组
-s: shell类型/ /bin/false和/sbin/nologin都是不允许用户登录, CentOS都支持, Ubuntu只有/bin/false
-d: 家目录路径
-c: 描述
- useradd命令在创建用户时的默认属性由
/etc/default/useradd
定义, 或者执行useradd -D
也能查看该文件的内容
[14:05:07 root@centos8-3 ~]#vim /etc/default/useradd
# useradd defaults file
GROUP=100
HOME=/home
INACTIVE=-1 # 对应/etc/shadow文件第七列, 即用户密码过期的宽限期
EXPIRE= # 对应/etc/shadow文件第八列, 即用户账号的有效期
SHELL=/bin/bash
SKEL=/etc/skel # 包含创建用户家目录的模板文件, 创建了用户家目录后, /home/xx里面会包含三个隐藏文件, 就是从该目录拷贝过去的. 默认是三个隐藏文件, 也可以自行创建普通文件放进去, 这样用户创建后, 就会有自定义的普通文件, 这个普通文件也是从/etc/skel复制过去的
CREATE_MAIL_SPOOL=yes
[14:07:47 root@centos8-3 ~]#ls -a /home/lala
. .. .bash_logout .bash_profile .bashrc
[14:07:54 root@centos8-3 ~]#ls -a /etc/skel/
. .. .bash_logout .bash_profile .bashrc
练习: 希望新建用户的家目录里有abc文件?
在/etc/skel目录中, 创建abc文件, 这样新建的用户家目录就会有abc文件.
修改完/etc/skel内容后, 会立即生效, 不需要退出root账户, 直接创建新用户, 就会在家目录生成相应文件
修改模板后, 只会影响新建用户
[14:08:43 root@centos8-3 ~]#cd /etc/skel/
[14:17:45 root@centos8-3 /etc/skel]#touch abc.txt
[14:18:24 root@centos8-3 /etc/skel]#ls
abc.txt
[14:18:25 root@centos8-3 /etc/skel]#useradd oohh
[14:18:35 root@centos8-3 /etc/skel]#ls /home/oohh/
abc.txt
3.2 用户属性修改
usermod可以修改用户属性
格式:
usermod [option] 用户名
常见选项:
-u UID: 指定新的UID
-g GID: 指定新的主组GID
-G GROUP1[,GROUP2,...]: 指定新的附加组ID, 默认会覆盖原有的附加组, 如果想追加附加组, 需要配合-a选项
-s SHELL: 修改使用的shell
-c 'COMMENT' 添加注释
-d HOME_DIRECTORY, 指定新的家目录, 需要手动创建目录, 若要创建新家目录并移动原价目录数据, 同时使用-m选项
-l 用户名, 指定新的用户名
-L 用户名, 锁定用户, 会在/etc/shadow密码栏加!!
-U 用户名, 解锁用户, 去掉/etc/shadow密码栏的!!
-e YYYY-MM-DD, 指定用户账号过期时间
-f INACTIVE: 设定非活动期间, 即密码过期后的宽限期
3.3 删除用户
格式:
userdel [options] USERNAME
不加任何选项, 只会删除用户, 但是家目录, 邮箱都会保留, 如果想保留用户数据, 可以不加选项
userdel -r USERNAME, 会把数据都删了, 包括用户家目录和邮箱
userdel -f, 强制删除
3.4 查看用户相关的ID信息
id命令可以查看用户的UID, GID等信息
id [option]... [user]
常见选项:
-u 显示UID
-g 显示GID
-G 显示用户所属的组和ID
-n 显示名称, 需配合ugG使用
3.5 切换用户或以其他用户身份执行命令
su: 即switch user, 该命令用于切换用户身份, 并且以指定用户的身份执行命令
格式:
su [options] [-] [user [args...]]
常见选项:
-l, --login su -l 用户名, 相当于 su - 用户名
-c, --command pass a single command to the shell with -c
切换用户的方式:
su USERNAME: 非登录式切换, 即不会读取目标用户的配置文件, 也不会改变当前工作目录, 即不完全切换
su - USERNAME: 登录式切换, 会读取目标用户的配置文件, 切换至目标用户的家目录, 即完全切换
说明: root通过su, 切换至其他用户时, 无需输入密码, 非root用户, 通过su, 切换到其他用户时, 需要输入对应用户的密码
注意: su切换到新用户后, 要使用exit退回至原来的用户, 而不要使用su切换至原来的账户, 否则会生成很多的bash子进程, 环境可能会混乱
su USERNAME vs su - USERNAME
su USERNAME: 非完全切换
- 切换后的工作目录,还停留在切换前的工作目录
- 切换后的PATH变量,保留了root的PATH变量信息
[14:28:07 root@centos8-3 ~]#su david
[14:31:02 david@centos8-3 /root]$echo $PATH
/home/david/.local/bin:/home/david/bin:/data/scripts:/data/scripts:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
su - USERNAME: 完全切换, 等于 su -l USERNAME
- 切换后, 当前工作目录就是切换后的用户的自己的家目录
- 切换后, PATH就是自己账户的PATH变量
- 即使是从root su - 到普通用户, 切换后的工作目录也是普通用户的家目录
[14:37:33 root@centos8-3 ~]#su - david
Last login: Thu Aug 20 14:36:09 AEST 2020 on pts/0
[14:37:36 david@centos8-3 ~]$pwd
/home/david
[14:37:37 david@centos8-3 ~]$echo $PATH
/home/david/.local/bin:/home/david/bin:/data/scripts:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin
root用户和普通用户的PATH变量是不同的
[root@demo-c8 ~]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
[wang@demo-c8 ~]$ echo $PATH
/home/wang/.local/bin:/home/wang/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin
su - USERNAME -c CMD: 以别的用户的身份执行命令, 命令执行完退回当前用户身份
普通用户临时切换成root用户执行命令, 需要知道root密码
[14:41:22 david@centos8-3 ~]$su - root -c 'cat /etc/passwd'
Password:
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
3.6 设置密码
passwd可以修改用户密码
格式:
passwd [options] USERNAME
常用选项:
-d: 删除指定用户密码
-l: 锁定指定用户
-u: 解锁指定用户
-e: 强制用户下次登录时修改密码
-f: 强制修改
-n MINDAYS: 指定密码最短使用期限
-x MAXDAYS: 指定密码最长使用期限
-w WARNDAYS: 提前几天开始密码过期警告
-i INACTIVEDAYS: 非活动期限
--stdin: 从标准输入接收用户密码, Ubuntu无此选项, Ubuntu可以用chpasswd
# CentOS独有
echo 000000 | passwd --stdin wang
# CentOS和Ubunut通用的修改密码方法
echo wang:000000 | chpasswd
echo -e "123456\n123456" | passwd wang
-e: 创建用户后, 先通过passwd USERNAME给用户设置一个初始密码, 这样用户能够完成登录 之后管理员再通过passwd -e USERNAME选项强制用户下次登录修改密码. 该命令实际修改了/etc/shadow文件, 对应用户在date of last password change字段的值, 修改为0了, 也就是从1970年1月1日到上次修改密码是0天, 所有下次登录必须修改密码
# 先创建owen用户, 设置密码, 然后使用-e选项, 强制用户下次登录修改密码
[root@demo-c8 ~]# useradd owen
[root@demo-c8 ~]# passwd owen
Changing password for user owen.
New password:
BAD PASSWORD: The password is a palindrome
Retype new password:
passwd: all authentication tokens updated successfully.
[root@demo-c8 ~]# passwd -e owen
Expiring password for user owen.
passwd: Success
# owen用户登录
[root@demo-c8 ~]# clear
[root@demo-c8 ~]# ssh [email protected]
[email protected]'s password: #1. 先通过原始密码登录
You are required to change your password immediately (administrator enforced)
Activate the web console with: systemctl enable --now cockpit.socket
Last login: Sat Aug 20 23:00:50 2022 from 10.0.0.108
WARNING: Your password has expired.
You must change your password now and login again!
Changing password for user owen.
Current password: #2. 输入原始密码
New password: #3. 输入新的密码, 因为是普通用户修改自己的密码, 所以必须符合复杂度要求
Retype new password: #4. 重复输入新密码
passwd: all authentication tokens updated successfully.
Connection to 10.0.0.108 closed.
[root@demo-c8 ~]# ssh [email protected]
[email protected]'s password: #5. 用新密码登录
Activate the web console with: systemctl enable --now cockpit.socket
Last login: Sat Aug 20 23:01:02 2022 from 10.0.0.108
[owen@demo-c8 ~]$
修改用户密码方法
- passwd USERNAME # 需要输入两次密码
- echo USERNAME:PASSWORD | chpasswd # 可以直接修改密码
- echo PASSWORD | passwd --stdin USERNAME # 仅适用于红帽系统
- 非交互式修改密码
#此方式适用于各种Linux版本,
[14:56:57 root@centos8-3 ~]#echo -e 'ilovelinux\nilovelinux' | passwd david
Changing password for user david.
New password: Retype new password: passwd: all authentication tokens updated successfully.
#此方式只用于红帽系列
[14:57:55 root@centos8-3 ~]#echo 'linuxloveme' | passwd --stdin david
Changing password for user david.
passwd: all authentication tokens updated successfully.
3.7 修改用户密码策略
如果是普通用户给自己修改密码,必须符合密码组合条件, 比如大于8个字符, 大小写都要有等等. 而通过root用户给自己或者给其他用户设置密码, 是没有复杂度要求的
- chage -l USERNAME: 查看用户密码策略, 看的是shadow文件里的内容, 因此只有root用户可以执行
常见选项:
-d 表示的是最近一次密码的更改时间: 以1970年1月1号开始,到上一次修改密码的天数, 如果设置为0, 那么用户下一次登录就必须修改密码
-m 密码最短有效期, 比如今天改了密码, 那么要过了相应的天数后才能再次修改. 如果数值是0, 表示没有最短使用天数限制, 如果是3, 表示3天后才能修改. 这个只限制了普通用户改自己的密码, 如果是root用户, 可以随时修改任何人的密码
-M 密码最长有效期, 改了密码后, 再过多少天密码就会过期, 以天为单位. 可以修改此项, 限制
-W 上一位定义的密码有效期到期前, 提前几天提醒用户修改密码
-I 密码有效期到了之后, 宽限的天数, 如果超过了这个宽限天数, 还没有修改, 那么账号就被锁定, 用户无法登录
-E 账户有效期, 从1970年1月1号, 到账户失效那天的天数
[14:57:59 root@centos8-3 ~]#chage -l david
Last password change : Aug 20, 2020
Password expires : never
Password inactive : never # 宽限期
Account expires : never
Minimum number of days between password change : 0
Maximum number of days between password change : 99999
Number of days of warning before password expires : 7
[15:00:41 root@centos8-3 ~]#chage -l root
Last password change : Aug 20, 2020
Password expires : never
Password inactive : never
Account expires : never
Minimum number of days between password change : 0
Maximum number of days between password change : 99999
Number of days of warning before password expires : 7
[15:00:44 root@centos8-3 ~]#su - david
Last login: Thu Aug 20 14:37:36 AEST 2020 on pts/0
[15:00:48 david@centos8-3 ~]$chage -l root
chage: Permission denied.
范例: 修改用户密码策略
[root@demo-c8 ~]# chage -m 3 -M 42 -W 14 -I 7 -E 2022-11-11 wang
[root@demo-c8 ~]# chage -l wang
Last password change : never
Password expires : never
Password inactive : never
Account expires : Nov 11, 2022
Minimum number of days between password change : 3
Maximum number of days between password change : 42
Number of days of warning before password expires : 14
范例: 强制用户下次登录修改密码
# 把date of last password change设置为0, 这样下次登录就必须修改密码
chage -d 0 wang
# 或者passwd -e USERNAME
3.8 用户相关的其他命令
- chfn 指定个人信息. COMMENT列的内容
- chsh 指定shell, 相当于usermod -s
- finger 可查看用户个人信息
root@demo-c8 ~]# chfn wang
Changing finger information for wang.
Name [wang]: wangxiaoning
Office []: it
Office Phone []: 100000
Home Phone []: 11111
Finger information changed.
[root@demo-c8 ~]# getent passwd wang
wang:x:1000:1000:wangxiaoning,it,100000,11111:/home/wang:/bin/bash
root@demo-c8 ~]# chsh -s /bin/sh wang
Changing shell for wang.
Shell changed.
[root@demo-c8 ~]# getent passwd wang
wang:x:1000:1000:wangxiaoning,it,100000,11111:/home/wang:/bin/sh
3.9 创建组
groupadd实现创建组, 把用户加到组里, 用户就有了该组的权限
常见选项:
-g GID 指明组ID
-r 创建系统组, CentOS6之前, ID 1-499, CentOS7之后, ID 1-999
范例:
[root@demo-c8 ~]# groupadd -g 48 -r apache
[root@demo-c8 ~]# getent group apache
apache:x:48:
3.10 修改组
groupmod 组属性修改
usermod -g: 修改用户的基本组信息
usermod -G: 修改用户的附加组信息
格式:
groupmod [option] group
常见选项:
-n 组的新名字
-g 组的新ID
一般都是把用户添加到一个附加组, 基本组很少动
用户必须属于一个且只有一个主组
一个用户可以属于零个或多个附属组
usermod -G GROUPNAME USERNAME: 该命令会把用户加入到指定附加组, 但是如果给同一个用户添加不同附加组时, 先加入的会被后面的组取代, 无法保留多个附加组
[15:02:12 root@centos8-3 ~]#groupadd g1
[15:13:41 root@centos8-3 ~]#groupadd g2
[15:13:43 root@centos8-3 ~]#groupadd g3
[15:13:44 root@centos8-3 ~]#usermod -G g1 david
[15:13:50 root@centos8-3 ~]#usermod -G g2 david
[15:13:52 root@centos8-3 ~]#id david
uid=1000(david) gid=1000(david) groups=1000(david),1006(g2)
[15:13:57 root@centos8-3 ~]#usermod -G g3 david
[15:14:10 root@centos8-3 ~]#id david
uid=1000(david) gid=1000(david) groups=1000(david),1007(g3)
如果想把一个用户添加到多个附加组, 需要再加 -a 选项
-a 要在 -G 选项前面, 组名之间逗号隔开, 不能用空格,
[15:17:43 root@centos8-3 ~]#usermod -a -G g1,g2,g3 david
[15:17:47 root@centos8-3 ~]#id david
uid=1000(david) gid=1000(david) groups=1000(david),1005(g1),1006(g2),1007(g3)
- groupmems: 查看, 修改组信息的命令
查看组成员:
groupmems -l -g g1 # -l 在前 -g 在后 Usage: groupmems [options] [action]
[15:18:28 root@centos8-3 ~]#groupmems -l -g g1
david
[15:19:45 root@centos8-3 ~]#groupmems -l -G g1
groupmems: invalid option -- 'G'
Usage: groupmems [options] [action]
Options:
-g, --group groupname change groupname instead of the user's group
(root only)
-R, --root CHROOT_DIR directory to chroot into
Actions:
-a, --add username add username to the members of the group
-d, --delete username remove username from the members of the group
-h, --help display this help message and exit
-p, --purge purge all members from the group
-l, --list list the members of the group
3.11 组删除
groupdel 可以删除组
格式:
groupdel [options] GROUP
常见选项:
-f 强制删除, 即使是用户的主组也会被强制删除
把某用户, 从其所有的附加组中移除
usermod -G "" david # 组名为空, 就是从附加组移除
附加组, 即使里面有人, 也可以随便删
[15:24:42 root@centos8-3 ~]#groupmems -l -g g2
david
[15:24:51 root@centos8-3 ~]#groupdel g2
基本组删除需要使用-f选项, groupdel -f, 会把基本组删除
[root@demo-c8 ~]# id wang
uid=1000(wang) gid=1000(wang) groups=1000(wang)
[root@demo-c8 ~]# groupdel -f wang
[root@demo-c8 ~]# getent group wang
[root@demo-c8 ~]# id wang
uid=1000(wang) gid=1000 groups=1000
3.11 更改组密码
gpasswd命令, 可以修改组密码. 也可以修改附加组的成员关系
格式:
gpasswd [option] GROUP
常见选项:
-a user 将user添加到指定组
-d user 从指定附加组中移除指定用户
-A user1, user2, ... 设置有组管理权限的用户列表
# 增加组成员
[root@demo-c8 ~]# groupadd -g 1002 admins
[root@demo-c8 ~]# id wang
uid=1000(wang) gid=1000(wang) groups=1000(wang)
[root@demo-c8 ~]# gpasswd -a wang admins
Adding user wang to group admins
[root@demo-c8 ~]# id wang
uid=1000(wang) gid=1000(wang) groups=1000(wang),1002(admins)
[root@demo-c8 ~]# groups wang
wang : wang admins
[root@demo-c8 ~]# getent group admins
admins:x:1002:wang
# 删除组成员
[root@demo-c8 ~]# gpasswd -d wang admins
Removing user wang from group admins
[root@demo-c8 ~]# groups wang
wang : wang
[root@demo-c8 ~]# id wang
uid=1000(wang) gid=1000(wang) groups=1000(wang)
[root@demo-c8 ~]# getent group admins
admins:x:1002:
3.12 临时切换主组
newgrp命令可以临时切换主组, 如果用户本身不属于此组, 则需要组密码
基本组和附加组使用场景
临时切换基本组, 这样同一个账户可以创建属组不同的文件. 先切换到一个主组1, 这样该用户创建的文件的属主是自己, 属组是临时切换的主组1. 创建完毕, 执行exit, 退回到默认状态, 这样再创建的文件, 属主是自己, 属组也是自己本身的主组了
格式:
newgrp [-] [group]
如果使用[-]选项, 可以初始化用户环境
# 给root组添加密码
[root@demo-c8 ~]# gpasswd root
Changing the password for group root
New Password: 000000
Re-enter new password: 000000
# 验证组密码被创建
[root@demo-c8 ~]# getent gshadow root
root:$6$KCTQwDsFxse$o10OqHuwjlhYyCdL5W7GunQpQb6abRq.xUlajdCV2C99TeEVEVVt25fas3c8ynqRgnVAj370Gr79NXfJ95Zlh.::
# 登录wang账户, 执行newgrp root, 临时切换wang的主组为root
[root@demo-c8 ~]# id wang # wang的主组是wang
uid=1000(wang) gid=1000(wang) groups=1000(wang)
[root@demo-c8 ~]# su - wang
[wang@demo-c8 ~]$ newgrp root
Password:
[wang@demo-c8 ~]$ id
uid=1000(wang) gid=0(root) groups=0(root),1000(wang)
[wang@demo-c8 ~]$ touch wang1.txt
[wang@demo-c8 ~]$ ll
-rw-r--r--. 1 wang root 0 Aug 20 23:46 wang1.txt
# 执行newgrp切换主组后, 需要执行exit退出, 退出后, 主组信息就回到默认的主组了
[wang@demo-c8 ~]$ exit
exit
[wang@demo-c8 ~]$ id
uid=1000(wang) gid=1000(wang) groups=1000(wang)
[wang@demo-c8 ~]$ touch wang2.txt
[wang@demo-c8 ~]$ ll wang2.txt -d
-rw-rw-r--. 1 wang wang 0 Aug 20 23:47 wang2.txt
3.13 更改和查看组成员
groupmems可以管理附加组的成员关系
格式:
groupmems [options] [action]
常见选项:
-g 组名 # 指定管理的组名
-a 用户名 # 配合-g 组名, 将用户添加到该组, 作为附加组
-d 用户名 # 配合-g 组名, 将用户从该附加组中删除
-p 组名 # 从组中清除所有成员
-l 组名 # 配合-g 组名, 显示组成员列表
groups命令可查看用户组关系
格式:
# 查看用户所属组列表
groups [options] [username]
[wang@demo-c8 ~]$ groups wang
wang : wang
范例:
[root@demo-c8 ~]# usermod -G admins -a wang
[root@demo-c8 ~]# groups wang
wang : wang admins
[root@demo-c8 ~]# id wang # 主组 # 附加组
uid=1000(wang) gid=1000(wang) groups=1000(wang),1002(admins)
# 查看该附加组的成员
[root@demo-c8 ~]# groupmems -g admins -l
wang
# 将root添加到admins组, 将其作为root的附加组
[root@demo-c8 ~]# groupmems -a root -g admins
[root@demo-c8 ~]# groups admins
groups: ‘admins’: no such user
[root@demo-c8 ~]# groupmems -g admins -l
wang root
# 将wang和root从附加组admins删除
[root@demo-c8 ~]# groupmems -g admins -d wang
[root@demo-c8 ~]# groupmems -g admins -d root
[root@demo-c8 ~]# groupmems -g admins -l
[root@demo-c8 ~]# id wang
uid=1000(wang) gid=1000(wang) groups=1000(wang)
[root@demo-c8 ~]# id root
uid=0(root) gid=0(root) groups=0(root)
# 情况admins附加组所有成员信息
[root@demo-c8 ~]# groupmems -g admins -p
3.14 练习
创建用户gentoo, 附加组为bin和root, 默认shell为/bin/csh, 注释信息为"Gentoo Distribution"
创建下面的用户, 组和成员关系
名字为webs的组
用户nginx, 使用webs作为附加组
用户varnish, 使用webs作为附加组
用户mysql, 不可交互式登录系统, 且不是webs的成员, nginx, varnish, mysql密码都是000000
文件权限管理
4.1 文件所有者和属组属性操作
4.1.1 设置文件的所有者chown
chown
命令可以修改文件的属主, 也可以修改文件属组
格式:
chown [OPTION]... [OWNER][:[GROUP]] FILE...
chown [OPTION]... --reference=RFILE FILE...
用法说明:
OWNER # 只修改所有者
OWNER:GROUP # 同时修改所有者和属组
:GROUP # 只修改属组, 冒号也可用.替换
--reference=RFILE # 参考指定的属性, 来修改, 也就是按照RFILE文件的属主和属组来修改其他的文件的属主和属组
-R # 递归修改, 非常危险!
范例:
# 准备测试文件
[root@demo-c8 ~]# cd /data
[root@demo-c8 data]# cp /etc/fstab f1.txt
[root@demo-c8 data]# ll
total 4
-rw-r--r--. 1 root root 709 Aug 21 20:18 f1.txt
# 修改f1.txt的属主为wang账号
[root@demo-c8 data]# chown wang f1.txt
[root@demo-c8 data]# ll
total 4
-rw-r--r--. 1 wang root 709 Aug 21 20:18 f1.txt
# 修改f1.txt的属组为admins
[root@demo-c8 data]# groupadd -g 1002 admins
[root@demo-c8 data]# getent group admins
admins:x:1002:
[root@demo-c8 data]# chown :admins f1.txt
[root@demo-c8 data]# ll
total 4
-rw-r--r--. 1 wang admins 709 Aug 21 20:18 f1.tx
# 修改f1.txt的属主为root, 修改属组为bin
[root@demo-c8 data]# chown root.bin f1.txt
[root@demo-c8 data]# ll
total 4
-rw-r--r--. 1 root bin 709 Aug 21 20:18 f1.txt
# 修改f1.txt的属主为wang, 修改属组为admins
[root@demo-c8 data]# chown wang:admins f1.txt
[root@demo-c8 data]# ll
total 4
-rw-r--r--. 1 wang admins 709 Aug 21 20:18 f1.txt
# 根据f1.txt的属主和属组, 修改f2.txt的属主和属组
[root@demo-c8 data]# cp /etc/fstab f2.txt
[root@demo-c8 data]# ll
total 8
-rw-r--r--. 1 wang admins 709 Aug 21 20:18 f1.txt
-rw-r--r--. 1 root root 709 Aug 21 20:26 f2.txt
[root@demo-c8 data]# chown --reference=f1.txt f2.txt
[root@demo-c8 data]# ll
total 8
-rw-r--r--. 1 wang admins 709 Aug 21 20:18 f1.txt
-rw-r--r--. 1 wang admins 709 Aug 21 20:26 f2.txt
- chown -R, 递归修改目录, 以目录内所有文件的所有者和所属组
递归修改会修改目录本身权限, 目录内的文件和子目录权限, 子目录内的文件和子子目录权限...
[15:33:47 root@centos8-3 ~]#cp -r /boot /data/prac
[16:28:26 root@centos8-3 ~]#cd /data/prac
[16:28:29 root@centos8-3 /data/prac]#ls
boot
[16:28:29 root@centos8-3 /data/prac]#ll -d boot/
dr-xr-xr-x 6 root root 4096 Aug 20 16:28 boot/
[16:28:34 root@centos8-3 /data/prac]#chown -R david:g1 boot
[16:28:46 root@centos8-3 /data/prac]#ll -d boot/
dr-xr-xr-x 6 david g1 4096 Aug 20 16:28 boot/
[16:28:55 root@centos8-3 /data/prac]#ll boot/
total 129432
-rw-r--r-- 1 david g1 187648 Aug 20 16:28 config-4.18.0-193.el8.x86_64
drwxr-xr-x 3 david g1 17 Aug 20 16:28 efi
drwx------ 4 david g1 83 Aug 20 16:28 grub2
-rw------- 1 david g1 65603976 Aug 20 16:28 initramfs-0-rescue-f072eccf217a4374b5b44dc4461b3c54.img
-rw------- 1 david g1 27486526 Aug 20 16:28 initramfs-4.18.0-193.el8.x86_64.img
-rw------- 1 david g1 17507504 Aug 20 16:28 initramfs-4.18.0-193.el8.x86_64kdump.img
drwxr-xr-x 3 david g1 21 Aug 20 16:28 loader
drwx------ 2 david g1 6 Aug 20 16:28 lost+found
-rw------- 1 david g1 3909996 Aug 20 16:28 System.map-4.18.0-193.el8.x86_64
-rwxr-xr-x 1 david g1 8913656 Aug 20 16:28 vmlinuz-0-rescue-f072eccf217a4374b5b44dc4461b3c54
-rwxr-xr-x 1 david g1 8913656 Aug 20 16:28 vmlinuz-4.18.0-193.el8.x86_64
chown -R是及其危险的命令, 很容易失误把整个根/目录全部递归修改了
范例: / 和boot中间加了个空格, 直接把整个根目录及其内部所有内容的所有者和所属组全改了
chown -R g1:g2 / boot
4.1.2 设置文件的属组信息chgrp
chgrp
命令只可以修改文件的属组
格式:
chgrp [OPTION]... GROUP FILE...
chgrp [OPTION]... --reference=RFILE FILE...
-R递归
范例:
[root@demo-c8 data]# chgrp bin f1.txt
[root@demo-c8 data]# ll
total 12
-rw-r--r--. 1 wang bin 709 Aug 21 20:18 f1.txt
4.2 文件权限
4.2.1 文件权限说明
文件的权限主要针对三类对象进行定义
owner 属主 u
group 属组 g
other 其他 o
注意: 用户的最终权限, 是从左向右进行顺序匹配, 即, 所有者, 所属组, 其他人, 一旦匹配到相应权限, 那么立即生效, 不再向右查看其权限
- 是不是文件所有者
- 是不是文件所属组的成员, id命令查看, 不管是基本组还是附加组, 只要是该组成员即可
- 都不是那就是其他用户
每个文件,针对每类访问者都定义了三种权限
r readable 可读
w writable 可写
x excutable 可执行
rwx读写执行, 对于文件和目录的含义是不同的
对于文件:
r: 可使用文件查看类工具,比如:cat,可以查看文件内容
w: 可修改其内容, vim编辑, echo重定向
x: 可以把此文件提请内核启动为一个进程,即可以执行(运行)此文件(此文件的内容必须是可执行的, 比如脚本或者编译好的命令. 即使是root账户, 如果没有文件的x权限, 也是无法执行文件的
对于目录:
r: 可以使用ls
查看此目录中文件列表, 并且需要对目录有x
权限, 如果没有x
权限, 虽然也能看见文件列表, 但会有以下报错
# /root目录默认权限是550, 其他用户没有读写执行权限
[root@demo-c8 ~]# ll -d /root
dr-xr-x---. 15 root root 4096 Aug 21 20:18 /root
# 通过root账号, 给/root目录, 添加其他用户可读的权限
[root@demo-c8 ~]# chmod o+r /root -R
[root@demo-c8 ~]# ll -d /root
dr-xr-xr--. 15 root root 4096 Aug 21 20:18 /root
# 切换到wang账号, 执行ls /root
[root@demo-c8 ~]# su - wang
[wang@demo-c8 ~]$ ls /root
ls: cannot access '/root/anaconda-ks.cfg': Permission denied
ls: cannot access '/root/initial-setup-ks.cfg': Permission denied
ls: cannot access '/root/Desktop': Permission denied
ls: cannot access '/root/Downloads': Permission denied
ls: cannot access '/root/Templates': Permission denied
ls: cannot access '/root/Public': Permission denied
ls: cannot access '/root/Documents': Permission denied
ls: cannot access '/root/Music': Permission denied
ls: cannot access '/root/Pictures': Permission denied
ls: cannot access '/root/Videos': Permission denied
ls: cannot access '/root/f1.txt': Permission denied
# wang账号仍然可以查看/root目录内的文件列表, 但是会有Permission denied报错
anaconda-ks.cfg Desktop Documents Downloads f1.txt initial-setup-ks.cfg Music Pictures Public Templates Videos
# 给其他用户添加x权限后, 再次查看/root目录就不会报错了
[root@demo-c8 ~]# chmod o+x /root -R
[root@demo-c8 ~]# su - wang
[wang@demo-c8 ~]$ ls /root
anaconda-ks.cfg Desktop Documents Downloads f1.txt initial-setup-ks.cfg Music Pictures Public Templates Videos
w: 可在此目录中创建文件,也可删除此目录中的文件,或者改名, 删除和修改文件名的权限和此被删除或修改的文件的本身rwx权限无关. 因为文件名属于目录的数据内容, 一个目录的数据内容包含文件名/目录名, 以及对应的inode编号
x: 可以cd
进入此目录,可以使用ls -l
查看此目录中的文件和目录的元数据(须配合r权限),x属于目录的可访问的最小权限, 也就是只给用户某个目录x权限, 那么该用户只能进入到该目录,但是什么也不能干, 无法ls查看目录里内容, 无法创建删除修改文件
[root@demo-c8 ~]# ll -d /root
dr-xr-xr-x. 15 root root 4096 Aug 21 20:18 /root
[root@demo-c8 ~]# chmod o-r -R /root
[root@demo-c8 ~]# ll -d /root
dr-xr-x--x. 15 root root 4096 Aug 21 20:18 /root
[root@demo-c8 ~]# su - wang
[wang@demo-c8 ~]$ cd /root
[wang@demo-c8 root]$ ll
ls: cannot open directory '.': Permission denied
[wang@demo-c8 root]$ touch f1.txt
touch: cannot touch 'f1.txt': Permission denied
X : 只给目录x权限, 不给无执行权限的文件x权限, 用于-R递归修改权限, 比如
chmod -R a=rwx /data
: 如果这样执行, 那么data和data里面所有文件和目录(包含子文件和目录)就都有rwx权限
chmod -R a=rwX /data
: 如果这样执行, data和data里面的目录(包含子文件和目录),都赋予rwx权限, 但是文件不同, 如果文件本身就是x权限, 那么最终就rwx, 如果文件本身没有x权限, 那么就是rw权限, 不会赋予x权限
目录可以有x权限, 让用户能进来, 但是文件不能轻易给x权限, 因为要避免脚本或程序被恶意执行
练习: Linux中的目录和文件的权限区别? 分别说明读写和执行权限对于文件和目录的区别?
4.2.2 修改文件权限chmod
格式:
chmod [option]... MODE[,MODE]... FILE...
chmod [option]... OCTAL-MODE FILE...
# 参考RFILE文件的权限, 将FILE的权限修改为和RFILE一样的权限
说明:
MODE模式:
who: 针对哪类用户, u(所有者), g(所属组), o(其他用户), a(所有者, 所属组, 其他用户, 也就是任何人)
opt: +(添加权限), -(删除权限), =(直接指明权限)
permission: r, w, x
修改指定某类用户的所有权限:
u= g= o= ug= a= u= g=
修改指定某类用户的某个权限
u+ u- g+ g- o+ o- a+ a- + -
-R: 递归修改权限
范例:
chmod u+wx, g-r,o=rx FILE
chmod -R g+rwx /testdir
chmod 600 FILE
范例: 一旦匹配到对应的权限, 就不再向右匹配
# 准备测试文件
[root@demo-c8 ~]# cd /data
[root@demo-c8 data]# ls
[root@demo-c8 data]# cp /etc/fstab .
[root@demo-c8 data]# ll
total 4
-rw-r--r--. 1 root root 709 Aug 21 22:05 fstab
# 修改测试文件的所有者为wang账号, 文件的权限为u=, g=r, o=rw
[root@demo-c8 data]# chown wang fstab
[root@demo-c8 data]# chmod u=,g=r,o=rw fstab
[root@demo-c8 data]# ll
total 4
----r--rw-. 1 wang root 709 Aug 21 22:05 fstab
# 切换到wang账号进行验证
[wang@demo-c8 ~]$ cat /data/fstab
cat: /data/fstab: Permission denied
普通用户即使被加入到了root组, 也不一定就有和root用户一样的权限
范例: /etc/shadow文件
即使把普通用户加入到了root组, 也无法查看shadow文件, 因为加入到root组了, 就有了root组权限, 但是root组也没有权限查看该文件, 而root能查看是因为是管理员
[root@demo-c8 ~]# ll /etc/shadow
----------. 1 root root 1359 Aug 15 17:05 /etc/shadow
[root@demo-c8 ~]# usermod -G root wang
d[root@demo-c8 ~]# id wang
uid=1000(wang) gid=1000(wang) groups=1000(wang),0(root)
[root@demo-c8 ~]# su - wang
[wang@demo-c8 ~]$ cat /etc/shadow
cat: /etc/shadow: Permission denied
- 文件权限设置规范: 所有者权限最大; 所属组次之, other权限最小
文件的权限以及所有者所属组信息,谁能修改? 需要什么权限
- 普通用户不能修改文件权限和所有者以及所属组信息, 除非自己是文件所有者
- root用户可以随意修改文件的权限, 所有者和所属组信息
一个文件能不能被某个用户删除,需要看用户的什么权限?:对目录有写和执行权限
- 需要看用户对于文件所在目录的权限
- 文件名, 文件列表属于目录的数据部分, 目录的元数据并不包括文件名, 而是包含的文件inode编号.
- 因此, 删除文件, 就是修改目录的数据内容, 要对该目录有写和执行权限, 执行权限使得用户能进到目录, 写权限使得用户的在该目录内创建,修改,删除文件
- 如果用户对于一个目录, 只有w权限没有x权限, 也无法删除文件, 用户做修改, 必须能进去到目录, 因此, 想删除某个文件, 那么用户必须对该文件所在目录拥有wx权限, r无所谓, 删除文件不需要查看文件列表
ls
一个目录结构需要对目录有rx
权限
如果没有r权限, 也可以ls
但是会报错, 没有r
权限, 如果能记住文件名, 也能cat该文件, 只要对文件有r
权限即可. 因为x决定了用户是否能进到目录, 而r决定用户能否查看文件内容, 如果记住了文件路径, 那就不用先进到目录再查看文件内容了
删除文件的最小权限: 对所在目录有wx权限
无需r权限, 但是没有r权限, 删除文件时,如果不进去到目录里, 使用绝对路径是无法自动补齐文件名的, 因此想要对一个目录里的内容能自动补齐, 就要对该目录有r权限, 没有r权限, 不能自动补齐, 也无法ls查看文件列表
范例:
[17:16:16 root@centos8-3 ~]#cd /data
[17:19:28 root@centos8-3 /data]#ls
abc.txt prac scripts testing_scripts
[17:19:29 root@centos8-3 /data]#ll -d /data
drw-r----x. 5 root root 71 Aug 20 16:56 /data
# 给/data目录, 其他用户rx权限
[17:19:34 root@centos8-3 /data]#chmod o+w /data
[17:19:44 root@centos8-3 /data]#ll -d /data
drw-r---wx. 5 root root 71 Aug 20 16:56 /data
# 切换到david用户
[17:19:50 root@centos8-3 /data]#su - david
Last login: Thu Aug 20 17:14:33 AEST 2020 on pts/0
# 因为david属于其他用户, 所以有wx权限, 可以删除/data目录内的文件
[17:19:55 david@centos8-3 ~]$rm -rf /data/abc.txt
# 但是因为david是其他用户, 对于/data目录没有r权限, 所以无法执行ls查看/data的目录列表
[17:20:09 david@centos8-3 ~]$ll /data/
ls: cannot open directory '/data/': Permission denied
# david有x权限, 可以进入/data目录
[17:20:15 david@centos8-3 ~]$cd /data
# 无法查看目录列表
[17:20:21 david@centos8-3 /data]$ll
ls: cannot open directory '.': Permission denied
[17:20:22 david@centos8-3 /data]$su -
Password:
Last login: Thu Aug 20 17:16:16 AEST 2020 on pts/0
[17:20:26 root@centos8-3 ~]#ls /data
prac scripts testing_scripts
练习: 执行cp /etc/issue /data/dir/ 所需要的最小权限?
/bin/ 需要x权限
/bin/cp 需要x权限
/etc/ 需要x权限
/etc/issue 需要r权限
/data/ 需要x权限
/data/dir/ 需要w,x权限
-
/bin/cp
: 一个命令程序, 本身也是文件, 想要被执行, 执行者需要x权限, 没有x权限的用户是无法运行该命令的, 并且, 也需要对命令所在的目录有x
权限
[17:30:40 root@centos8-3 /data]#ll /bin/cp
-rwxr-xr-x. 1 root root 333128 Apr 10 04:53 /bin/cp
[17:30:51 root@centos8-3 /data]#chmod o-x /bin/cp
[17:31:02 root@centos8-3 /data]#su - david
Last login: Thu Aug 20 17:19:55 AEST 2020 on pts/0
[17:31:04 david@centos8-3 ~]$touch f1.txt
[17:31:10 david@centos8-3 ~]$cp f1.txt /tmp
-bash: /usr/bin/cp: Permission denied
/etc: 对于/etc/目录, 需要x权限, 能进到目录才能操作文件
/etc/issue: 复制一个文件, 需要对该文件有r权限,并且对文件所在目录至少有x权限, 因为要进入所在目录
[17:34:33 david@centos8-3 ~]$ll
total 0
-rw-r----- 1 david g1 0 Aug 20 17:31 f1.txt
-rw-r----- 1 david g1 0 Aug 20 17:34 f2.txt
-rw-rwxr-- 1 david g1 0 Aug 20 16:49 david.txt
[17:34:35 david@centos8-3 ~]$chmod u-r f1.txt
[17:34:44 david@centos8-3 ~]$cp f1.txt /tmp
cp: cannot open 'f1.txt' for reading: Permission denied
- 执行文件, 需要对目录有x, 如果是普通脚本文件, 需要对文件有rx权限, 如果是二进制程序文件, 有x权限即可
[wang@demo-c8 ~]$ touch hello.sh
[wang@demo-c8 ~]$ ll
total 0
-rw-rw-r--. 1 wang wang 0 Aug 21 22:52 hello.sh
[wang@demo-c8 ~]$ chmod u=x hello.sh
[wang@demo-c8 ~]$ ll
total 0
---xrw-r--. 1 wang wang 0 Aug 21 22:52 hello.sh
[wang@demo-c8 ~]$ bash hello.sh
bash: hello.sh: Permission denied
[wang@demo-c8 ~]$ chmod u=rx hello.sh
[wang@demo-c8 ~]$ bash hello.sh
- 复制一个文件.需要对该文件有r权限
[wang@demo-c8 ~]$ ll
total 0
-r-xrw-r--. 1 wang wang 0 Aug 21 22:52 hello.sh
[wang@demo-c8 ~]$ chmod u-x hello.sh
[wang@demo-c8 ~]$ cp hello.sh hello.sh.bak
[wang@demo-c8 ~]$ ll
total 0
-r--rw-r--. 1 wang wang 0 Aug 21 22:52 hello.sh
-r--rw-r--. 1 wang wang 0 Aug 21 22:53 hello.sh.bak
想对文件操作, 不管是读,写还是执行,都需要能先进入到文件所在的目录, 也就是需要对文件所在的目录有x权限
读一个文件: 需要对该文件有r权限, 对文件所在的目录有x权限,
创建删除或者改名: 和文件的权限无关, 看的是用户对文件所在目录的权限, 创建删除或改名, 需要对目录最小的权限是wx, 能不能读目录的文件列表无所谓, 可以手写路径文件名, 不自动补齐
执行文件, 需要对目录有x, 如果是普通脚本文件, 需要对文件有rx权限, 如果是二进制程序文件, 有x权限即可
想要对一个目录里的内容能自动补齐, 就要对该目录有r权限, 没有r权限, 不能自动补齐, 也无法
ls
查看文件列表. 没有目录r权限, 想要操作目录内的文件, 就只能记住文件名, 然后手写全路径
[22:26:23 wang@c7node1 ~]$ll
total 0
---xr--r-- 1 wang wang 0 Oct 4 22:26 test.sh
[22:26:38 wang@c7node1 ~]$./test.sh
bash: ./test.sh: Permission denied
[22:26:49 wang@c7node1 ~]$chmod 544 test.sh
[22:27:08 wang@c7node1 ~]$ll
total 0
-r-xr--r-- 1 wang wang 0 Oct 4 22:26 test.sh
[22:27:11 wang@c7node1 ~]$./test.sh
[22:27:13 wang@c7node1 ~]$
即使是root账户, 没有
x
权限也无法执行文件如果把
chmod
文件的x
权限取消了, 那么root也不能执行chmod
解决方案:
可以从别处scp复制一份过来, 要求版本一样, 然后通过cp -a命令把chmod执行命令, 复制到/bin目录下
或者使用救援模式
或者通过acl
- 工作时文件权限设置600比较多, 给所有者读写权限, 所属组和其他人不给任何权限
4.3 新建文件和目录的默认权限
umask的值可以用来决定新建文件和目录的默认权限
umask的值不会受到chmod
命令的影响, 比如给一个目录设置了777的递归权限, 之后无论在该目录里创建文件还是目录, 都还是遵循umask的规则
实现方式:
新建文件默认权限: 666-umask, 如果所得结果某位存在执行(奇数)权限, 则将其权限+1, 偶数不变
权限位xxx xxx xxx, r=4, w=2,x=1. 一旦某一组xxx出现了奇数, 就说明这组肯定是有x权限的, LInux安全策略不允许新建的文件默认有x权限, root也不行, 读和写没有x带来的风险大
新建目录默认权限: 777-umask, 没有奇偶限制
非特权用户umask默认是002
[21:16:56 linux@centos8-3 ~]$umask
0002 #第一位的0表示8进制, 可以忽略
- root的umask默认是022
[21:09:49 root@centos8-3 ~]#umask
0022 #第一位的0表示8进制, 可以忽略
总结:
对于root账户,新建文件的默认权限就是666-022=644, rw-r--r--
对于root账户,新建目录的默认权限就是777-022=755, rwx-r-x-r-x
对于普通账户, 新建文件的默认权限就是666-002=664, rw-rw-r
对于普通账户,新建目录的默认权限就是777-002=775,rwx-rwxr-x
查看umask:
# umask
[root@demo-c8 ~]# umask
0022
# 模式方式显示
umask -S
[root@demo-c8 ~]# umask -S
u=rwx,g=rx,o=rx
# 输出可被调用
umask -p
[root@demo-c8 ~]# umask -p
umask 0022
修改umask:
范例:
umask 022
umask u=rw,g=r,o=
- 临时修改,只在当前终端,当前进程有效: 直接在命令行执行, umask xxx, 第一位可以省略
[21:17:43 root@centos8-3 ~]#umask 223 # 666-223=443, 新建文件, 其他人的x位是奇数,默认加1变成偶数, 所以是444, r--r--r--
[21:22:12 root@centos8-3 ~]#umask
0223
[21:22:07 root@centos8-3 ~]#touch a.txt
[21:22:11 root@centos8-3 ~]#ll
total 4
-r--r--r-- 1 root root 0 Aug 20 21:22 a.txt
- 持久保存, 写到每个用户家目录的.bashrc文件, 或者保存到/etc/bashrc全局生效
[21:25:28 root@centos8-3 ~]#vim .bashrc
# .bashrc
# User specific aliases and functions
alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'
# Source global definitions
if [ -f /etc/bashrc ]; then
. /etc/bashrc
fi
umask 033
# . or source 使.bashrc文件生效
[21:30:35 root@centos8-3 ~]#. .bashrc
[21:30:42 root@centos8-3 ~]#touch d.txt
[21:30:46 root@centos8-3 ~]#ll -d d.txt
-rw-r--r-- 1 root root 0 Aug 20 21:30 d.txt
[21:30:48 root@centos8-3 ~]#666-033=633>644
#directory
[21:30:48 root@centos8-3 ~]#mkdir a
[21:31:32 root@centos8-3 ~]#ll -d a
drwxr--r-- 2 root root 6 Aug 20 21:31 a
[21:31:35 root@centos8-3 ~]#777-033=744
- 在不影响当前bash进程的umask情况下, 修改文件的默认umask, 并且创建文件和目录
[root@demo-c8 ~]# umask
0022
[root@demo-c8 ~]# ( umask 666; touch f2.txt ) # (cmd1; cmd2; cmd3...)会开启子进程, 执行括号内的命令, 子进程的bash环境不影响父进程
[root@demo-c8 ~]# umask
0022
[root@demo-c8 ~]# ll f2.txt
----------. 1 root root 0 Aug 21 23:26 f2.txt
练习:
- 当用户docker对/testdir目录物质性权限时, 意味着无法做哪些操作?
- 当用户mongodb对/testdir目录无读权限时, 意味着无法做哪些操作?
- 当用户redis对/testdir目录无写权限时, 该目录下的只读文件file1.txt是否可以被修改和删除?
- 当用户zabbix对/testdir目录有写和执行权限时, 该目录下的只读文件file1.txt是否可以被修改和删除?
- 复制/etc/fstab文件到/var/tmp目录下, 设置文件所有者为tomcat读写权限, 所属组为apps, 并且有读写权限, 其他人无权限
- 误删除了用户git的家目录, 请重建并恢复该用户家目录及相应的权限属性
练习:
在/testdir/dir里创建的新文件自动属于webs组, 组apps的成员如: tomcat能对这些文件有读写权限, 组dbs的成员如: mysql只能对新文件有读权限, 其他用户(不属于webs, appd, dbs)不能访问这个文件夹
误将/bin/chmod文件的执行权限删除, 如何恢复?
#1. 确定操作系统发行版本, 和chmod命令的版本
#2. 找一个相同版本的系统, 把chmod命令文件通过scp复制到删除了chmod命令的系统
# scp不会丢失属性
#3. 将复制来的chmod命令, cp -a到/bin目录下, 测试即可
4.4 Linux文件系统上的特殊权限
前面介绍了三种常见的权限: r,w,x, 还有三种特殊权限: SUID, SGID, Sticky
4.4.1 特殊权限SUID
前提: 一个进程有其属主和属组; 一个文件也有属主和属组
- 任何一个可执行程序文件能不能启动为进程, 取决于发起者对程序文件是否拥有执行权限
- 启动为进程之后, 其进程的属主为发起者, 进程的属组为发起者所属的组
- 进程访问文件时的权限, 取决于进程的发起者
(a)进程的发起者, 是文件的属主, 则应用文件属主权限
(b)进程的发起者, 属于文件属组, 则应用文件属组权限
(c)进程的发起者, 属于其他用户, 则应用文件Other权限
二进制的可执行文件(程序)上设置SUID权限功能:
- 任何一个可执行程序文件能不能启动为进程: 取决于发起者对程序文件是否拥有执行权限
- 启动为进程后, 其进程的属主为原程序文件的属主
- SUID只对二进制可执行程序有效
- SUID设置在目录上无意义, SUID作用在一个二进制程序的属主的执行权限位上
- 给一个二进制可执行程序文件添加了SUID功能后, 那么任何对该程序有执行权限的用户, 在执行该程序去操作文件时, 都会临时变成该二进制程序的属主身份
- 当用户临时变成该二进制程序的属主身份后, 是否能操作相应的文件, 就看这个属主身份的权限了
SUID权限设定:
chmod u+s FILE... # 添加SUID
chmod 4644 FILE # 添加SUID, 特殊权限位写在权限的第一位, 后三位为正常的文件权限
chmod u-s FILE... # 删除SUID
范例:
[root@demo-c8 ~]# ll /usr/bin/passwd
-rwsr-xr-x. 1 root root 33600 Apr 7 2020 /usr/bin/passwd
passwd
命令可以被任何用户使用去重置密码, 这是因为/usr/bin/passwd
被添加了SUID权限, 而默认情况下, 属主, 属组和其他用户对于该文件都有执行权限. 所以, 当任何用户执行该程序命令时, 都会临时变成root账号.
修改密码, 最终修改的是/etc/shadow文件, 这个文件默认只有root用户可以访问, 修改, 但是因为passwd程序有SUID权限, 因此, 任何用户运行了此命令后, 都会变成root, 也就对/etc/shadow文件有了权限, 也就可以修改密码了
SUID权限不要随便设置: 比如cat命令是一个二进制可执行程序. 任何用户对于cat命令都是有执行权限的, 一旦给/bin/cat添加了SUID, 那么所有用户在执行cat命令时, 都会继承root用户权限, 也就可以查看任何文件了.
范例:
[root@demo-c8 data]# ll /bin/cat
-rwxr-xr-x. 1 root root 87496 Apr 10 2020 /bin/cat
# 给/bin/cat添加SUID
[root@demo-c8 data]# chmod u+s /bin/cat
[root@demo-c8 data]# ll /bin/cat
-rwsr-xr-x. 1 root root 87496 Apr 10 2020 /bin/cat
# 切换到wang账号, 验证其可以打开/etc/shadow文件
[root@demo-c8 data]# su - wang
[wang@demo-c8 ~]$ cat /etc/shadow
root:$6$YD64S7fSNEcHhV6s$cR6V/rj9Te2GdnE.WJQvlVup9cn8cSDsKaDHazCloevgmSvrswUYC9enlpI5CCVPRQZwA58VyUxvCpval6BaW0::0:99999:7:::
bin:*:18358:0:99999:7:::
daemon:*:18358:0:99999:7:::
adm:*:18358:0:99999:7:::
lp:*:18358:0:99999:7:::
sync:*:18358:0:99999:7:::
shutdown:*:18358:0:99999:7:::
halt:*:18358:0:99999:7:::
mail:*:18358:0:99999:7:::
...
# 切换回root, 取消/bin/cat的SUID
root@demo-c8 data]# chmod u-s /bin/cat
[root@demo-c8 data]# ll /bin/cat
-rwxr-xr-x. 1 root root 87496 Apr 10 2020 /bin/cat
4.4.2 特殊权限SGID
二进制的可执行文件上SGID权限功能:
- 任何一个可执行程序文件能不能启动为进程: 取决于发起者对程序文件是否拥有执行权限
- 启动为进程之后, 其进程的属组为原程序文件的属组
SGID权限设定:
chmod g+s FILE...
chmod 2xxx FILE
chmod g-s FILE...
目录上的SGID权限功能:
默认情况下, 用户创建的文件, 其属组为此用户所属的主组
, 一旦某目录被设定了SGID, 则对此目录有写权限
的用户, 也就是能在此目录创建/删除/修改文件名的用户, 在此目录中创建的文件所属的组为此目录本身的属组
, 而不是用户自己的主组了, 通常用于创建一个协作目录
范例:
# 创建测试目录, 并且设置权限为777, 这样任何用户都可以在该目录, 创建文件, 删除文件, 修改文件名
[root@demo-c8 data]# mkdir dir
[root@demo-c8 data]# ll
total 0
drwxr-xr-x. 2 root root 6 Aug 22 13:22 dir
[root@demo-c8 data]# chmod 777 dir
[root@demo-c8 data]# ll
total 0
drwxrwxrwx. 2 root root 6 Aug 22 13:22 dir
# 默认情况, 任何用户在该目录创建的文件的属组, 都是该用户的主组
[root@demo-c8 data]# cd dir
[root@demo-c8 dir]# touch root.txt
[root@demo-c8 dir]# ll
total 0
-rw-r--r--. 1 root root 0 Aug 22 13:23 root.txt # root创建的文件, 属组为root
[root@demo-c8 dir]# su - wang
# 想进入子目录, 必须对父目录也有x权限, 所以这里直接给/data目录777权限
[wang@demo-c8 ~]$ cd /data/dir
-bash: cd: /data/dir: Permission denied
[wang@demo-c8 ~]$ ll -d /data
drw----r--. 3 root root 17 Aug 22 13:22 /data
[wang@demo-c8 ~]$ su -
Password:
[root@demo-c8 ~]# chmod 777 /data
[root@demo-c8 ~]# su - wang
[wang@demo-c8 ~]$ cd /data/dir
[wang@demo-c8 dir]$ touch wang.txt
[wang@demo-c8 dir]$ ll
total 0
-rw-r--r--. 1 root root 0 Aug 22 13:23 root.txt
-rw-rw-r--. 1 wang wang 0 Aug 22 13:24 wang.txt # wang创建的文件属组为wang
# 给/data/dir目录加上SGID
[root@demo-c8 ~]# chmod 2777 /data/dir
[root@demo-c8 ~]# ll /data/dir -d
drwsrwsrwx. 2 root root 38 Aug 22 13:24 /data/dir
# 修改/data/dir目录的属组为bin, 这样任何人在dir目录创建的文件的属组就是bin
[root@demo-c8 dir]# chown .bin /data/dir
[root@demo-c8 dir]# ll -d /data/dir
drwsrwsrwx. 2 root bin 55 Aug 22 13:26 /data/dir
[root@demo-c8 dir]# touch root1.txt
[root@demo-c8 dir]# ll
total 0
-rw-r--r--. 1 root bin 0 Aug 22 13:34 root1.txt # root新建的文件的属组也是bin
-rw-r--r--. 1 root root 0 Aug 22 13:23 root.txt
-rw-rw-r--. 1 wang wang 0 Aug 22 13:24 wang.txt
[root@demo-c8 dir]# su - wang
[wang@demo-c8 ~]$ cd /data/dir
[wang@demo-c8 dir]$ touch wang1.txt
[wang@demo-c8 dir]$ ll
total 0
-rw-r--r--. 1 root bin 0 Aug 22 13:34 root1.txt
-rw-r--r--. 1 root root 0 Aug 22 13:23 root.txt
-rw-rw-r--. 1 wang bin 0 Aug 22 13:35 wang1.txt # wang新建的文件的属组也是bin
-rw-rw-r--. 1 wang wang 0 Aug 22 13:24 wang.txt
针对目录的SGID, 一般用于多个用户对于一个目录的共同协作使用. 即使没有加-R递归, 设定了SGID的目录的子目录也会继承SGID的设置, 只要是在该目录或者子目录内创建的所有文件的属组, 都是该目录的属组
工作中一般很少需要手动设置这三种特殊权限
4.4.3 特殊权限Sticky位
当用户对目录具有写权限时, 用户可以删除目录内的任何文件, 无论被删除的文件的权限是什么, 属主或属组是什么
在目录设置Sticky位后, 那么只有目录内, 文件的所有者或者root, 可以删除该目录内文件
Sticky设置在文件上无意义
范例:
[root@demo-c8 ~]# ll -d /tmp
drwxrwxrwt. 20 root root 4096 Aug 22 11:57 /tmp
- 通过Sticky, 可以避免, 多个对同一个目录有wx权限的用户, 可以互相删除彼此的文件
假如a和b对/data/dir目录都有wx权限, 那么a和b就可以互相删除/data/dir目录中, 属主是彼此的任何文件
总结:
默认情况:
1. 一个二进制程序能不能被执行, 看的是命令发起者对于这个二进制程序文件是否有x权限
2. 如果有x权限, 那么用户就能执行这个程序
3. 至于执行了这个程序后, 能不能操作其他文件, 就要看这个用户对操作的文件是否有权限, 和执行的程序本身无关
# 使用了SUID后: SUID只能作用于二进制可执行程序
1. 二进制程序文件的属主执行位会显示为s/S, s表示属主原本就有x权限, S表示属主原本没有x权限
2. 任何对这个二进制程序文件有x权限的用户, 执行了这个命令后, 都会临时变成这个程序属主的身份
3. 对于要操作的文件来说, 此时就要看这个临时的属主身份, 对于该文件有什么权限了, 和原本的用户无关
# 使用了SGID: SGID即可作用在二进制可执行程序, 也可作用在目录上
#1. 作用在二进制可执行程序的效果类似SUID, 用户会临时被加入到该二进制程序的属组中.
#2. 当操作文件时, 就看这个用户本身是不是备操作文件的属主, 如果是的话, 直接使用原本的属主权限, 如果不是, 就看该用户被临时加到的组是不是这个被操作文件的属组, 如果是的话, 就行驶属组权限, 否则就用Other权限
#3. 当把SGID设置在目录上时
默认情况下, 用户创建的文件, 其属组为此用户所属的主组, 一旦某目录被设定了SGID, 则对此目录有写权限的用户, 也就是能在此目录创建/删除/修改文件名的用户, 在此目录中创建的文件所属的组为此目录本身的属组, 而不是用户自己的主组了, 通常用于创建一个协作目录
4.4.4 特殊权限数字法
SUID SGID STICKY
000 0
001 1
010 2
011 3
100 4
101 5
110 6
111 7
4 SUID
2 SGID
1 Sticky
范例:
chmod 4777 /bin/cat # 给cat命令添加SUID, 并且普通权限为777
权限位映射:
SUID: user, 占据属主的执行权限位
s: 属本身拥有x权限
S: 属主本身没有x权限
SGID: group, 占据属组的执行权限位
s: group本身拥有x权限
S: group本身没有x权限
Sticky: other, 占据other的执行权限位
t: other本身拥有x权限
T: other本身没有x权限
4.5 设定文件特殊属性
通过设置文件的特殊属性, 可以防止root用户误删除或者修改文件内容, 设置特殊权限
- 任何人都不能删除, 改名, 更改文件内容, 这个文件所属的文件夹及父目录也不能被删除, 即使是root用户也会被限制
chattr +i # 文件变成只读
- 只能追加内容, 不能删除, 改名, 即使是root也会被限制
chattr +a
- 显示文件特殊属性
lsattr
[root@demo-c8 dir3]# lsattr f1.txt
----i--------------- f1.txt
范例:
# 构建测试文件
[root@demo-c8 ~]# mkdir /data/dir1/dir2/dir3 -pv
mkdir: created directory '/data/dir1'
mkdir: created directory '/data/dir1/dir2'
mkdir: created directory '/data/dir1/dir2/dir3'
[root@demo-c8 ~]# cd /data/dir1/dir2/dir3
[root@demo-c8 dir3]# touch f1.txt
# 添加chattr +i
[root@demo-c8 dir3]# chattr +i f1.txt
[root@demo-c8 dir3]# lsattr f1.txt
----i--------------- f1.txt
[root@demo-c8 dir3]# rm -rf f1.txt # 文件不能删除
rm: cannot remove 'f1.txt': Operation not permitted
[root@demo-c8 dir3]# rm -rf /data # 父目录也不让删除
rm: cannot remove '/data/dir1/dir2/dir3/f1.txt': Operation not permitted
[root@demo-c8 dir3]# cat /dev/null > f1.txt # 不能修改
-bash: f1.txt: Operation not permitted
[root@demo-c8 dir3]# mv f1.txt f1.txt.bak # 不能改名
mv: cannot move 'f1.txt' to 'f1.txt.bak': Operation not permitted
4.6 访问控制列表
4.6.1 ACL权限功能
ACL: Access Control List, 实现灵活的权限管理
除了文件的所有者, 所属组和其他用户, ACL可以对更多的用户设置权限
比如: 想让wang账号对文件f1.txt没有任何权限, 而david账号对f1.txt拥有任何权限, 光靠传统的三类权限分组(属主, 属组, Other)是无法实现的, 所以此时需要用ACL做到精准控制
CentOS7以后, 默认创建的xfs和ext4文件系统具有ACL功能
CentOS7以前, 默认手动创建的ext4文件系统, 没有ACL功能, 需要手动增加
tune2fs -o acl /dev/sdb1
mount -o acl /dev/sdb1 /mnt/test
- ACL生效顺序: 所有者, 自定义用户(指的就是ACL权限), 所属组|自定义组, 其他人
4.6.2 ACL相关命令
setfacl 可以设置ACL权限, 对一个文件设置ACL, 只有文件的属主或者属组用户才有权限设置ACL
范例: 针对f1.txt, wang没有任何权限, david可以读写, 其他Other用户只能读
# wang账号权限设置
[root@demo-c8 data]# touch f1.txt
[root@demo-c8 data]# ll
total 0
-rw-r--r--. 1 root root 0 Aug 22 14:17 f1.txt
[root@demo-c8 data]# setfacl -m u:wang:0 f1.txt # u:wang:0 u表示针对哪个用户, wang是用户名, 0或者-都表示没有读写执行权限
[root@demo-c8 data]# ll
total 0
-rw-r--r--+ 1 root root 0 Aug 22 14:17 f1.txt # 添加了ACL权限的文件会在权限的最后一位多一个加号, 表示设置了ACL权限
[root@demo-c8 data]# getfacl f1.txt
# file: f1.txt
# owner: root
# group: root
user::rw- 属主权限为读写
user:wang:--- # 用户wang没有任何权限
group::r-- # 属组权限为读
mask::r--
other::r-- # 其他人的权限为读
# 切换到wang账号进行测试
[root@demo-c8 ~]# su - wang
[wang@demo-c8 ~]$ cd /data/
[wang@demo-c8 data]$ cat f1.txt
cat: f1.txt: Permission denied
[wang@demo-c8 data]$ touch f1.txt
touch: cannot touch 'f1.txt': Permission denied
[wang@demo-c8 data]$ echo 1 >> f1.txt
-bash: f1.txt: Permission denied
# david账号权限设置
[root@demo-c8 data]# useradd david
[root@demo-c8 data]# id david
uid=1001(david) gid=1001(david) groups=1001(david)
[root@demo-c8 data]# setfacl -m u:david:rw f1.txt
[root@demo-c8 data]# getfacl f1.txt
# file: f1.txt
# owner: root
# group: root
user::rw-
user:wang:---
user:david:rw-
group::r--
mask::rw-
other::r--
# 切换到david账号进行测试
[root@demo-c8 ~]# su - david
[david@demo-c8 ~]$ cd /data
[david@demo-c8 data]$ cat f1.txt
[david@demo-c8 data]$ echo 1 >> f1.txt
# 创建john作为其他用户
[root@demo-c8 data]# useradd john
[root@demo-c8 data]# id john
uid=1002(john) gid=1002(john) groups=1002(john)
[root@demo-c8 ~]# su - john
[john@demo-c8 ~]$ cd /data
[john@demo-c8 data]$ cat f1.txt # Other可读
1
[john@demo-c8 data]$ echo 11>> f1.txt # Other不可写
-bash: f1.txt: Permission denied
getfacl 可以查看设置的ACL权限
# 执行getfacl查看一个文件的ACL权限是不需要对该文件有任何权限的
[wang@demo-c8 data]$ getfacl f1.txt
# file: f1.txt
# owner: root
# group: root
user::rw-
user:wang:---
user:david:rw-
group::r--
mask::rw-
other::r--
- 针对组, 设置ACL权限
setfacl -m g:bin:rw f1.txt
当一个用户属于多个组时, 那么其ACL权限就是多个组的权限叠加后的权限
删除单个用户ACL
# 删除david用户的ACL
setfacl -x u:david f1.txt
- 清空文件的ACL
setfacl -b f1.txt
- 针对目录递归设置ACL
# wang账号对/data目录和子目录内的所有文件都有rwx权限
setfacl -R -u:wang:rwx /data
mask权限:
- mask只影响除了所有者和Other之外的人和组的最大权限, 也就是自定义ACL用户, 所属组和自定义组
- mask需要与用户/组的权限进行逻辑运算后, 才能变成有效的权限(Effective Permission)
- 自定义ACL用户, 所属组和自定义组的权限设置必须小于mask权限设定范围内才会生效, 所以mask就是个限高杆, 如果mask权限是rw, 那么自定义ACL用户, 所属组和自定义组的权限只能是r, w, 或者rw, 不能有x权限
一旦给文件添加了ACL权限, 那么针对文件的属组设置的权限, 就会变成mask的权限. 两者的权限值是实时相等的
设置了ACL后, 修改属组权限, 那么mask权限也会跟着被修改为同样的权限. 修改mask权限, 那么属组权限也会被修改为同样的权限
# 目前f1.txt有ACL权限, mask权限是rwx
[root@demo-c8 data]# ll f1.txt
-rw-rwxr--+ 1 root root 2 Aug 22 14:22 f1.txt
[root@demo-c8 data]# getfacl f1.txt
# file: f1.txt
# owner: root
# group: root
user::rw-
user:wang:rwx
user:david:rw-
group::r--
mask::rwx
other::r--
# 修改f1.txt的属组权限为rw
[root@demo-c8 data]# chmod g=rw f1.txt
[root@demo-c8 data]# ll f1.txt
-rw-rw-r--+ 1 root root 2 Aug 22 14:22 f1.txt
# 再次查看f1.txt的ACL
[root@demo-c8 data]# getfacl f1.txt
# file: f1.txt
# owner: root
# group: root
user::rw-
user:wang:rwx #effective:rw- # 用户wang的rwx权限, 也变成了只有rw生效. 因为wang是自定义用户, 所以其生效权限是受到mask控制
user:david:rw-
group::r--
mask::rw- # mask变成了rw权限
other::r--
设置mask权限:
# 目前f1.txt的mask权限是rw
[root@demo-c8 data]# getfacl f1.txt
# file: f1.txt
# owner: root
# group: root
user::rw-
user:wang:rwx #effective:rw-
user:david:rw-
group::r--
mask::rw-
other::r--
# 将mask修改为rwx
oot@demo-c8 data]# setfacl -m mask::rwx f1.txt
[root@demo-c8 data]# getfacl f1.txt
# file: f1.txt
# owner: root
# group: root
user::rw-
user:wang:rwx # 自定义用户wang的rwx权限都可以生效
user:david:rw-
group::r--
mask::rwx # mask变成rwx, 那么自定义用户, 属组和自定义组的权限限高就变成了rwx
other::r--
- 针对属组或自定义组设置ACL
setfacl -m g:daemon:rw f1.txt
- mask的权限和自定义用户, 自定义组和属组的权限是相互作用的, 设置了mask后, 自定义用户, 自定义组和属组原有的权限, 需要按照mask限高杆调低. 而如果给自定义用户, 组和属组设置了高于限高杆的权限后, 那么mask的权限也会跟着调整, 来满足自定义用户, 组和属组的权限需求
--set选项会把原有的ACL项都删除, 用新的替代, 需要注意的是一定要包含UGO的设置, 不能像-m一样, 只是添加ACL就可以
范例:
setfacl --set u::rw,u:wang:rw,g::r,o::- file1
4.6.3 备份和还原ACL
主要的文件操作命令如cp和mv都支持ACL, 只是cp命令需要加上-p参数. 但是tar等常见的备份工具是不会保留目录和文件的ACL信息的
范例:
# 备份ACL
[root@demo-c8 data]# getfacl f1.txt
# file: f1.txt
# owner: root
# group: root
user::rw-
user:wang:rwx
user:david:rw-
group::r--
mask::rwx
other::r--
[root@demo-c8 data]# getfacl -R f1.txt > f1_acl.bak
[root@demo-c8 data]# cat f1_acl.bak
# file: f1.txt
# owner: root
# group: root
user::rw-
user:wang:rwx
user:david:rw-
group::r--
mask::rwx
other::r--
# 清空ACL权限
[root@demo-c8 data]# setfacl -b f1.txt
[root@demo-c8 data]# getfacl f1.txt
# file: f1.txt
# owner: root
# group: root
user::rw-
group::r--
other::r--
# 还原ACL权限
[root@demo-c8 data]# setfacl -R --set-file=f1_acl.bak f1.txt
[root@demo-c8 data]# getfacl f1.txt
# file: f1.txt
# owner: root
# group: root
user::rw-
user:wang:rwx
user:david:rw-
group::r--
mask::rwx
other::r--