内容概述

  • Linux的安全模型
  • 用户和组相关文件
  • 用户和组管理命令
  • 理解并设置文件权限
  • 默认权限
  • 特殊权限
  • 文件访问控制列表

    1 Linux 安全模型

    AAA认证资源分派:

  • Authentication : 认证,验证用户身份

  • Authorization :授权,不同的用户设置不同权限
  • Accouting | Audition :审计,计费

当用户登录时,系统会自动分配令牌 token,包括用户标识和组成员等等信息

1.1 用户

Linux 中每个用户是通过 User ID(UID)来唯一标识的。

  • 管理员:root,0
  • 普通用户:1-60000,自动分配

    • 系统用户:1-499(CentOS 6以前),1-999(CentOS 7以后)
    • 对守护进程获取资源进行权限分配
    • 登录用户:500+(CentOS 6以前),1000+(CentOS 7以后)
    • 给用户进行交互式登录使用

      1.2 用户组

      Linux 中可以将一个或者多个用户加入用户组中,用户组是通过Group ID(GID)来唯一标识的。
  • 管理员组:root,0

  • 普通组:

    • 系统组:1-499(CentOS 6以前),1-999(CentOS 7以后)
    • 对守护进程获取资源进行权限分配
    • 普通组:500+(CentOS 6以前),1000+(CentOS 7以后)
    • 给用户使用

      1.3 用户和组的关系

  • 用户的主要组(Primary Group):用户必须属于一个并且只有一个主组,默认创建用户时会自动创建和用户名同名的组,做为用户的主要组,由于此组中只有一个用户,又称为私有组。

  • 用户的附加组(Supplementary Group):一个用户可以属于零个或者多个辅助组,可有可无,可以有多个
  • 用户相当于员工,组相当于职位。Linux 默认情况:当创建新用户时,会自动创建一个和之同名的组,作为主组;Windows 默认情况:当创建新用户时,会自动添加到 User & Guest 组里。

    以超级管理员的身份运行CMD

    net user test 123 /add net user

    \LAPTOP-72CQ9GUB 的用户帐户

    SUNLOGIN_USER Administrator DefaultAccount Guest test WDAGUtilityAccount 命令成功完成。 net user test /del

范例:

  1. $ id postfix
  2. uid=89(postfix) gid=89(postfix) groups=89(postfix),12(mail)

1.4 安全上下文

Linux 安全上下文 Context :运行中的程序,即进程(process),以进程发起者的身份运行,进程所能够访问资源的权限取决于进程的运行者的身份。
比如:root 身份运行 /bin/cat /etc/shadow 和 zzw 的身份运行 /bin/cat /etc/shadow ,得到的结果是不同的,shadow 能否被访问是由运行者的身份决定的,而非程序本身。
安全上下文 主要取决于进程的运行者的身份决定。
范例:

  1. root$ cat /etc/shadow
  2. root:$1$FwlI8jH1$.00.07OFQjNkOIyMZH1Ef/::0:99999:7:::
  3. bin:*:18397:0:99999:7:::
  4. daemon:*:18397:0:99999:7:::
  5. adm:*:18397:0:99999:7:::
  6. user$ cat /etc/shadow
  7. cat: /etc/shadow: Permission denied

2 用户和组的配置文件

AAA认证资源:认证,授权,审计/计费

  • 认证:验证用户身份。操作系统需要给每一个同步的用户分配不同的用户账号(因为不同账号的权限各不相同)
  • 授权:用户的权限设置。

Windows 系统主要是面对用户,Linux 系统主要跑各种服务(不同的服务需要不同认证和授权的用户) Linux 系统分为给服务使用的账号,还有给用户使用的账号

  • Linux需要针对各种不同的服务创建不同的系统账号,系统服务账号不是给用户使用的,是给服务使用的,该系统服务账号是随着程序的服务的启动来自动的使用该用户来运行。
  • Linux的普通用户账号则是通过交互式或者非交互式的登录系统,进行系统的管理配置。

2.1 用户和组的主要配置文件

/etc/passwd :用户及其属性信息(名称、UID、主组ID等等)
/etc/shadow :用户密码及其属性信息
/etc/group : 组及其相关属性
/etc/gshadow :组密码及其相关属性

2.2 passwd文件格式

login name:登录用户名(zzw)
password:密码(x)
UID:用户身份编号(1000)
GID:登录默认所在组编号(1000)
GECOS:用户全名或者注释
home directory:用户主目录(/home/zzw)
shell:用户默认使用shell(/bin/bash)
范例:

  1. # 手动触发更新数据库
  2. $ mandb
  3. $ whereis passwd
  4. # 查看 /etc/passwd 文件格式
  5. $ man 5 passwd
  6. name:password:UID:GID:GECOS:directory:shell
  7. # /etc/passwd :用户及其属性信息(名称、UID、主组ID等等)
  8. $ head -n2 /etc/passwd
  9. root:x:0:0:root:/root:/bin/bash
  10. bin:x:1:1:bin:/bin:/sbin/nologin # /sbin/nologin 不能交互登录
  11. # 最好不要手动修改该文件
  12. # 查看进程的信息
  13. # ps a 显示现行终端机下的所有程序,包括其他用户的程序
  14. # ps u 以用户为主的格式来显示程序状况
  15. # ps x 显示所有程序,不以终端机来区分。
  16. ps aux
  17. # 查看本机的拥有的Shell类型
  18. cat /etc/shells
  19. ## Linux操作系统的UID为0的用户即为系统的超级管理员

2.3 shadow文件格式

登录用户
用户密码:一般使用 sha512 加密;! 是锁定账号的意思;!! 是双保险双锁定
从 1970 年 1 月 1 日起到密码最近一次被更改的时间
密码再过几天可以被变更(0 表示随时可以被变更)
密码再过几天必须被变更(99999表示永不过期)
密码过期前几天系统提醒用户(默认为一周)
密码过期几天后账号会被锁定(账号的宽限期)
从 1970 年 1 月 1 日算起,多少天后账号失效(账户有效期)

  1. # /etc/shadow:用户密码及其属性信息
  2. $ whereis shadow
  3. # 查看/etc/shadow的文件格式
  4. $ man 5 shadow
  5. $ cat /etc/shadow
  6. root:$6$yt8l0QdpdrBPqDoE$3Cw6UGmvuDeqZV5j3gRrBZOD5xH7sXicoGb1/Fv3Ja5mUZbwiqWGWYMORNDy34682GKPyf.rsp8QNHtIURtWz0:18663:0:99999:7:::
  7. # 当前时间距离1970-01-01的天数
  8. $ echo $(date +%s)/86400 | bc
  9. 19123

更改密码加密算法:

authconfig --passalgo=sha512 --update

密码的安全策略:

  • 足够长
  • 使用数字、大写字母、小写字母及特殊字符中至少3种
  • 使用随机密码
  • 定期更换,不要使用最近曾经使用过的密码

范例:生成随机密码

$ cat /dev/urandom | tr -dc '[:alnum:]' | head -c 12
$ tr -dc "[:alpha:]" < /dev/urandom | head -c 12
nrQMYebNGDoQ

$ openssl rand -base64 9
AeOVQHWiDH8J

生成随机密码:https://suijimimashengcheng.bmcx.com/

2.4 group文件格式

群组名称:就是群组名称
群组密码:通常不需要设定,密码是被记录在 /etc/gshadow
GID:就是群组的 ID
以当前组为附加组的用户列表(分隔符为逗号)
范例:

# /etc/group: 组及其相关属性
$ whereis group
group: /etc/group /usr/share/man/man5/group.5.gz
# 查看/etc/group的文件格式
$ man 5 group
$ cat /etc/group
root:x:0:
mail:x:12:postfix

# postfix 是 mail 组的成员,即postfix用户下有附加组mail
$ id postfix
uid=89(postfix) gid=89(postfix) groups=89(postfix),12(mail)

2.5 gshadow文件格式

群组名称:就是群组名称
群组密码:加密
组管理员列表:组管理员的列表,更改组密码和成员
以当前组为附加组的用户列表:多个用户间用逗号分隔

# /etc/gshadow:组密码及其相关属性
$ whereis gshadow
$ man 5 gshadow
$ cat /etc/gshadow
root:::
# ! 锁定禁用的意思
zzw:!::

2.6 文件操作

  • vipw:编辑/etc/passwd配置文件(含语法检查) 和 vigr:编辑/etc/group配置文件(含语法检查)
  • pwck:检查/etc/passwd配置文件语法 和 grpck:检查/etc/group配置文件语法

    修改用户和组的管理尽量使用命令的方式进行,手动修改容易出错。

3 用户和组管理命令

用户管理命令

  • useradd:用户创建
  • usermod:用户属性修改
  • userdel:删除用户

组账号维护命令

  • groupadd:创建组
  • groupmod:组属性修改
  • groupdel:删除组

    3.1 用户创建

    useradd 命令可以创建新的 Linux 用户
    格式:

    Usage: useradd [options] LOGIN
         useradd -D
         useradd -D [options]
    

    常见的选项:

  • -u :UID

  • -o :配合 -u 选项,不检查 UID 的唯一性
  • -g GID :指明用户所属基本组,可以为组名,也可以为 GID
  • -c “COMMENT” :用户的注释信息
  • -d HOME_DIR :以指定的路径(不存在)为家目录
  • -s SHELL :指明用户的默认 Shell 程序,可用列表在 /etc/shells 文件中
  • -G GROUP1 [,GROUP2,…] :为用户指明附加组,组须事先存在
  • -N :不创建私用(有)组做主组,使用 users 组做主组
  • -r :创建系统用户 CentOS 6 之前:ID < 500,CentOS 7 以后:ID < 1000
  • -m :创建家目录,用于系统用户(默认系统用户不创建家目录)
  • -M :不创建家目录,用于非系统用户(默认普通用户创建家目录)
  • -p :指定加密的密码

范例:

# 各参数解析:
-r         :系统用户,默认不会创建家目录也不会拥有有邮箱
-u 48 :用户的UID为48
-g apache :用户的用户组为apache
-s /sbin/nologin :使用的shell类型为/sbin/nologin
-d /var/www    :指定用户的家目录为/var/www
-c "Apache" :用户的注释信息
apache :用户名为apache
$ useradd -r -u 48 -g apache -s /sbin/nologin -d /var/www -c "Apache" apache
$ useradd xiaoming
# 没有指定的用户的shell类型,默认使用/bin/bash
$ cat /etc/passwd | grep xiaoming
xiaoming:x:1002:1002::/home/xiaoming:/bin/bash
# 在新创建的用户的密码中,! 代表锁定,!! 代表双保险双锁定
$ cat /etc/shadow | grep xiaoming
xiaoming:!!:19123:0:99999:7:::
# 该账户无法进行登录

# 修改用户密码
$ echo "Admin@h3c" | passwd --stdin xiaoming &> /dev/null
$ cat /etc/shadow | grep xiaoming g
xiaoming:$6$Quw1uLkW$oAwnsw66tULIqjINjgBykT3D46pRjnQ9YcCzOfV48864vLY/5L/6X.AtBQh8uekzoJkM4lg2j.XKY/p.Kg0f./:19123:0:99999:7:::
$ ls -l /home | grep xiaoming
$ ls -l /var/spool/mail | grep xiaoming

# 会创建一个用户组,并且作为用户的主组
$ cat /etc/group | grep xiaoming
xiaoming:x:1002:
$ id xiaoming
uid=1002(xiaoming) gid=1002(xiaoming) groups=1002(xiaoming)
## 生产环境中需要人为的创建用户组并且将该用户组作为主组添加到新创建的用户中。即用户组和用户都需要手动创建
## 判断用户是不是同一个人,是通过UID用户ID,而不是用户名

## 生产环境实际使用(UID和Uname必须在服务器集群中一致)
$ groupadd -r -g 80 zhongzhiwei
$ cat /etc/group | grep zhongzhiwei (getent group zhongzhiwei)
zhongzhiwei:x:80:
$ useradd -r -u 80 -g zhongzhiwei -c "Test System User" -d /home/zhongzhiwei -s /bin/bash -m zhongzhiwei
$ echo "Admin@h3c" | passwd --stdin zhongzhiwei &> /dev/null
# $ mkdir /home/zhongzhiwei/ && chown zhongzhiwei:zhongzhiwei -R /home/zhongzhiwei/
# 可以使用getent命令
cat /etc/passwd == getent passwd
$  getent passwd zhongzhiwei
zhongzhiwei:x:80:80:Test System User:/home/zhongzhiwei:/bin/bash

useradd 命令默认值的设置是由 /etc/default/useradd 定义的

$ cat /etc/default/useradd
# useradd defaults file
GROUP=100        # 若不指定主组,则用户使用的是GID=100的组users
HOME=/home    # 用户家目录
INACTIVE=-1 # 对应/etc/shadow文件的第七列,即用户密码过期的宽限期
EXPIRE=            # 对应/etc/shadow文件的第八列,即用户账号密码的有效期
SHELL=/bin/bash    # 默认Shell类型
SKEL=/etc/skel    # 默认模板目录
CREATE_MAIL_SPOOL=yes    # 是否建立邮箱/var/spool/mail

显示或者更改默认设置

# useradd -D
# useradd -D -s SHELL
# useradd -D -b BASE_DIR
# useradd -D -g GROUP

$ useradd -D
GROUP=100
HOME=/home
INACTIVE=-1
EXPIRE=
SHELL=/bin/bash
SKEL=/etc/skel
CREATE_MAIL_SPOOL=yes

新建用户的相关文件

  • /etc/default/useradd :默认创建用户的基本信息
  • /etc/skel/* :表示账号使用默认文件内容, 可以理解为添加用户的目录默认文件存放位置
  • /etc/login.defs :设置用户帐号限制的文件,创建密码的规则。该文件里的配置对root用户无效。

批量创建用户

newusers passwd 格式文件

批量修改用户口令

echo username:passwd | chpasswd

范例:CentOS 6 创建并指定基于 sha512 的用户密码

$ grub-crypt --help
$ grub-crypt --sha-512
Password: 
Retype password: 
...(512加密算法字段)...

$ useradd -p '...(512加密算法字段)...' test
$ getent passwd test
$ getent shadow test4

范例:CentOS 7 利用python程序基于 sha512 的用户密码

# 需要安装python环境以及pip下载器
$ curl https://bootstrap.pypa.io/pip/2.7/get-pip.py -o get-pip.py
$ python get-pip.py
# 下载所需要的python库包即可
$ python -c 'import crypt,getpass;pw="Admin@h3c";print(crypt.crypt(pw))'
$6$zEx7bVN93ZFrDsGf$9J481TndM/JHQldoSK3oxghztz.UR3dZ6iF9s8Eba/CMqtcvIcbKHERRN0UtjO/xqaE0o43nlxp5tVEPy0xtq.

范例:CentOS 8 创建并指定基于 sha512 的用户密码

# -6:SHA512-based password algorithm
$ openssl passwd -6 Admin@h3c
$6$ecGOIQWzW.oGYJXv$RkEU2N1OLru8.h87SVW5fyRLvT6dMnQbIZAdSZDAADw5RxR7Xs5jj1JO5ul2fy0PQA2Ec0NA44782ASYCAvd01

$ useradd -p `openssl passwd -6 Admin@h3c` test

3.2 用户属性修改

usermod 命令可用修改用户属性
格式:

Usage: usermod [options] LOGIN

常见选项:

  • -a, —append:将用户添加到补充组中由-G选项提到而不删除来自其他组的用户
  • -u :UID:新 UID
  • -g GID :新主组
  • -G GROUP1 [,GROUP2,…] :新附加组,原来的附加组将会被覆盖;若保留原有,则要同时使用 -a 选项
  • -s SHELL :新的默认 SHELL
  • -c “COMMENT” :新的注释信息
  • -d HOME_DIR :新家目录不会自动创建;若要创建新家目录并且移动原家数据,同时使用 -m 选项
  • -l login_name :新的名字
  • -L :lock 指定用户,在 /etc/shadow 密码栏的增加 !,锁定用户
  • -U :unlock 指定用户,将 /etc/shadow 密码栏的 ! 拿掉,解锁用户
  • -e YYYY-MM-DD :指明用户账号过期日期
  • -f INACTIVE :设定非活动期限

范例:

# 创建组:admin
$ groupadd admin
# 将 admin 组作为附加组添加到用户 zhong
$ usermod -G admin zhong
$ getent group admin
admin:x:1002:zhong
$ id zhong
uid=1001(zhong) gid=1001(zhong) groups=1001(zhong),1002(admin)
# 将 root 组作为附加组添加到用户 zhong,发现 admin 组被覆盖
$ usermod -G root zhong
$ id zhong
uid=1001(zhong) gid=1001(zhong) groups=1001(zhong),0(root)
# 通常使用 usermod 添加附加组时使用 usermod -aG 选项搭配
$ usermod -aG admin zhong
$ id zhong
uid=1001(zhong) gid=1001(zhong) groups=1001(zhong),1002(admin),0(root)
# 清除附加组
$ id zzw
uid=1000(zzw) gid=1000(zzw) groups=1000(zzw),10(wheel),1002(admins)
$ usermod -G "" zzw
$ id zzw
uid=1000(zzw) gid=1000(zzw) groups=1000(zzw)

3.3 删除用户

userdel 可以删除 Linux 用户。默认只删除账号,不删除数据和用户家目录(推荐)
格式:

Usage: userdel [options] LOGIN

常见选项:

-f,--force  :强制
-r,--remove :删除用户家目录和邮箱

范例:强制删除用户和数据

$ getent passwd alice
alice:x:1001:1002::/home/alice:/bin/bash
$ userdel alice
$ ll /home/
total 36
drwxr-xr-x  6 root root  4096 6月  22 10:36 ./
drwxr-xr-x 21 root root  4096 5月  24 10:41 ../
drwxr-xr-x  2 1001 1002  4096 6月  22 10:28 alice/
# 默认不会删除用户的数据,-r将删除用户家目录和邮箱
$ userdel -r xiaoming
$ useradd test
$ id test
uid=1003(test) gid=1003(test) groups=1003(test)

# 另一个终端使用 test 登录
$ su - test
[test@CentOS8-Server ~]$

# 删除正在登录的用户失败
$ userdel -r test
userdel: user test is currently used by process 74396
$ id test
uid=1003(test) gid=1003(test) groups=1003(test)

# 强制删除用户和数据
$ userdel -rf test
userdel: user test is currently used by process 74396
$ id test
id: ‘test’: no such user

3.4 查看用户相关的ID信息

id 命令可以查看用户的 UID ,GID 等等信息

id [OPTION]... [USERNAME]

常见选项:

  • -u :显示UID
  • -g :显示GID
  • -G :显示用户所属的组的ID
  • -n :显示名称,需要配合 ugG 使用 ```bash

    id: cannot print “only” of more than one choice

    id命令只能一个选项执行

-n :显示名称,需要配合 ugG 使用

$ id -u -n root

<a name="ac40798c"></a>
## 3.5 切换用户或者以其他用户身份执行命令
su : 即switch user,命令可以切换用户身份,并且以指定用户的身份执行命令<br />格式:
```bash
su [OPTION]... [-] [USER [ARG]...]

切换用户的方式:

  • su UserName:非登录式切换,既不会读取目标用户的配置文件,不改变当前工作目录,即不完全切换
  • su - UserName:登录式切换,会读取目标用户的配置文件,切换至家目录,即完全切换

说明:root su 至其他用户无须密码;非 root 用户切换时需要密码
注意:su 切换新用户后,使用 exit 退回至旧的用户身份,而不要再用 su 切换到旧用户,否则会生成很多的 bash 子进程,环境可能混乱。
换个身份执行命令:

su [-] UserName -c 'COMMAND'

范例:

# 方法1:
$ getent passwd xiaoming
xiaoming:x:1002:1002::/home/xiaoming:/bin/bash
$ usermod -s /sbin/nologin xiaoming
$ getent passwd xiaoming
xiaoming:x:1002:1002::/home/xiaoming:/sbin/nologin
$ su - xiaoming
Last login: Wed May 11 14:55:09 CST 2022 on pts/0
This account is currently not available.
$ whoami
root

# 方法2:
$ su - root -c "cat /etc/passwd"
Password: (root口令)

常见选项:

-l —login su -l UserName 相当于 su - UserName -c, —command pass a single command to the shell with -c

范例:

# 完全切换用户身份
$ su - zhongzhiwei
$ pwd
/home/zhongzhiwei
$ id
uid=80(zhongzhiwei) gid=80(zhongzhiwei) groups=80(zhongzhiwei),1002(alice),2000(admins) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
$ echo $BASHPID
69086

$ su - alice
Password:
$ pwd
/home/alice
$ id
uid=1002(alice) gid=1002(alice) groups=1002(alice) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
$ echo $BASHPID
69246

# 使用root超级管理员新开终端
$ pstree -p | grep 69246
|-sshd(1069)-+-sshd(8495)---sshd(8501)-+-bash(8506)---su(69083)---bash(69086)---su(69230)---bash(69246)
# 可以发现终端运行了很多的子 Bash Shell。会造成环境混乱

# 不完全切换用户身份
$ cd /data/
$ su zhongzhiwei
[zhongzhiwei@CentOS8-Server data]$ pwd
/data
[zhongzhiwei@CentOS8-Server data]$ echo $PATH
/home/zhongzhiwei/.local/bin:/home/zhongzhiwei/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
# 不完全切换是会残留上一个用户的权限信息
# 完全切换执行root用户的指令
[zhongzhiwei@CentOS8-Server root]$ su - root -c "cat /etc/passwd"
Password: 
root:x:0:0:root:/root:/bin/bash

3.6 设置密码

image.png
passwd 可以修改用户密码
格式:

passwd [OPTION...] UserName

常用选项:

  • -d :删除指定用户密码
  • -l :锁定指定用户(usermod -L)
  • -u :解锁指定用户(usermod -U)
  • -e :强制用户下次登录修改密码
  • -f :强制操作
  • -n mindays :指定最短使用期限
  • -x maxdays :最大使用期限
  • -w warndays :提前多少天开始警告
  • -i inactivedays :非活动期限
  • —stdin :从标准输入接收用户密码

范例:非交互式修改用户密码

# 此方法更加通用,适用于各种Linux操作系统版本,比如:Ubuntu
$ echo -e "123456\n123456" | passwd zhongzhiwei 
Changing password for user zhongzhiwei.
New password: BAD PASSWORD: The password is shorter than 8 characters
Retype new password: passwd: all authentication tokens updated successfully.

# 此方法适用于红帽系列的Linux版本
$ echo "123456" | passwd --stdin zhongzhiwei
Changing password for user zhongzhiwei.
passwd: all authentication tokens updated successfully.

范例:Ubuntu 非交互式修改用户密码

# 方法1:需要借助chpasswd通用
# 格式:echo 用户名:密码 | chpasswd
$ echo wang:centos | chpasswd

# 方法2:
$ passwd wang <<EOF
centos
centos
EOF

# 方法3:
$ echo -e "magedu\nmagedu" | passwd wang

范例:设置用户下次必须更改密码

$ useradd -c "Test User" -m alice
$ echo "123456" | passwd --stdin alice
Changing password for user zhongzhiwei.
passwd: all authentication tokens updated successfully.
$ getent shadow alice
alice:$6$A/1XlYuzCT7LToKo$/U7VbVVTIB3eOosQzS8sJmNBvTuqMmZYcTOF0H/Qw2s9F4OJb//RNt8hK.D5W7noqj/PEUU4A3gv1HkKnvY901:19123:0:99999:7:::
$ passwd -e alice
Expiring password for user alice.
passwd: Success
$ getent shadow alice
alice:$6$A/1XlYuzCT7LToKo$/U7VbVVTIB3eOosQzS8sJmNBvTuqMmZYcTOF0H/Qw2s9F4OJb//RNt8hK.D5W7noqj/PEUU4A3gv1HkKnvY901:0:0:99999:7:::

$ su - alice
[alice@CentOS8-Server ~]$ su - alice
Password: Admin@h3c
You are required to change your password immediately (administrator enforced)
Current password: Admin@h3c
New password: Kubesphere@Admin@h3c
Retype new password: Kubesphere@Admin@h3c
$ logout
$ getent shadow alice 
alice:$6$PmhKEAStbdDUqXNF$0mX1NdJMWuCeyIhYaIPh0kXAw8M4fnMFOPsgnRgvcoYnWQDxfzejv6wD/o45518FPx4XFgeeHHD/SaJHxmKY9.:19123:0:99999:7::

3.7 修改用户密码策略

# 默认创建用户的密码策略是 /etc/login.defs

chage 可以修改用户密码策略
格式:

Usage: chage [options] LOGIN

常见选项:

  • -d LAST_DAY:最后一次设置口令的时间(chage -d 0 username = passwd -e username)
  • -m —mindays MIN_DAYS:用户最小口令有效期
  • -M —maxdays MAX_DAYS:用户最大口令有效期
  • -W —warndays WARN_DAYS:口令过期提前告警
  • -l —inactive INACTIVE:密码过期后的宽限期
  • -E —expiredate EXPORE_DATE:用户的有效期
  • -l:显示密码策略

范例:

# 默认交互式进行修改用户密码策略
$ chage zhongzhiwei
Changing the aging information for zhongzhiwei
Enter the new value, or press ENTER for the default

        Minimum Password Age [-1]: 3
        Maximum Password Age [-1]: 42
        Last Password Change (YYYY-MM-DD) [2022-05-11]: 2022-05-20
        Password Expiration Warning [-1]: 7
        Password Inactive [-1]: 20
        Account Expiration Date (YYYY-MM-DD) [-1]: 2023-05-11

$ chage -m 3 -M 42 -W 14 -I 7 -E 2020-10-10 zhongzhiwei
$ chage -l zhongzhiwei
Last password change                                    : May 20, 2022
Password expires                                        : Jul 01, 2022
Password inactive                                       : Jul 21, 2022
Account expires                                         : May 11, 2023
Minimum number of days between password change          : 3
Maximum number of days between password change          : 42
Number of days of warning before password expires       : 7
$ getent passwd zhongzhiwei
zhongzhiwei:x:80:80:Test System User:/home/zhongzhiwei:/bin/bash

# 下一次登录强制重设密码
$ chage -d 0 zhongzhiwei
$ getent shadow zhongzhiwei
zhongzhiwei:$6$ezbKKcIF$GObcBsflpUXLuhORWIqp.0t1hc2KVLpx3mX3YA2oOxKpAapCagOf.cYqeEHXe2pPO3Eqz1H8/K0g854EeBiAL/:0:3:42:7:20:19488:
$ chage -l zhongzhiwei
Last password change                                    : password must be changed
Password expires                                        : password must be changed
Password inactive                                       : password must be changed
Account expires                                         : May 11, 2023
Minimum number of days between password change          : 3
Maximum number of days between password change          : 42
Number of days of warning before password expires       : 7

3.8 用户相关的其他命令

  • chfn :指定个人信息
  • chsh :指定shell
  • finger :可以看用户个人信息

范例:

# chfn :指定个人信息
$ chfn zhong
Changing finger information for zhongzhiwei.
Name [Test System User]:
Office []: Kubesphere.io
Office Phone []: 15118013447
Home Phone []: 15118013447

Finger information changed.

# finger :可以看用户个人信息
$ yum install -y finger
$ finger zhong
Login: zhong                            Name: zhong
Directory: /home/zhong                  Shell: /bin/bash
Office: IT, 110                         Home Phone: 119
Never logged in.
No mail.
No Plan.
$ getent passwd zhong
zhong:x:1001:1001:zhong,IT,110,119:/home/zhong:/bin/bash

# chsh :指定shell
$ getent passwd zhong
zhong:x:1002:1002:zhong user:/home/zhong:/bin/bash
$ chsh -s /bin/sh zhong
$ getent passwd zhong
zhong:x:1002:1002:zhong user:/home/zhong:/bin/sh
$ usermod -s /bin/bash zhong
$ getent passwd zhong
zhong:x:1002:1002:zhong user:/home/zhong:/bin/bash

# finger :可以看用户个人信息
$ finger zhong
Login: zhongzhiwei                      Name: Test System User
Directory: /home/zhongzhiwei            Shell: /bin/bash
Office: Kubesphere.io, +1-511-801-3447  Home Phone: +1-511-801-3447
Last login Thu May 12 08:33 (CST) on pts/0
No mail.
No Plan.

范例:修改用户使用不可登录 Shell 类型

### 不可登录 Shell 类型:/bin/false & /sbin/noligin
$ getent passwd zhong
zhong:x:1001:1001:zhongzhiwei,IT,110,119:/home/zhong:/bin/bash
$ chsh -s /sbin/nologin zhong
Changing shell for zhong.
chsh: Warning: "/sbin/nologin" is not listed in /etc/shells.
Shell changed.

$ su - zhong
This account is currently not available.
$ chsh -s /bin/false zhong
Changing shell for zhong.
chsh: Warning: "/bin/false" is not listed in /etc/shells.
Shell changed.

$ su - zhong
Last login: Tue May  4 17:26:32 CST 2021 on pts/0
$ id
uid=0(root) gid=0(root) groups=0(root)
$ chsh -s /bin/bash zhong
Changing shell for zhong.
Shell changed.

$ su - zhong
Last login: Tue May  4 17:26:47 CST 2021 on pts/0
$ id
uid=1001(zhong) gid=1001(zhong) groups=1001(zhong),0(root)

3.9 创建组

groupadd 实现创建组
格式:

groupadd [options] GROUP

常见选项:

  • -g GID:指明 GID 号;[GID_MIN , GID_MAX]
  • -r :创建系统组,CentOS 6之前: ID<500,CentOS 7以后: ID<1000

范例:

groupadd -g 48 -r apache

# zhongzhiwei用户原本有附加组
$ id zhongzhiwei 
uid=80(zhongzhiwei) gid=80(zhongzhiwei) groups=80(zhongzhiwei),1002(alice)
$ groupadd -g 2000 admins
$ getent group admins
admins:x:2000:
# 若直接使用usermod -G admins zhongzhiwei 会将原有的附加组覆盖
$ usermod -G admins zhongzhiwei
$ id zhongzhiwei
uid=80(zhongzhiwei) gid=80(zhongzhiwei) groups=80(zhongzhiwei),2000(admins)

# 正确添加附加组的做法:
# 方法1:需要查看用户之前是否的有附加组,若有则-G选项后补该附加组
$ usermod -G alice,admins zhongzhiwei
$ id zhongzhiwei
uid=80(zhongzhiwei) gid=80(zhongzhiwei) groups=80(zhongzhiwei),1002(alice),2000(admins)
# 方法2:直接使用 -aG 选项追加附加组即可
$ usermod -aG admins zhongzhiwei
$ id zhongzhiwei
uid=80(zhongzhiwei) gid=80(zhongzhiwei) groups=80(zhongzhiwei),1002(alice),2000(admins)

3.10 修改组

groupmod 实现组属性修改
格式:

Usage: groupmod [options] GROUP

常见选项:

  • -n group_name:新名字
  • -g GID:新的 GID

    3.11 组删除

    groupdel 实现组的删除
    格式:

    groupdel [options] GROUP
    

    常见选项:

  • -f ,—force :强制删除,即时是用户的主组也强制删除组,但是会导致无主组的用户不可用无法登录

    3.12 更改组密码

    组密码:gpasswd
    格式:

    gpasswd [option] GROUP
    

    常见选项:

  • -a user:将 user 添加至指定组中(usermod -aG groupname username | groupmems -a username groupname)

  • -d user:从指定组中移除用户user(groupmems -d username groupname)
  • -A user1,user2,……:设置有管理权限的用户列表

范例:

# 修改用户组密码
$ gpasswd root
Changing the password for group root
New Password:
Re-enter new password:

# 添加组成员
$ groupadd admins
$ id zzw
uid=1000(zzw) gid=1000(zzw) groups=1000(zzw)
$ gpasswd -a zzw admins
Adding user zzw to group admins
$ id zzw
uid=1000(zzw) gid=1000(zzw) groups=1000(zzw),1002(admins)
$ getent group admins
admins:x:1002:zzw
$ groups zzw
zzw : zzw admins

# 删除组成员
$ gpasswd -d zzw admins
Removing user zzw from group admins
$ id zzw
uid=1000(zzw) gid=1000(zzw) groups=1000(zzw)
$ groups zzw
zzw : zzw

3.13 临时切换主组

newgrp 命令可以临时切换主组,如果用户本不属于此组,则需要组密码。
格式:

newgrp [-] [group]

如果使用 - 选项,可以初始化用户环境
范例:

$ gpasswd root
Changing the password for group root
New Password:
Re-enter new password:

$ getent gshadow root
root:$6$7tiKB5zdJa/$Y3KzkkqVsuvWSSmve5watUe5T2wI/txrUDFsJGs22zuUxR9tST7vgpM0NtCnmkJIwyFwiucKM/QXu89mx9ToV/::zhongzhiwei

$ su - zzw
Last login: Sun May  8 12:17:50 CST 2022 on pts/0
[zzw@kubesphere-docker ~]$ newgrp root
Password:
# 临时切换主组为root
[zzw@kubesphere-docker ~]$ id
uid=1000(zzw) gid=0(root) groups=0(root),1000(zzw)
[zzw@kubesphere-docker ~]$ echo "zzw.txt" > zzw.txt
[zzw@kubesphere-docker ~]$ ls -l
total 4
-rw-r--r-- 1 zzw root 8 May 12 08:38 zzw.txt
[zzw@kubesphere-docker ~]$ exit

# 退出后重新登录,临时主组已经失效
$ su - zzw
Last login: Thu May 12 08:37:44 CST 2022 on pts/0
[zzw@kubesphere-docker ~]$ id
uid=1000(zzw) gid=1000(zzw) groups=1000(zzw)
[zzw@kubesphere-docker ~]$ echo "zzw.log" > zzw.log
[zzw@kubesphere-docker ~]$ ls -l
total 8
-rw-rw-r-- 1 zzw zzw  8 May 12 08:40 zzw.log
-rw-r--r-- 1 zzw root 8 May 12 08:38 zzw.txt

3.14 更改和查看组成员

groupmems 可以管理组成员关系
格式:

groupmems [options] [action]

常见选项:

  • -g, —group groupname:更改为指定组(只有root)
  • -a,-add username :指定用户加入组
  • -d,—delete username :从组中删除用户
  • -p,—purge :从组中清除所有成员
  • -l,—list :显示组成员列表

groups 可以查看用户组关系
格式:

# 查看用户所属组列表
groups [OPTION]... [USERNAME]...

范例:

# 显示组成员列表
$ groupmems -l -g admins & getent group admins
zhongzhiwei

# 指定用户加入组
$ groupmems -a xiaoming -g admins ( usermod -aG admins xiaoming )
$ groupmems -l -g admins
zhongzhiwei  xiaoming

# 从组中删除用户
$ groupmems -d zhongzhiwei -g admins ( usermod -G "" zhongzhiwei )
$ groupmems -l -g admins
xiaoming
### 以上功能在usermod 命令中也可以实现,作为扩展命令了解即可

# groups 可以查看用户组关系
$ groups zhongzhiwei
zhongzhiwei : zhongzhiwei admins
$ groupmems -l -g admins
xiaoming  zhongzhiwei
# 从组中清除所有成员
$ groupmems -p -g admins
$ groupmems -l -g admins

3.15 练习

# 1.创建用户gentoo,附加组为bin和root,默认shell为/bin/csh,注释信息为"Gentoo Distribution"
# 2.创建下面的用户、组和组成员关系
## 名字为 webs 的组
## 用户nginx,使用 webs 作为附加组
## 用户varnish,使用 webs 作为附加组
## 用户mysql,不可交互登录系统,且不是 webs 的成员,nginx,varnish,mysql密码都是magedu
## 不可交互登录系统:CentOS:/sbin/nologin Ubuntu:/usr/sbin/nologin 以及 /bin/false
# 1.创建用户gentoo,附加组为bin和root,默认shell为/bin/csh,注释信息为"Gentoo Distribution"
$ useradd -s /bin/csh -G bin,root -c "Gentoo Distribution" gentoo

# 2.创建下面的用户、组和组成员关系
## 名字为 webs 的组
$ groupadd -g 8088 webs 

## 用户nginx,使用 webs 作为附加组
$ useradd -G webs -c "Nginx Distribution" -s /bin/bash nginx
$ echo -e "magedu\nmagedu" | passwd nginx

## 用户varnish,使用 webs 作为附加组
$ useradd -G webs -c "Varnish Distribution" -s /bin/bash varnish
$ echo "magedu" | passwd --stdin varnish

## 用户mysql,不可交互登录系统,且不是 webs 的成员,nginx,varnish,mysql密码都是magedu
$ useradd -s /sbin/nologin -c "MySQL Distribution" mysql
$ echo "magedu" | passwd --stdin mysql

### 不可交互登录系统:CentOS:/sbin/nologin Ubuntu:/usr/sbin/nologin 以及 /bin/false

4 文件权限管理

程序访问文件时的权限,取决于此程序的发起者

  • 进程的发起者,同文件的属主:则应用文件属主权限
  • 进程的发起者,属于文件属组;则应用文件属组权限
  • 应用文件”其它”权限

image.png

4.1 文件所有者和属组属性操作

4.1.1 设置文件的所有者 chown

chown 命令可以修改文件的属组,也可以修改文件属组
格式:

chown [OPTION]... [OWNER][:[GROUP]] FILE...
chown [OPTION]... --reference=RFILE FILE...

文件 7 种类型:

  • -:普通文件
  • d:目录
  • p:管道文件
  • s:socket 套接字文件
  • l:链接文件
  • c:字符设备文件
  • b:块设备文件

常用选项:

  • OWNER:只修改所有者
  • OWNER:GROUP:同时修改所有者和属组
  • :GROUP:只修改属组,冒号也可用 . 替换
  • -R:递归,此选项慎用,非常危险
  • —reference=RFILE:参考指定的属性,来修改

范例:

$ mkdir dir
$ cp /etc/fstab dir/f1.txt
$ ls -l dir/
total 8
-rw-r--r-- 1 root root 382 May 12 10:30 f1.txt
$ chown zhongzhiwei dir/f1.txt
$ ls -l dir/f1.txt
-rw-r--r-- 1 zhongzhiwei root 382 May 12 10:37 dir/f1.txt

$ chown :admins dir/f1.txt (chgrp admins dir/f1.txt)
$ ls -l dir/f1.txt
-rw-r--r-- 1 zhongzhiwei admins 382 May 12 10:37 dir/f1.txt

# 参考指定的属性,来修改
$ cp /etc/issue dir/f2.txt
$ chown --reference=dir/f1.txt dir/f2.txt
$ ls -l dir/
total 8
-rw-r--r-- 1 zhongzhiwei admins 382 May 12 10:37 f1.txt
-rw-r--r-- 1 zhongzhiwei admins  23 May 12 10:38 f2.txt

范例:

chown -R zzw:zzw dir

范例:查看文件 selinux 属性

$ ll
total 8
-rw-------. 1 root root 2728 Feb  4 23:16 anaconda-ks.cfg
$ ll -Z anaconda-ks.cfg
-rw-------. 1 root root system_u:object_r:admin_home_t:s0 2728 Feb  4 23:16 anaconda-ks.cfg

4.1.2 设置文件的属组信息 chgrp

chgrp 命令可以只修改文件的属组
格式:

chgrp [OPTION]... GROUP FILE...
chgrp [OPTION]... --reference=RFILE FILE...

常用选项:

  • -R:递归

范例:

$ ls -l dir/f1.txt 
-rw-r--r-- 1 zzw zzw 382 May 12 10:37 dir/f1.txt
$ chgrp admins dir/f1.txt
$ ls -l dir/f1.txt 
-rw-r--r-- 1 zzw admins 382 May 12 10:37 dir/f1.txt.

# -R:递归
$ chgrp -R zhongzhiwei dir
$ ls -l dir/
total 8
-rw-r--r-- 1 zzw zhongzhiwei 382 May 12 10:37 f1.txt
-rw-r--r-- 1 zzw zhongzhiwei  23 May 12 10:38 f2.txt

4.2 文件权限

4.2.1 文件权限说明

文件的权限主要针对三类对象进行定义

  • owner: 属组,u
  • group: 属组,g
  • other: 其他,o

注意:

用户的最终权限,是从左向右进行顺序匹配,即,所有者,所属组,其他人,一旦匹配权限立即生效,不再向右查看其权限r和w权限对root用户无效 只要所有者,所属组或other三者之一有x权限, root就可以执行

每个文件针对每类访问者都定义了三种常用的权限

  • r:Readable ,读权限,查看文件的内容
  • w:Writable ,写权限,编辑修改文件内容
  • x:eXcutable ,执行权限,例如:二进制程序,脚本

对文件的权限

  • r:可以使用文件查看类工具获取其内容,可以进行拷贝等操作;比如:cat 可以获取其内容
  • w:可以修改其内容
  • x:可以把此文件提请内核启动为一个进程,即可以执行(运行)此文件(此文件的内容必须是可执行的)

对目录的权限

  • r:可以使用 ls 查看此目录中文件列表
  • w:可以在此目录中创建文件,也可以删除此目录中的文件
  • x:可以使用 ls -l 查看此目录中文件元数据(需要配合 -r ),可以 cd 进入到此目录中。执行权限是目录的最小权限
  • X:只给目录 x 执行权限,不给无执行权限文件 x 执行权限

    一个文件是否可以删除,跟文件本身的权限无关,跟文件所处的目录权限(写权限)有关

面试题:

Linux中的目录和文件的权限区别?(分别说明读,写和执行权限的区别)

数字法的权限
image.png

八进制数字:—- 000 0;—x 001 1;-w- 010 2;-wx 011 3;r— 100 4;r-x 101 5;rw- 110 6;rwx 111 7; 例如:640 :rw-r——- 755 :rwxrw-rw-

  • 只要有执行权限,数字法表示就一定是奇数

4.2.2 修改文件权限 chmod

格式:

chmod [OPTION]... MODE[,MODE]... FILE...
chmod [OPTION]... OCTAL-MODE FILE...
# 参考RFILE 文件的权限,将FILE的修改为同RFILE
chmod [OPTION]... --reference=RFILE FILE...

说明:

  • -R:递归修改权限

说明:模式法格式

# MODE:who opt permission
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:递归修改权限
## 执行权限对root管理员有一定的影响,但是读写权限对root管理员没有影响(即使该文件没有读写权限)

范例:设置 X 权限

# 可以发现cat 和 subdir中的所属组和其他人在执行权限没有(目录和可执行文件)
$ ls -l testdir/
total 60
-rwxr--r-- 1 root root 54080 May 12 11:11 cat
-rw-r--r-- 1 root root   382 May 12 11:09 f1.txt
drwxr--r-- 2 root root     6 May 12 11:10 subdir
$ ls -ld testdir
drwxr-xr-x 3 root root 45 May 12 11:12 testdir
# 只给目录 x 执行权限,不给无执行权限文件 x 执行权限
$ chmod -R a+X testdir
$ ls -l testdir/
total 60
-rwxr-xr-x 1 root root 54080 May 12 11:11 cat
-rw-r--r-- 1 root root   382 May 12 11:09 f1.txt
drwxr-xr-x 2 root root     6 May 12 11:10 subdir

范例:

chmod u+wx,g-r,o=rx file
chmod -R g+rwx /testdir
chmod 600 file

面试题:

# 执行 cp /etc/issue /data/dir 所需要的最小权限?
/bin/cp :需要 x 权限
/etc/ : 需要 x 权限
/etc/issue :需要 r 权限
/data/ :需要 x 权限
/etc/dir :需要 w,x 权限

4.3 新建文件和目录的默认权限

umask 的值可以保留在创建文件权限中(umask 一般不会主动修改)
实现方式:

  • 新建文件的默认权限为:666-umask,如果所得结果某位存在执行(奇数)权限,则将其权限 +1 ,偶数保留结果
  • 新建目录的默认权限为:777-umask

    umask+default=dir777 | file666

非特权用户 umask 默认为是 002;即(新创建文件权限为666 - 002 = 664;新创建目录权限为777 - 002 = 775)
root 特权用户 umask 默认为是 022;即(新创建文件权限为 666-022 = 644;新创建目录权限为 777 - 022 = 755)
查看 umask

$ umask
0022
# 模式方式显示
$ umask -S
u=rwx,g=rx,o=rx
# 输出可被调用
$ umask -p
umask 0022

修改 umask

umask #umask数

范例:设置 umask 数值

umask 022
umask u=rw,g=r,o=

持久保存 umask

  • 全局设置:/etc/bashrc
  • 用户设置:~/.bashrc

范例:

$ umask 
0022
$ umask -p
umask 0022
$ umask -S
u=rwx,g=rx,o=rx

$ ( umask 666;touch /data/app.key )
$ umask 
0022
$ ls -l /data/app.key 
---------- 1 root root 0 May 12 11:54 /data/app.key

4.3.1 练习:

# 1.当用户docker对/testdir 目录无执行权限时,意味着无法做哪些操作?
# 2.当用户mongodb对/testdir 目录无读权限时,意味着无法做哪些操作?
# 3.当用户redis 对/testdir 目录无写权限时,该目录下的只读文件file1是否可修改和删除?
# 4.当用户zabbix对/testdir 目录有写和执行权限时,该目录下的只读文件file1是否可修改和删除?
# 5.复制/etc/fstab文件到/var/tmp下,设置文件所有者为tomcat读写权限,所属组为apps组有读写权限,其他人无权限。
# 6.误删除了用户git的家目录,请重建并恢复该用户家目录及相应的权限属性
### 准备工作
for NAME in {docker,mongodb,redis,zabbix,tomcat}; do useradd $NAME; done
mkdir -pv /testdir

# 1.当用户docker对/testdir 目录无执行权限时,意味着无法做哪些操作?
用户 docker将无法进入到 /testdir
#则 docker 用户无法使用 cd 命令进入到 /testdir。

# 2.当用户mongodb对/testdir 目录无读权限时,意味着无法做哪些操作?
用户 mongodb将无法读取 /testdir 文件列表内容
#则 mongodb 用户可以使用 cd 命令进入到 /testdir 目录中,但是无法查看该目录的文件列表内容。

# 3.当用户redis 对/testdir 目录无写权限时,该目录下的只读文件file1是否可修改和删除?
用户 redis无法对 /testdir/file1只读文件进行修改和删除
#则 redis 用户无法修改和删除只读文件 file1。但是可以进入和查看该目录的文件列表。

# 4.当用户zabbix对/testdir 目录有写和执行权限时,该目录下的只读文件file1是否可修改和删除?
用户 zabbix 可以对 /testdir/file1只读文件进行修改和删除
#则 zabbix 用户可以对该目录下的只读文件file1 有修改和删除的操作。但是无法查看该目录的文件列表。

# 5.复制/etc/fstab文件到/var/tmp下,设置文件所有者为tomcat读写权限,所属组为apps组有读写权限,其他人无权限。
~ cp -av /etc/fstab /var/tmp/
~ setfacl -m u:tomcat:rw- /var/tmp/fstab
~ chgrp apps /var/tmp/fstab ; setfacl -m g:apps:rw- /var/tmp/fstab
~ chmod o=--- /var/tmp/fstab
~ getfacl /var/tmp/fstab
getfacl: Removing leading '/' from absolute path names
# file: var/tmp/fstab
# owner: root
# group: apps
user::rw-
user:tomcat:rw-
group::r--
group:apps:rw-
mask::rw-
other::---

# 6.误删除了用户git的家目录,请重建并恢复该用户家目录及相应的权限属性
~ rm -rf /home/git
~ mkdir -pv /home/git
~ cp -av /etc/skel/ /home/git
~ chown -R git:git /home/git

4.4 Linux 文件系统上的特殊权限

前面介绍了三种常见的权限:r,w,x,还有三种特殊权限:SUID,SGID,Sticky

  • 以上特殊权限只针对普通用户,root用户不受限

SUID :作用在二进制可执行文件上,用户将继承此程序所有者的权限
SGID :
(1)作用在二进制可执行文件上,用户将继承此程序所属组的权限
(2)作用于目录上,此目录中新建的文件或者目录所属组将自动从此目录继承
Sticky :作用于目录上,此目录中的文件只能由所有者自己来删除(作用在文件上没有用)

4.4.1 特殊权限 SUID

安全上下文;
前提:进程有属主和属组;文件有属主和属组;

  1. 任何一个可执行程序文件能不能启动为进程,取决于发起者对程序文件是否拥有执行权限
  2. 启动为进程之后,其进程的属主为发起者,进程的属组为发起者所属的组
  3. 进程访问文件时的权限,取决于进程的发起者

(a)进程的发起者,同文件的属主;则应用文件属主权限
(b)进程的发起者,属于文件的属组;则应用文件属组权限
(c)应用文件“其他”权限
二进制的可执行文件上的 SUID 权限功能:

  • 任何一个可执行程序文件能不能启动为进程:取决于发起者对程序文件是否拥有执行权限
  • 启动为进程之后,其进程的属主为原程序文件的属主
  • SUID 只对二进制可执行程序有效
  • SUID 设置在目录上无意义

SUID 权限设定:

# 使用 suid 特殊权限后,用户使用该命令后继承会使用该命令属主的权限
chmod u+s FILE ...
chmod 4xxx FILE ...
chmod u-s FILE ...

# suid 只能作用于所有者权限上

范例:

$ ls -l /bin/passwd 
-rwsr-xr-x. 1 root root 27856 Apr  1  2020 /bin/passwd

$ ls -l /bin/vim
-rwxr-xr-x 1 root root 2337208 Dec 16  2020 /bin/vim
# 添加 suid 权限
$ chmod u+s /bin/vim     ( chmod 4755 /bin/vim )
$ ls -l /bin/vim
-rwsr-xr-x 1 root root 2337208 Dec 16  2020 /bin/vim
# 普通用户登录
$ id 
uid=1003(admins) gid=1003(admins) groups=1003(admins)
# 普通用户可以使用vim编辑/etc/shadow文件
# 所以该特殊权限尽量不要使用,危险
$ vim /etc/shadow

4.4.2 特殊权限 SGID

二进制的可执行上 SGID 权限功能:

  • 任何一个可执行程序文件能不能启动为进程:取决于发起者对程序文件是否拥有执行权限
  • 启动为进程之后,其进程的属主为原程序文件的属组

SGID 权限设定:

# 使用 sgid 特殊权限后,用户使用该命令后会继承使用该命令属组的权限
chmod g+s FILE ...
chmod 2xxx FILE ...
chmod g-s FILE ...

范例:二进制的可执行上 SGID 权限功能

$ ll /etc/shadow
---------- 1 root root 1464 May  5 00:33 /etc/shadow
$ su zzw
$ vim /etc/shadow
"/etc/shadow" [Permission Denied]

$ chmod g+s /bin/vim
$ ll /bin/vim
-rwxr-sr-x. 1 root root 3063848 Jun 18  2020 /bin/vim
$ su zzw
$ vim /etc/shadow
"/etc/shadow" [Permission Denied]

$ ll /etc/shadow
---------- 1 root root 1464 May  5 00:33 /etc/shadow
$ chmod g+rw /etc/shadow
$ ll /etc/shadow
----rw---- 1 root root 1464 May  5 00:33 /etc/shadow
$ su zzw
$ vim /etc/shadow
root:$1$FwlI8jH1$.00.07OFQjNkOIyMZH1Ef/::0:99999:7:::
bin:*:18397:0:99999:7:::
daemon:*:18397:0:99999:7:::

目录上的 SGID 权限功能:
默认情况下,用户创建文件时,其属组为此用户所属的主组,一旦某个目录被设定了 SGID ,则对此目录有写权限的用户在此目录中创建的文件所属的组为此目录的属组,通常用于创建一个协作目录。
SGID 权限设定:

chmod g+s FILE ...
chmod 2xxx FILE ...
chmod g-s FILE ...

范例:目录上的 SGID 权限功能

$ mkdir sgid-dir
$ chgrp admins sgid-dir
$ chmod a+w sgid-dir
# 目录上的 SGID 权限功能
$ chmod g+s sgid-dir
$ ls -ld sgid-dir
drwxrwsrwx 2 root admins 6 May 12 12:59 sgid-dir

# 切换普通用户
$ su zzw
$ echo 1111 > zzw.txt
$ ls -l
total 4
-rw-rw-r-- 1 zzw admins 5 May 12 13:01 zzw.txt
$ su admins
$ mkdir admins-dir
$ ls -l
total 4
drwxrwsr-x 2 admins admins 6 May 12 13:02 admins-dir
-rw-rw-r-- 1 zzw    admins 5 May 12 13:01 zzw.txt
# 在目录上添加SGID,其在该目录下新建的文件或者目录都是继承该目录的所属组

4.4.3 特殊权限Sticky 位

具有写权限的目录通常用户可以删除该目录中的任何文件,无论该文件的权限或者拥有权
在目录设置 Sticky 位,只有文件的所有者 或者 root 可以删除该文件(使用 Sticky 特殊权限后,各用户只能管理各用户的文件)
Sticky 设置在文件上无意义
Sticky 权限设定:

# 使用 Sticky 特殊权限后,各用户只能管理各用户的文件
chmod o+t DIR ...
chmod 1xxx DIR ...
chmod o-t DIR ...

范例:

ll -d /tmp/
drwxrwxrwt. 19 root root 4096 May  4 22:17 /tmp/

4.4.4 特殊权限数字法

SUID,SGID,STICKY

000 0
001 1
010 2
011 3
100 4
101 5
110 6
111 7

范例:

# 设置 SUID
chmod 4777 /tmp/a.txt
# 设置SGID
chmod 2777 /tmp/a.txt
# 设置Sticky
chmod 1777 /tmp/a.txt

权限位映射:
SUID: user ,占据属主的执行权限位(4)
s:属主拥有 x 权限;
S:属主没有 x 权限;
SGID:group ,占据属组的执行权限位(2)
s:group 拥有 x 权限
S:group 没有 x 权限
Sticky:other ,占据 other 的执行权限位(1)
t: other 拥有 x 权限
T:other 没有 x 权限

4.5 设定文件特殊属性

设置文件的特殊属性,可以访问 root 用户误操作或者修改文件(普通用户无法使用该命令)
不能删除 , 改名 , 更改

$ chattr +i file

只能追加内容,不能删除,改名

$ chattr +a file

显示特定属性

$ lsattr

范例:

$ cp /etc/fstab important.txt
$ ls -l important.txt 
-rw-r--r-- 1 root root 382 May 12 16:30 important.txt
# 不能删除 , 改名 , 更改
$ chattr +i important.txt
$ grep -Ev "^#|^$" important.txt 
UUID=9cff3d69-3769-4ad9-8460-9c54050583f9 /                       xfs     defaults        0 0
LABEL=YUNIFYSWAP swap                    swap    defaults        0 0

$ rm -rf important.txt
rm: cannot remove ‘important.txt’: Operation not permitted
$ echo 111222 >> important.txt
-bash: important.txt: Permission denied
$ chmod 777 important.txt
chmod: changing permissions of ‘important.txt’: Operation not permitted

# 显示特定属性
$ lsattr important.txt
----i----------- important.txt

# 去掉特定属性
$ chattr -i important.txt
$ lsattr important.txt
---------------- important.txt
$ rm -f important.txt
$ cp /etc/issue import.txt
$ chattr +a import.txt
$ lsattr import.txt
-----a---------- import.txt

$ rm -f import.txt
rm: cannot remove ‘import.txt’: Operation not permitted
$ mv import.txt f1.txt
mv: cannot move ‘import.txt’ to ‘f1.txt’: Operation not permitted
$ echo 111222 >> import.txt
$ cat import.txt
\S
Kernel \r on an \m

111222
$ chattr -a import.txt
$ lsattr import.txt
---------------- import.txt
$ rm -f import.txt

4.6 访问控制列表ACL

4.6.1 ACL 权限功能

ACL:Access Control List,实现灵活的权限管理
除了文件的所有者,所属组和其他人,可以对更多的用户设置权限
CentOS 7 默认创建的 xfs 和 ext4 文件系统具有 ACL 功能
CentOS 7 之前版本,默认手工创建的 ext4 文件系统无ACL功能,需要手动增加

# 查看文件系统的属性以及挂载ACL属性功能到文件系统
tune2fs -o acl /dev/sda1
mount -o acl /dev/sda1 /mnt/test

ACL生效顺序:

所有者 , 自定义用户ACL , 所属组 | 自定义组ACL ,其他人

4.6.2 ACL 相关命令

setfacl :可以设置 ACL 权限
getfacl :可以查看设置的 ACL 权限
范例:setfacl 设置 ACL 权限 & getfacl 查看 ACL 权限

$ cp /etc/fstab a.txt
$ ls -l a.txt 
-rw-r--r--. 1 root root 709 May 12 16:46 a.txt
# 可以查看文件,但是不能追加内容
$ su zzw -c 'grep -Ev "^#|^$" /data/a.txt'
UUID=350eb3e0-4b6a-4036-a1c0-fcbcc1b58140 /                       xfs     defaults        0 0
UUID=a799f8aa-508a-4bb8-9864-0f909e03c3a0 /boot                   xfs     defaults        0 0
UUID=ebd1e734-6c68-4025-a123-7a9344acc04b /data                   xfs     defaults        0 0
UUID=0ea9011c-474c-40c1-90d1-cb012c3f0769 none                    swap    defaults        0 0

$ setfacl -m u:zzw:rw /data/a.txt
$ ls -l /data/a.txt
-rw-rw-r--+ 1 root root 709 May 12 16:46 /data/a.txt

$ getfacl /data/a.txt
getfacl: Removing leading '/' from absolute path names
# file: data/a.txt
# owner: root
# group: root
user::rw-
user:zzw:rw-
group::r--
mask::rw-
other::r--
$ su - zzw -c "echo 1122 >> /data/a.txt"
# 设置权限为空的ACL
$ setfacl -m u:xiaoming:- /data/a.txt 
$ setfacl -m u:xiaoming:0 /data/a.txt 
# 一旦设置了ACL权限(在组权限中会被ACL mask权限占用)想要查看Group组的权限需要使用getfacl查看
# ACL中 mask 权限:除了所有者和other其他人以外的人的最大权限(例如:ACL指定的用户,所属组均会受到mask的影响)

# ACL可以作用在用户组中
$ setfacl -m g:zzw:rw /data/a.txt

范例:

mount -o acl /directory
# 查看设置的 ACL 权限
getfacl file | directory
# 设置用户 wang 的 ACL 权限
setfacl -m u:wang:rwx file | directory
# 设置用户组 admins 的 ACL 权限
setfacl -m g:admins:rw file | directory
# 清除用户 wang 的 ACL 权限
setfacl -x u:wang file | directory
# 清除所有 ACL 权限
setfacl -b file1
# 复制 file1 的 acl权限给 file2
getfacl file1 | setfacl --set-file=- file2

mask 权限

  • mask 只影响除所有者和 other其他人 的之外的人和组的最大权限
  • mask 需要与用户的权限进行逻辑与运算后,才能变成有限的权限(Effetive Permission)
  • 用户或者组的设置必须存在于 mask 权限设定范围内才会生效

范例:

setfacl -m mask::rx file

范例:

## 修改mask方法
$ chmod g=r /data/a.txt
$ setfacl -m mask::r /data/a.txt

$ getfacl /data/a.txt
getfacl: Removing leading '/' from absolute path names
# file: data/a.txt
# owner: root
# group: root
user::rw-
user:zzw:rw-            #effective:r--   ## zzw用户已经超过mask权限,只能使用mask权限
user:xiaoming:---
group::r--
mask::r--
other::r--

# 删除ACL权限
$ setfacl -x u:zzw /data/a.txt
# 清空ACL权限
$ setfacl -b /data/a.txt

—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
getfacl -R /tmp/dir > acl.txt
# 消除 ACL 权限
setfacl -R -b /tmp/dir
# 还原 ACL 权限
setfacl -R --set-file=acl.txt /tmp/dir
# 还原 ACL 权限
setfacl --restore acl.txt
# 查看 ACL 权限
getfacl -R /tmp/dir

范例:备份和还原ACL

$ setfacl -m u:zzw:rw a.txt ; setfacl -m g:alice:r a.txt
$ ls -l a.txt
-rw-rw-r--+ 1 root root 714 May 12 17:18 a.txt
$ getfacl a.txt
# file: a.txt
# owner: root
# group: root
user::rw-
user:zzw:rw-
group::r--
group:alice:r--
mask::rw-
other::r--

# 当对a.txt进行备份操作。备份的文件丢失ACL权限
$ cp a.txt a.txt.bak ; ls -l a.txt.bak
-rw-r--r--. 1 root root 714 May 12 17:51 a.txt.bak
# 可以使用cp命令中的 -a 选项对文件属性完全保存
$ cp -av a.txt a.txt.all &> /dev/null ; ls -l a.txt.all
-rw-rw-r--+ 1 root root 714 May 12 17:18 a.txt.all

# 备份ACL
$ getfacl -R a.txt > a.txt.acl
$ touch a.log ; ls -l a.log
-rw-r--r--. 1 root root 0 May 12 17:55 a.log
# 还原 ACL 权限
$ setfacl --set-file=a.txt.acl a.log
$ getfacl -R a.log 
# file: a.log
# owner: root
# group: root
user::rw-
user:zzw:rw-
group::r--
group:alice:r--
mask::rw-
other::r--
$ chmod a-x `which chmod`
$ chmod a+x `which chmod`
-bash: /usr/bin/chmod: Permission denied
# 可以使用ACL临时添加执行权限
$ setfacl -m u:root:rwx /usr/bin/chmod
$ chmod a+x `which chmod`
$ ls -l `which chmod`
-rwxrwxr-x+ 1 root root 63880 Apr 27  2020 /usr/bin/chmod

4.6.4 练习:

# 1. 在/testdir/dir里创建的新文件自动属于webs组,组apps的成员如:tomcat能对这些新文件有读写权限,组dbs的成员如:mysql只能对新文件有读权限,其它用户(不属于webs,apps,dbs)不能访问这个文件夹
# 2. 备份/testdir/dir里所有文件的ACL权限到/root/acl.txt中,清除/testdir/dir中所有ACL权限,最后还原ACL权限
# 
~ for GNAME in {webs,apps,dbs}; do groupadd $GNAME; done
~ usermod -aG apps tomcat ; usermod -aG dbs mysql 
# 1. 在/testdir/dir里创建的新文件自动属于webs组,组apps的成员如:tomcat能对这些新文件有读写权限,组dbs的成员如:mysql只能对新文件有读权限,其它用户(不属于webs,apps,dbs)不能访问这个文件夹
~ mkdir -pv /testdir/dir ; chgrp webs /testdir/dir ; chmod g+s /testdir/dir
~ setfacl -m u:tomcat:rw- /testdir/dir
~ setfacl -m u:mysql:r-- /testdir/dir
~ for GNAME in {webs,apps,dbs}; do setfacl -m g:$GNAME:r-x /testdir/dir; done
~ chmod o=--- /testdir/dir
~ getfacl /testdir/dir
getfacl: Removing leading '/' from absolute path names
# file: testdir/dir
# owner: root
# group: webs
# flags: -s-
user::rwx
user:tomcat:rw-
user:mysql:r--
group::r-x
group:apps:r-x
group:webs:r-x
group:dbs:r-x
mask::rwx
other::---

# 2. 备份/testdir/dir里所有文件的ACL权限到/root/acl.txt中,清除/testdir/dir中所有ACL权限,最后还原ACL权限
~ getfacl -R /testdir/dir > /root/acl.txt
~ setfacl -bR /testdir/dir
~ setfacl --set-file=/root/acl.txt /testdir/dir
~ getfacl /testdir/dir