Linux 权限管理:用户组 + 特殊权限 + ACL 解析

用户与组管理

创建两个用户:

复制代码
useradd dev1
useradd dev2

创建组:

复制代码
groupadd project

把 dev1 和 dev2 加入 project 组。

要把 dev1dev2 加入 project 组,可以使用以下常用命令:

方法 1:使用 usermod(逐个添加)

复制代码
usermod -aG project dev1
usermod -aG project dev2
  • -a:追加(append),避免覆盖用户原有附属组
  • -G:指定附属组(supplementary group)

方法 2:使用 gpasswd(逐个添加)

复制代码
gpasswd -a dev1 project
gpasswd -a dev2 project
方法 3:使用 gpasswd 批量添加(部分系统支持)
复制代码
gpasswd -M dev1,dev2 project

验证是否添加成功:

复制代码
id dev1
id dev2
# 或
groups dev1
groups dev2

高效命令

bash 复制代码
# 先创建组,再创建两个用户,最后把用户加入组(CentOS/RHEL 系统)
groupadd project && useradd dev1 && useradd dev2 && usermod -aG project dev1 && usermod -aG project dev2

# 如果是 Debian/Ubuntu 系统,且需要给用户加 sudo 权限,可执行这个
groupadd project && useradd dev1 && useradd dev2 && usermod -aG project dev1 && usermod -aG project dev2 && usermod -aG sudo dev1 && usermod -aG sudo dev2

删除命令

基础用法(仅删除用户账号,保留家目录)
复制代码
# 删除dev1用户(仅删账号,/home/dev1目录还在)
userdel dev1
彻底删除(删除用户 + 家目录 + 邮件文件)

这是最常用的方式,避免残留文件占用空间:

复制代码
# -r 表示递归删除用户的家目录和邮件池
userdel -r dev1
注意事项(避坑关键)
  • 权限要求 :必须用 root 用户或加 sudo 执行(比如 sudo userdel -r dev1);
  • 不能删除当前登录的用户 :如果要删的用户正在登录,先执行 pkill -u 用户名 结束该用户的所有进程,再删除;
  • 删除组 :如果要删除之前创建的 project 组,用 groupdel project
  • 验证删除结果 :执行 id dev1,如果提示 id: 'dev1': no such user,说明删除成功。
如果仅删除用户,然后又想删除家目录
复制代码
# 检查家目录
ls -ld /home/dev1

# 用rm -rf递归删除家目录(-r=递归,-f=强制,无需确认)
rm -rf /home/dev1

# 检查清理结果,确认所有残留都已删除
ls -ld /home/dev1
id dev1
删除之后情况

如果只是执行了 userdel 用户名(未删家目录):用户账号可以重建(用 useradd 用户名),家目录里的文件还在,相当于 "恢复" 了用户

如果执行了 userdel -r 用户名 或手动 rm -rf /home/用户名

  • ✖️ 用户账号:系统里的用户 ID(UID)、组 ID(GID)等记录会被彻底删除,无法通过常规命令 "撤销删除";
  • ✖️ 家目录 / 文件rm -rf 是直接删除文件系统中的索引节点(inode),不会放入 "回收站",Linux 默认也没有类似 Windows 的回收站机制,普通用户几乎无法恢复

组权限控制场景

场景:

  • 目录 /data/project
  • 属主 root
  • 属组 project
  • 只有 project 组成员可以进入并写入
  • 其他人不能访问

要求:

  1. 创建目录

  2. 修改属主属组

  3. 设置权限

    1. 创建目录

    mkdir -p /data/project

    2. 修改属主属组

    chown root:project /data/project

    3. 设置权限

    chmod 770 /data/project

    4. 验证权限

    ls -ld /data/project

特殊权限

SUID 权限

1. 为什么普通用户可以修改自己的密码?

普通用户本身没有权限直接修改存储密码的 /etc/shadow 文件(该文件权限为 000,只有 root 可写)。

/usr/bin/passwd 程序设置了 SUID(Set User ID) 特殊权限位,当普通用户执行它时,会临时获得该程序属主(root)的权限,从而可以修改 /etc/shadow 中的密码记录。


2. s 出现在哪里?

在权限字符串 -rwsr-xr-x 中,s 出现在属主(user)的执行权限位 上,替代了原本的 x

  • 这表示该文件启用了 SUID 权限。
  • 当文件有执行权限 x 时,SUID 显示为 s;如果没有执行权限,SUID 会显示为 S(大写 S)。

3. 如果去掉 SUID 会发生什么?

执行 chmod u-s /usr/bin/passwd 后,passwd 程序的 SUID 权限被移除:

  • 普通用户执行 passwd 命令时,将不再获得 root 权限。
  • 尝试修改密码时,会因权限不足而失败,出现类似 passwd: Authentication token manipulation error 的错误。
  • 只有 root 用户仍能正常修改所有用户的密码。

实验完成后,务必恢复 passwd 的 SUID 权限,否则所有用户都将无法正常修改密码

恢复权限chmod u+s /usr/bin/passwd

Sticky Bit

1. t 表示什么?

t 出现在 /tmp 目录权限字符串 drwxrwxrwt其他人权限位 上,它代表 Sticky Bit(粘滞位) 权限。

  • 当目录设置了 Sticky Bit 时,只有文件 / 目录的所有者、目录所有者或 root 用户才能删除或重命名该目录下的文件。
  • 如果该目录原本对其他人有执行权限 x,Sticky Bit 显示为 t;如果没有执行权限,则显示为 T

2. 为什么 /tmp 必须设置这个权限?

/tmp 是系统的临时文件目录,所有用户都需要在这里创建、读写临时文件。

  • 如果没有 Sticky Bit,任何用户都可以删除或重命名其他用户在 /tmp 下的文件,这会导致严重的安全问题和数据混乱。
  • 设置 Sticky Bit 后,既保证了所有用户都能在 /tmp 中创建文件,又能防止用户误删或恶意删除他人文件,保障了系统的安全性和稳定性。

3. 如果没有 sticky bit 会发生什么?

如果移除 /tmp 的 Sticky Bit(执行 chmod o-t /tmp):

  • 任何拥有 /tmp 目录写权限的用户,都可以删除或重命名该目录下的任意文件,无论这些文件的所有者是谁。
  • 这会导致系统服务、应用程序和其他用户的临时文件被意外或恶意删除,引发程序崩溃、数据丢失甚至系统不稳定。
  • 因此,/tmp 目录在默认情况下都会被设置 Sticky Bit,实验后务必恢复该权限。

ACL 权限

复制代码
apt install acl

为什么需要 ACL?

传统的 Linux 文件权限模型(ugo 权限)只定义了三种角色:

  • 文件所有者(user)
  • 所属组(group)
  • 其他用户(other)

如果 test.txt 的权限是 rw-r--r--(即所有者读写,组和其他人只读),而你又想只给 dev1****用户额外的读写权限 ,同时不改变其他用户的权限,传统的 chmod 命令就无法实现了。因为:

  • 把文件所有者改成 dev1 会改变文件的归属。
  • dev1 加入文件所属组,会让组内所有用户都获得权限,而不是只针对 dev1 一人。
  • 开放 "其他用户" 的权限,会让所有人都获得权限,这不符合安全要求。

因此,需要使用 ACL 来为特定用户或组设置独立于传统权限模型之外的细粒度访问控制。

练习题

场景:

  • 文件 test.txt
  • 只给 dev1 单独添加读写权限
  • 不影响其他权限

要给 dev1 用户单独添加读写权限,使用 setfacl 命令:

bash 复制代码
setfacl -m u:dev1:rw test.txt
  • -m:修改 ACL 规则
  • u:dev1:rw:表示为用户(user)dev1 分配读(r)和写(w)权限

验证与查看

执行命令后,可以用 getfacl 查看 ACL 规则:

复制代码
getfacl test.txt

会看到类似输出,其中明确列出了为 dev1 用户设置的权限:

bash 复制代码
# file: test.txt
# owner: root
# group: root
user::rw-
user:dev1:rw-
group::r--
mask::rw-
other::r--

同时,用 ls -l 查看文件权限时,权限位后面会出现一个 + 号,表示该文件启用了 ACL:

ACL 权限常见命令

一、安装 ACL 工具

bash 复制代码
# Debian/Ubuntu
apt install -y acl

# CentOS/RHEL
yum install -y acl
# 或
dnf install -y acl

二、核心操作:setfacl

1. 为特定用户设置权限
bash 复制代码
# 给用户 dev1 对 test.txt 增加读写权限
setfacl -m u:dev1:rw test.txt

# 给用户 dev2 对 /data 目录(递归)增加读写执行权限
setfacl -R -m u:dev2:rwx /data
2. 为特定组设置权限
bash 复制代码
# 给组 project 对 test.txt 增加读写权限
setfacl -m g:project:rw test.txt

# 给组 project 对 /data 目录(递归)增加读写执行权限
setfacl -R -m g:project:rwx /data
3. 设置默认 ACL(新文件自动继承)
bash 复制代码
# 让 /data 目录下新建的文件/目录,自动给 dev1 用户 rw- 权限
setfacl -m d:u:dev1:rw- /data

# 让 /data 目录下新建的文件/目录,自动给 project 组 rwx 权限
setfacl -m d:g:project:rwx /data
4. 删除 ACL 规则
bash 复制代码
# 删除用户 dev1 的 ACL 规则
setfacl -x u:dev1 test.txt

# 删除组 project 的 ACL 规则
setfacl -x g:project test.txt

# 删除所有 ACL 规则(恢复到传统权限)
setfacl -b test.txt

三、查看 ACL:getfacl

bash 复制代码
# 查看文件/目录的 ACL 规则
getfacl test.txt

# 查看目录及其下所有内容的 ACL(递归)
getfacl -R /data

典型输出示例:

bash 复制代码
# file: test.txt
# owner: root
# group: root
user::rw-
user:dev1:rw-
group::r--
mask::rw-
other::r--

四、常见场景示例

|-------------------------------|---------------------------------|
| 场景 | 命令 |
| 只给 dev1 读写权限,不影响其他 | setfacl -m u:dev1:rw test.txt |
| 让 /data 下所有新文件自动给 dev1 读权限 | setfacl -m d:u:dev1:r-- /data |
| 撤销 dev1 对 test.txt 的所有 ACL 权限 | setfacl -x u:dev1 test.txt |
| 完全清除 test.txt 的所有 ACL | setfacl -b test.txt |

常见问题

755 和 775 区别?

755 → rwxr-xr-x

775 → rwxrwxr-x

实际场景区别

755 是"个人可写",775 是"团队可写"

755 适合:
  • 网站程序目录
  • 系统目录
  • 只允许属主修改
775 适合:
  • 开发团队共享目录
  • 需要组协作写入

为什么目录必须有 x 才能进入?

这是权限模型的关键理解点。

目录的 x ≠ 执行程序

目录的 x = "是否允许穿越目录"

目录权限含义

|----|-------------|
| 权限 | 含义 |
| r | 能否列出文件名(ls) |
| w | 能否创建删除文件 |
| x | 能否进入目录(cd) |

umask 022 表示什么?

umask(权限掩码)是 Linux 中新建文件 / 目录时默认权限的 "扣除规则" ,核心作用是:默认权限 = 最大权限 - umask 值

默认权限规则

|----|------|
| 类型 | 最大权限 |
| 文件 | 666 |
| 目录 | 777 |

然后减去 umask。

先明确 "最大权限":
  • 新建文件的最大默认权限:666(rw-rw-rw-)------ 文件默认没有 x 权限(防止恶意脚本自动执行);
  • 新建目录的最大默认权限:777(rwxrwxrwx)------ 目录需要 x 权限才能进入,所以默认开放。
umask 022 的计算逻辑:

022 是八进制数,对应权限位:0(所有者)- 2(所属组)- 2(其他人)(八进制 2 = 二进制 010,对应 w 权限)。

  • 新建文件的默认权限666 - 022 = 644(rw-r--r--);
  • 新建目录的默认权限777 - 022 = 755(rwxr-xr-x)。
直观解释:

umask 022 表示:

  • 文件所有者:不扣除任何权限(保留 rw);
  • 所属组:扣除写(w)权限(只保留 r、x);
  • 其他人:扣除写(w)权限(只保留 r、x)。
检验
bash 复制代码
# 查看当前 umask 值
umask  # 输出 0022(前两位 00 是特殊权限位,核心看后三位 022)

# 新建文件,查看权限(应为 644)
touch testfile
ls -l testfile  # 输出 -rw-r--r-- ... testfile

# 新建目录,查看权限(应为 755)
mkdir testdir
ls -ld testdir  # 输出 drwxr-xr-x ... testdir

文件默认权限为什么不是 777?

原因有三个层面:

1、 安全模型

777 表示:

  • 任何人都可以写
  • 任何人都可以执行

这意味着:

  • 任意用户可篡改文件
  • 恶意代码可执行
  • 权限边界失效

属于严重安全漏洞。

2、 最小权限原则(Principle of Least Privilege)

Linux 遵循:只给必要权限

默认文件没有 x 权限,是因为: 文件不一定是程序


3、 文件默认不能带执行权限

Linux 不能自动判断:

  • 这是脚本?
  • 这是二进制?
  • 还是普通文本?

因此默认不给执行权限。

你必须显式:chmod +x file.sh

什么时候用 ACL,而不是 chmod?

chmod 的局限

传统权限模型:

复制代码
属主
属组
其他人

只有三类,无法满足:给某一个特定用户单独授权,给多个不同用户不同权限。

ACL 适用场景
场景 1:临时给某人访问权限

比如:文件属于 root,组是 dev,但临时需要给 userA 写权限

如果不用 ACL:只能改属组,或改属主,或放开其他人权限

都会影响整体安全结构。

场景 2:复杂权限矩阵

例如:

|-------|----|
| 用户 | 权限 |
| dev1 | rw |
| dev2 | r |
| test1 | rw |
| 其他 | 无 |

chmod 做不到。ACL 可以:

复制代码
setfacl -m u:dev1:rw file
setfacl -m u:dev2:r file

企业判断标准

|----------|--------------|
| 情况 | 用什么 |
| 简单三层模型 | chmod |
| 多用户细粒度控制 | ACL |
| 临时授权 | ACL |
| 共享协作目录 | SGID + chmod |
| 大规模统一管理 | 组 + chmod |

相关推荐
2501_907136822 小时前
手搓仓库管理系统Senbar-1.0.4(附带财务管理板块)
运维·服务器·软件需求
盟接之桥3 小时前
盟接之桥EDI软件:API数据采集模块深度解析,打造企业数据协同新引擎
java·运维·服务器·网络·数据库·人工智能·制造
2501_907136823 小时前
离线工具箱 内含53个小工具
linux·服务器·网络
时空潮汐4 小时前
神卓N600 NAS身份核验功能深度解析
linux·运维·网络·神卓nas·神卓n600 pro·家庭轻nas
哈哈浩丶4 小时前
安卓系统全流程启动
android·linux·驱动开发
小李独爱秋4 小时前
模拟面试:用自己的话解释一下lvs的工作原理
linux·运维·面试·职场和发展·操作系统·lvs
百锦再4 小时前
Jenkins 全面精通指南:从入门到脚本大师
运维·后端·python·servlet·django·flask·jenkins
隔壁老王的代码4 小时前
Jenkins的流水线详解
运维·servlet·jenkins
一路往蓝-Anbo4 小时前
第 7 章:内存地图 (Memory Map) 深度设计——DDR 与 SRAM
linux·stm32·单片机·嵌入式硬件·网络协议