Linux 权限模型概述
三类主体 × 三种权限
Linux 的权限系统基于一个简洁却强大的模型:每个文件/目录都有一个所有者(owner)和所属组(group),权限被分为三个维度(所有者、所属组、其他人),每个维度各有三种权限(读 r、写 w、执行 x)。
三种权限的含义
查看权限:ls -l
# 详细列表(显示权限、所有者、大小、时间)
ls -l
ls -la # 包含隐藏文件(.开头)
ls -lh # 人类可读大小(KB/MB/GB)
ls -ln # 显示 UID/GID 数字而非用户名
# 查看特定文件的权限
ls -l /etc/passwd
ls -ld /etc # -d 查看目录本身而非目录内容
stat /etc/passwd # 显示完整的 inode 信息包括权限
# 输出示例
# -rw-r--r-- 1 root root 2847 Jan 1 10:00 /etc/passwd
# drwxr-xr-x 3 alice devs 4096 Jan 1 10:00 /home/alice
# lrwxrwxrwx 1 root root 7 Jan 1 10:00 /bin -> usr/bin
chmod:修改权限
符号模式(推荐用于理解)
# 语法:chmod [ugoa][+-=][rwx] 文件
# u=user(owner), g=group, o=others, a=all
chmod u+x script.sh # 给所有者添加执行权限
chmod g-w config.conf # 移除所属组的写权限
chmod o=r public.txt # 设置其他人权限为只读
chmod a+r announcement.txt # 所有人添加读权限
chmod u+x,g+x deploy.sh # 同时修改多个
chmod a-x somefile # 去掉所有人的执行权限
# 对目录递归修改
chmod -R 755 /var/www/html # 递归修改整个目录树
数字模式(高效简洁)
将 rwx 视为二进制位:r=4, w=2, x=1,三个数字分别表示 owner/group/others。
| 数字 | 二进制 | 权限 | 典型用途 |
|---|---|---|---|
| 7 | 111 | rwx | 目录所有者 |
| 6 | 110 | rw- | 普通文件所有者 |
| 5 | 101 | r-x | 目录组/其他人 |
| 4 | 100 | r-- | 只读文件 |
| 0 | 000 | --- | 无任何权限 |
# 常用数字权限组合
chmod 755 script.sh # rwxr-xr-x:可执行脚本
chmod 644 config.txt # rw-r--r--:普通文本文件
chmod 600 ~/.ssh/id_rsa # rw-------:私钥(严格保密)
chmod 700 ~/.ssh # rwx------:SSH 目录
chmod 777 /tmp/shared # rwxrwxrwx:所有人可读写执行(谨慎)
chmod 640 /etc/app.conf # rw-r-----:配置文件,组可读
# 查看数字权限
stat -c "%a %n" /etc/passwd # 输出: 644 /etc/passwd
stat -c "%a %n" /usr/bin/passwd # 输出: 4755(SUID 位设置)
- 可执行脚本:755(所有人可执行,只有所有者可修改)
- 普通文件:644(所有人可读,只有所有者可修改)
- 私密文件(密钥/密码):600 或 400
- Web 目录:755(需要可执行来进入目录)
- 上传目录:775(组成员可写)
chown 与 chgrp:修改所有者
# chown:修改文件所有者
chown alice file.txt # 修改所有者为 alice
chown alice:developers file.txt # 同时修改所有者和所属组
chown :developers file.txt # 只修改所属组(等同 chgrp)
chown -R www-data /var/www # 递归修改目录树
# chgrp:修改所属组
chgrp developers project/ # 修改目录所属组
chgrp -R docker /var/docker # 递归修改
# 查看当前用户信息
whoami # 当前用户名
id # uid=1000(alice) gid=1000(alice) groups=1000(alice),27(sudo),1001(docker)
id alice # 查看 alice 的 uid/gid/groups
groups # 当前用户所在的所有组
用户与组管理
用户管理命令
# 创建用户
useradd alice # 创建用户(不创建主目录)
useradd -m -s /bin/bash alice # 创建主目录,指定 shell
useradd -m -G sudo,docker alice # 加入附加组
# 设置/修改密码
passwd alice # 为 alice 设置密码(需要 root)
passwd # 修改当前用户密码
# 修改用户
usermod -aG docker alice # 将 alice 加入 docker 组(-a 追加)
usermod -s /bin/zsh alice # 修改默认 shell
usermod -l newname alice # 改用户名
# 删除用户
userdel alice # 删除用户(保留主目录)
userdel -r alice # 删除用户及其主目录
# 创建/删除组
groupadd developers
groupdel developers
# 查看用户信息文件
cat /etc/passwd # 用户信息(用户名:密码占位:UID:GID:注释:主目录:Shell)
cat /etc/group # 组信息(组名:密码:GID:成员列表)
cat /etc/shadow # 加密密码(只有 root 可读)
SUID、SGID 与 Sticky Bit
三种特殊权限位
/usr/bin/passwd——普通用户执行 passwd 命令时,进程以 root 身份运行,因此可以修改 /etc/shadow。ls -l 显示为 -rwsr-xr-x(s 替代 x)。drwxr-sr-x(s 替代 g 的 x)。drwxrwxrwt(t 替代 o 的 x)。# 查看特殊位
ls -l /usr/bin/passwd # -rwsr-xr-x(SUID)
ls -l /usr/bin/wall # -rwxr-sr-x(SGID)
ls -ld /tmp # drwxrwxrwt(Sticky Bit)
# 设置特殊位(符号方式)
chmod u+s /usr/local/bin/myapp # 设置 SUID
chmod g+s /home/team/project # 设置 SGID(目录)
chmod +t /tmp/shared # 设置 Sticky Bit
# 设置特殊位(数字方式,第4位)
chmod 4755 myapp # 4 = SUID(rwsr-xr-x)
chmod 2775 teamdir # 2 = SGID(rwxrwsr-x)
chmod 1777 /tmp # 1 = Sticky(rwxrwxrwt)
chmod 6755 special # 6 = SUID + SGID
# 查找系统中所有 SUID 文件(安全审计)
find / -perm -4000 -type f 2>/dev/null
find / -perm -2000 -type f 2>/dev/null # SGID 文件
SUID 程序以 root 身份运行,如果存在安全漏洞(缓冲区溢出、路径注入等),攻击者可以借此获得 root 权限。定期审计 SUID/SGID 文件,删除不必要的特殊位。永远不要为 Shell(bash、sh)或文本编辑器设置 SUID。
sudo:临时提权
sudo 的工作原理
sudo(Substitute User DO)允许授权用户以其他用户(通常是 root)的身份执行特定命令,而无需知道 root 密码。sudo 权限由 /etc/sudoers 文件控制。
# 基本用法
sudo command # 以 root 身份执行命令
sudo -u alice command # 以 alice 身份执行
sudo -i # 启动 root 登录 shell(获取 root 环境变量)
sudo -s # 启动 root shell(保留当前环境变量)
sudo -l # 列出当前用户可以 sudo 的命令
sudo !! # 以 sudo 重新执行上一条命令(bash 技巧)
# 常用 sudo 操作
sudo apt update
sudo systemctl restart nginx
sudo nano /etc/hosts
sudo chmod 600 /etc/ssl/private/key.pem
# 切换到 root(不推荐长期使用)
su - # 完全切换到 root(需要 root 密码)
su - alice # 切换到 alice(需要 alice 密码)
exit # 退出 su/sudo -i 会话
配置 /etc/sudoers
永远不要直接用文本编辑器编辑 /etc/sudoers,语法错误会导致所有用户(包括 root)都无法使用 sudo,造成系统锁定。使用 visudo 命令,它会在保存前验证语法。
# 使用 visudo 编辑(会进行语法检查)
visudo
visudo -f /etc/sudoers.d/alice # 编辑单独的 drop-in 文件(推荐)
# /etc/sudoers 语法格式:
# 用户/组 主机=(执行身份) 命令
# 常用配置示例
alice ALL=(ALL:ALL) ALL # alice 可以在所有主机以任意用户身份执行任意命令
%sudo ALL=(ALL:ALL) ALL # sudo 组成员(% 表示组)
%wheel ALL=(ALL) ALL # wheel 组(Red Hat 系惯例)
# 无密码 sudo(CI/CD 常用)
alice ALL=(ALL) NOPASSWD:ALL
deploy ALL=(ALL) NOPASSWD:/usr/bin/systemctl,/usr/bin/docker
# 限制只能 sudo 特定命令
bob ALL=(root) /usr/bin/apt,/usr/bin/systemctl restart nginx
# 将用户加入 sudo 组(Ubuntu)
usermod -aG sudo alice
# 将用户加入 wheel 组(CentOS/RHEL)
usermod -aG wheel alice
umask:默认权限掩码
新建文件的默认权限
umask 定义了创建新文件/目录时要去掉的权限位。系统默认权限:文件为 666(rw-rw-rw-),目录为 777(rwxrwxrwx)。用默认权限减去 umask 得到实际权限。
# 查看当前 umask
umask # 0022(八进制)
umask -S # u=rwx,g=rx,o=rx(符号形式)
# umask 计算示例:
# 文件默认 666,umask 022 → 666-022 = 644(rw-r--r--)
# 目录默认 777,umask 022 → 777-022 = 755(rwxr-xr-x)
# 临时修改 umask(当前会话有效)
umask 027 # 文件→640,目录→750(组可读,其他人无权限)
umask 077 # 文件→600,目录→700(只有所有者可访问)
# 永久修改 umask(写入配置文件)
echo "umask 022" >> ~/.bashrc # 用户级
echo "umask 022" >> /etc/profile # 系统级(需要 root)
| umask 值 | 文件权限 | 目录权限 | 适用场景 |
|---|---|---|---|
| 022 | 644(rw-r--r--) | 755(rwxr-xr-x) | 默认值,公共服务器 |
| 027 | 640(rw-r-----) | 750(rwxr-x---) | 企业服务器,增强安全 |
| 077 | 600(rw-------) | 700(rwx------) | 高安全,只有所有者访问 |
| 002 | 664(rw-rw-r--) | 775(rwxrwxr-x) | 团队协作,组内共享 |
访问控制列表(ACL)
突破三类主体限制
传统的 rwx 权限只能针对所有者、所属组、其他人三类主体设置。ACL(Access Control List)允许为特定用户或组单独设置权限,解决更复杂的权限需求。
# 安装 ACL 工具(通常已预装)
apt install acl # Debian/Ubuntu
# 查看文件的 ACL
getfacl file.txt
# 输出示例:
# file: file.txt
# owner: alice
# group: developers
# user::rw-
# user:bob:r-- ← 专门给 bob 设置的读权限
# group::r--
# mask::r--
# other::---
# 设置 ACL
setfacl -m u:bob:r-- file.txt # 给 bob 添加读权限
setfacl -m g:ops:rwx /deploy/ # 给 ops 组添加完全权限
setfacl -m u:bob:--- secret.txt # 禁止 bob 访问
setfacl -R -m u:bob:rx /var/www/ # 递归设置
# 设置默认 ACL(新建文件继承)
setfacl -d -m g:developers:rwx /project/
# 删除 ACL
setfacl -x u:bob file.txt # 删除 bob 的 ACL 条目
setfacl -b file.txt # 删除所有 ACL 条目
实战:Web 服务器权限配置
# 场景:Nginx 服务器,开发者需要上传文件,www-data 需要读取
# 1. 设置 Web 根目录所有者
chown -R www-data:www-data /var/www/html
# 2. 设置目录权限:755(进入+列出)
find /var/www/html -type d -exec chmod 755 {} \;
# 3. 设置文件权限:644(读取)
find /var/www/html -type f -exec chmod 644 {} \;
# 4. 允许 alice 上传文件(ACL 方式,不修改所有者)
setfacl -R -m u:alice:rwx /var/www/html
setfacl -d -m u:alice:rwx /var/www/html # 新建文件继承
# 5. 上传目录设置 SGID(新文件继承 www-data 组)
chmod g+s /var/www/html/uploads
# 验证设置
ls -la /var/www/html
getfacl /var/www/html
- 确认操作用户:
whoami和id - 查看文件权限:
ls -la 文件 - 查看目录链上的权限(从根到文件的每一级目录都需要 x 权限)
- 检查 ACL:
getfacl 文件 - 以 root 测试:
sudo cat 文件(确认是权限问题还是文件损坏) - SELinux/AppArmor(若启用):
getenforce,aa-status
Linux 权限系统的核心要点:① 权限分三类主体(所有者/组/其他人)× 三种权限(r/w/x),数字表示法 755/644 是最常用的设定;② 目录的 x 权限是进入的关键,没有 x 则 r 也无法使用;③ 删除文件由目录的 w 权限控制而非文件自身;④ SUID 让程序以所有者身份运行(passwd 命令的基础),SGID 让目录中新文件继承组,Sticky Bit 防止用户删除他人文件(/tmp 的保护机制);⑤ umask 控制新建文件的默认权限(022 → 文件 644,目录 755);⑥ ACL 突破三类主体限制,为特定用户精细授权;⑦ 务必用 visudo 编辑 sudoers,语法错误会锁定系统。