Linux教程 / 第 70 节

第7章:文件权限系统

理解Linux权限机制,保护代码和数据安全

本章目标

  • 理解Linux文件权限的三层结构
  • 掌握chmod、chown等权限管理命令
  • 学会使用特殊权限(SUID、SGID、Sticky Bit)
  • 能够为项目配置合理的权限策略

7.1 权限系统基础

7.1.1 权限的三个维度

Linux文件权限由三个维度组成:

-rwxr-xr--  1 user group 1234 Jan 13 10:00 script.sh
│││││││││
│││││││└┴── 其他用户权限(others): r--
││││││└┴┴── 所属组权限(group): r-x
│││└┴┴┴┴── 所有者权限(owner): rwx
││└──────── 文件类型: - (普通文件)
│└───────── 链接数
└────────── 文件类型标识

权限字符含义:

  • r (read): 读权限,数值为4
  • w (write): 写权限,数值为2
  • x (execute): 执行权限,数值为1
  • -: 无权限,数值为0

文件类型标识:

  • -: 普通文件
  • d: 目录
  • l: 符号链接
  • c: 字符设备
  • b: 块设备

7.1.2 权限对文件和目录的影响

对于文件:

  • r: 可以读取文件内容
  • w: 可以修改文件内容
  • x: 可以执行文件(脚本或程序)

对于目录:

  • r: 可以列出目录内容(ls)
  • w: 可以在目录中创建、删除文件
  • x: 可以进入目录(cd),访问目录中的文件

重要: 目录的x权限是访问其内容的前提!


7.2 查看权限

7.2.1 ls -l 详细查看

# 查看当前目录文件权限
ls -l

# 查看指定文件权限
ls -l /etc/passwd

# 查看目录本身的权限(不是内容)
ls -ld /var/log

# 以人类可读格式显示文件大小
ls -lh

实战场景: 检查项目文件权限

# 查看项目目录权限
cd ~/projects/myapp
ls -lh

# 输出示例:
# drwxr-xr-x  5 user group 4.0K Jan 13 10:00 src
# -rw-r--r--  1 user group  512 Jan 13 10:00 README.md
# -rwxr-xr-x  1 user group 2.1K Jan 13 10:00 deploy.sh

7.2.2 stat 命令详细信息

# 查看文件的详细权限信息
stat filename

# 示例输出:
#   File: deploy.sh
#   Size: 2048      Blocks: 8          IO Block: 4096   regular file
# Device: 801h/2049d    Inode: 123456      Links: 1
# Access: (0755/-rwxr-xr-x)  Uid: ( 1000/    user)   Gid: ( 1000/   group)
# Access: 2026-01-13 10:00:00.000000000 +0800
# Modify: 2026-01-13 09:30:00.000000000 +0800
# Change: 2026-01-13 09:30:00.000000000 +0800

7.3 修改权限 - chmod

7.3.1 符号模式

语法: chmod [who][operator][permission] file

who (谁):

  • u: user (所有者)
  • g: group (所属组)
  • o: others (其他用户)
  • a: all (所有人,默认)

operator (操作):

  • +: 添加权限
  • -: 移除权限
  • =: 设置权限(覆盖原有)

permission (权限):

  • r: 读
  • w: 写
  • x: 执行

基础示例:

# 给所有者添加执行权限
chmod u+x script.sh

# 移除其他用户的写权限
chmod o-w file.txt

# 给所属组添加读写权限
chmod g+rw data.log

# 给所有人添加执行权限
chmod a+x deploy.sh
# 或简写为:
chmod +x deploy.sh

# 设置所有者为读写,其他人只读
chmod u=rw,go=r config.ini

7.3.2 数字模式

权限用三位八进制数表示,每位是权限值之和:

rwx = 4 + 2 + 1 = 7
rw- = 4 + 2 + 0 = 6
r-x = 4 + 0 + 1 = 5
r-- = 4 + 0 + 0 = 4
-wx = 0 + 2 + 1 = 3
-w- = 0 + 2 + 0 = 2
--x = 0 + 0 + 1 = 1
--- = 0 + 0 + 0 = 0

常用权限组合:

# 755: rwxr-xr-x (所有者全权限,其他人读+执行)
chmod 755 script.sh

# 644: rw-r--r-- (所有者读写,其他人只读)
chmod 644 README.md

# 600: rw------- (仅所有者读写)
chmod 600 ~/.ssh/id_rsa

# 777: rwxrwxrwx (所有人全权限,不推荐!)
chmod 777 file  # ⚠️ 安全风险

# 700: rwx------ (仅所有者全权限)
chmod 700 ~/bin/private-script.sh

7.3.3 递归修改权限

# 递归修改目录及其所有内容
chmod -R 755 /var/www/html

# 只修改目录权限(使用find)
find /var/www -type d -exec chmod 755 {} \;

# 只修改文件权限
find /var/www -type f -exec chmod 644 {} \;

实战场景: 修复Web项目权限

# 场景:部署Web应用,需要正确的权限
cd /var/www/myapp

# 目录设置为755(可进入和列出)
find . -type d -exec chmod 755 {} \;

# 普通文件设置为644(可读)
find . -type f -exec chmod 644 {} \;

# 脚本文件设置为755(可执行)
chmod 755 bin/*.sh

7.4 修改所有者 - chown

7.4.1 基本用法

# 修改文件所有者
sudo chown newuser file.txt

# 修改文件所有者和组
sudo chown newuser:newgroup file.txt

# 只修改组(也可用chgrp)
sudo chown :newgroup file.txt

# 递归修改目录
sudo chown -R user:group /var/www/html

7.4.2 实战场景

场景1: 部署后修改Web目录所有者

# 将Web目录所有权交给www-data用户
sudo chown -R www-data:www-data /var/www/html

# 验证
ls -ld /var/www/html
# drwxr-xr-x 5 www-data www-data 4096 Jan 13 10:00 /var/www/html

场景2: 修复用户主目录权限

# 确保用户拥有自己的主目录
sudo chown -R username:username /home/username

# 修复SSH密钥权限
sudo chown username:username ~/.ssh
sudo chown username:username ~/.ssh/id_rsa
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_rsa

场景3: 共享项目目录

# 创建开发组
sudo groupadd developers

# 将用户添加到组
sudo usermod -aG developers alice
sudo usermod -aG developers bob

# 设置项目目录所有权
sudo chown -R :developers /opt/project

# 设置组权限
sudo chmod -R 775 /opt/project

# 设置SGID,新文件自动继承组
sudo chmod g+s /opt/project

7.5 特殊权限

7.5.1 SUID (Set User ID)

作用: 执行文件时,临时获得文件所有者的权限

标识: 所有者执行位显示为s

-rwsr-xr-x  1 root root 12345 Jan 13 10:00 /usr/bin/passwd
  SUID

设置方法:

# 符号模式
chmod u+s file

# 数字模式(4xxx)
chmod 4755 file

典型应用: /usr/bin/passwd命令

# 普通用户可以修改自己的密码
# 因为passwd有SUID,执行时临时获得root权限
ls -l /usr/bin/passwd
# -rwsr-xr-x 1 root root 59976 /usr/bin/passwd

⚠️ 安全警告: SUID是安全风险点,谨慎使用!

7.5.2 SGID (Set Group ID)

对文件: 执行时获得文件所属组权限 对目录: 在目录中创建的新文件自动继承目录的组

标识: 组执行位显示为s

drwxrwsr-x  2 user developers 4096 Jan 13 10:00 shared
     SGID

设置方法:

# 符号模式
chmod g+s directory

# 数字模式(2xxx)
chmod 2775 directory

实战场景: 团队共享目录

# 创建共享目录
sudo mkdir /opt/team-project
sudo chown :developers /opt/team-project

# 设置SGID和组写权限
sudo chmod 2775 /opt/team-project

# 现在任何developers组成员创建的文件都属于developers组
cd /opt/team-project
touch test.txt
ls -l test.txt
# -rw-r--r-- 1 alice developers 0 Jan 13 10:00 test.txt
#                    ↑
#              自动继承developers组

7.5.3 Sticky Bit

作用: 在目录上设置,只有文件所有者才能删除自己的文件

标识: 其他用户执行位显示为t

drwxrwxrwt  10 root root 4096 Jan 13 10:00 /tmp
   Sticky Bit

设置方法:

# 符号模式
chmod +t directory

# 数字模式(1xxx)
chmod 1777 directory

典型应用: /tmp目录

ls -ld /tmp
# drwxrwxrwt 10 root root 4096 Jan 13 10:00 /tmp

# 所有用户都可以在/tmp创建文件
# 但只能删除自己的文件

实战场景: 共享上传目录

# 创建上传目录
sudo mkdir /var/uploads
sudo chmod 1777 /var/uploads

# 所有用户可以上传文件
# 但不能删除别人的文件

7.5.4 特殊权限总结

权限符号数字对文件对目录
SUIDu+s4以所有者身份执行无效
SGIDg+s2以所属组身份执行新文件继承目录组
Sticky+t1无效只能删除自己的文件

组合使用:

# 同时设置SGID和Sticky Bit
chmod 3775 directory
# 3 = 2(SGID) + 1(Sticky)
# 775 = rwxrwxr-x

7.6 默认权限 - umask

7.6.1 理解umask

umask定义新建文件和目录的默认权限

计算方式:

  • 文件最大权限: 666 (rw-rw-rw-)
  • 目录最大权限: 777 (rwxrwxrwx)
  • 实际权限 = 最大权限 - umask

查看和设置:

# 查看当前umask
umask
# 0022

# 计算新建文件权限:
# 666 - 022 = 644 (rw-r--r--)

# 计算新建目录权限:
# 777 - 022 = 755 (rwxr-xr-x)

7.6.2 修改umask

# 临时修改(当前会话)
umask 0027
# 新文件: 666 - 027 = 640 (rw-r-----)
# 新目录: 777 - 027 = 750 (rwxr-x---)

# 永久修改(添加到~/.bashrc)
echo "umask 0027" >> ~/.bashrc
source ~/.bashrc

常用umask值:

  • 0022: 文件644,目录755 (默认,较宽松)
  • 0027: 文件640,目录750 (安全,组可读)
  • 0077: 文件600,目录700 (最安全,仅所有者)

实战场景: 提高安全性

# 在~/.bashrc中设置更严格的umask
echo "umask 0077" >> ~/.bashrc

# 重新加载
source ~/.bashrc

# 测试
touch test.txt
ls -l test.txt
# -rw------- 1 user user 0 Jan 13 10:00 test.txt

7.7 实战场景

场景1: 部署Node.js应用

# 1. 创建应用用户
sudo useradd -m -s /bin/bash nodeapp

# 2. 创建应用目录
sudo mkdir -p /opt/nodeapp
sudo chown nodeapp:nodeapp /opt/nodeapp

# 3. 部署代码
sudo -u nodeapp git clone https://github.com/user/app.git /opt/nodeapp

# 4. 设置权限
cd /opt/nodeapp
sudo chmod 755 .
sudo find . -type d -exec chmod 755 {} \;
sudo find . -type f -exec chmod 644 {} \;

# 5. 启动脚本可执行
sudo chmod 755 /opt/nodeapp/bin/start.sh

# 6. 日志目录
sudo mkdir /var/log/nodeapp
sudo chown nodeapp:nodeapp /var/log/nodeapp
sudo chmod 755 /var/log/nodeapp

场景2: 配置SSH密钥权限

# SSH对权限要求非常严格!

# 1. .ssh目录权限
chmod 700 ~/.ssh

# 2. 私钥权限(必须是600)
chmod 600 ~/.ssh/id_rsa

# 3. 公钥权限
chmod 644 ~/.ssh/id_rsa.pub

# 4. authorized_keys权限
chmod 600 ~/.ssh/authorized_keys

# 5. config文件权限
chmod 600 ~/.ssh/config

# 验证
ls -la ~/.ssh
# drwx------  2 user user 4096 Jan 13 10:00 .
# -rw-------  1 user user 1234 Jan 13 10:00 id_rsa
# -rw-r--r--  1 user user  567 Jan 13 10:00 id_rsa.pub
# -rw-------  1 user user  890 Jan 13 10:00 authorized_keys

场景3: Web服务器文件权限

# Nginx/Apache典型权限配置

# 1. Web根目录
sudo chown -R www-data:www-data /var/www/html
sudo find /var/www/html -type d -exec chmod 755 {} \;
sudo find /var/www/html -type f -exec chmod 644 {} \;

# 2. 上传目录(需要写权限)
sudo mkdir /var/www/html/uploads
sudo chown www-data:www-data /var/www/html/uploads
sudo chmod 755 /var/www/html/uploads

# 3. 缓存目录
sudo mkdir /var/www/html/cache
sudo chown www-data:www-data /var/www/html/cache
sudo chmod 755 /var/www/html/cache

# 4. 配置文件(敏感信息)
sudo chmod 640 /var/www/html/config/database.php
sudo chown www-data:www-data /var/www/html/config/database.php

场景4: 团队开发项目权限

# 多人协作项目的权限配置

# 1. 创建开发组
sudo groupadd devteam

# 2. 添加成员
sudo usermod -aG devteam alice
sudo usermod -aG devteam bob
sudo usermod -aG devteam charlie

# 3. 创建项目目录
sudo mkdir /opt/team-project
sudo chown :devteam /opt/team-project

# 4. 设置SGID(新文件自动继承组)
sudo chmod 2775 /opt/team-project

# 5. 设置ACL(更细粒度控制)
sudo setfacl -R -m g:devteam:rwx /opt/team-project
sudo setfacl -R -d -m g:devteam:rwx /opt/team-project

# 6. 验证
ls -ld /opt/team-project
# drwxrwsr-x+ 2 root devteam 4096 Jan 13 10:00 /opt/team-project
#       ↑                                        ↑
#      SGID                                     ACL

场景5: 修复权限问题

# 常见权限问题诊断和修复

# 问题1: "Permission denied"执行脚本
# 解决:
chmod +x script.sh

# 问题2: 无法进入目录
# 解决:
chmod +x directory

# 问题3: 无法创建文件
# 检查目录写权限:
ls -ld directory
# 解决:
chmod u+w directory

# 问题4: SSH登录失败
# 修复SSH权限:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_rsa
chmod 644 ~/.ssh/id_rsa.pub
chmod 600 ~/.ssh/authorized_keys

# 问题5: Web服务器403错误
# 修复Web目录权限:
sudo chown -R www-data:www-data /var/www/html
sudo find /var/www/html -type d -exec chmod 755 {} \;
sudo find /var/www/html -type f -exec chmod 644 {} \;

7.8 高级主题 - ACL

7.8.1 什么是ACL

ACL (Access Control List) 提供比传统权限更细粒度的控制

安装ACL工具:

# Ubuntu/Debian
sudo apt-get install acl

# CentOS/RHEL
sudo yum install acl

7.8.2 基本ACL操作

# 查看ACL
getfacl file.txt

# 设置ACL(给特定用户权限)
setfacl -m u:alice:rw file.txt

# 设置ACL(给特定组权限)
setfacl -m g:developers:rwx directory

# 删除ACL
setfacl -x u:alice file.txt

# 删除所有ACL
setfacl -b file.txt

# 递归设置ACL
setfacl -R -m u:alice:rw directory

# 设置默认ACL(新文件继承)
setfacl -d -m u:alice:rw directory

实战示例:

# 允许alice读写项目文件,但不改变所有者
cd /opt/project
sudo setfacl -R -m u:alice:rw .
sudo setfacl -R -d -m u:alice:rw .

# 验证
getfacl file.txt
# # file: file.txt
# # owner: root
# # group: root
# user::rw-
# user:alice:rw-
# group::r--
# mask::rw-
# other::r--

7.9 权限安全最佳实践

7.9.1 最小权限原则

# ❌ 不要这样做
chmod 777 file  # 给所有人全部权限

# ✅ 应该这样做
chmod 644 file  # 只给必要的权限

7.9.2 敏感文件保护

# 配置文件(包含密码)
chmod 600 config/database.yml

# SSH私钥
chmod 600 ~/.ssh/id_rsa

# SSL证书私钥
sudo chmod 600 /etc/ssl/private/server.key
sudo chown root:root /etc/ssl/private/server.key

7.9.3 定期审计权限

# 查找所有777权限的文件(安全风险)
find / -type f -perm 0777 2>/dev/null

# 查找所有SUID文件
find / -type f -perm -4000 2>/dev/null

# 查找所有SGID文件
find / -type f -perm -2000 2>/dev/null

# 查找所有可写的配置文件
find /etc -type f -perm -002 2>/dev/null

7.9.4 权限检查清单

部署前检查:

  • 配置文件权限是否为600或640
  • 日志目录是否可写
  • 脚本文件是否有执行权限
  • 上传目录权限是否合理
  • SSH密钥权限是否正确
  • 是否有不必要的777权限

7.10 常见问题

Q1: chmod和chown有什么区别?

A:

  • chmod: 修改权限(读、写、执行)
  • chown: 修改所有者和组

Q2: 为什么SSH登录总是失败?

A: 检查SSH相关文件权限:

chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_rsa
chmod 600 ~/.ssh/authorized_keys

Q3: 如何让多个用户共享目录?

A: 使用组权限+SGID:

sudo groupadd shared
sudo usermod -aG shared user1
sudo usermod -aG shared user2
sudo chown :shared /opt/shared
sudo chmod 2775 /opt/shared

Q4: 755和644分别用在什么场景?

A:

  • 755: 目录、可执行脚本
  • 644: 普通文件(代码、文档)

Q5: 如何批量修改权限?

A:

# 只修改目录
find . -type d -exec chmod 755 {} \;

# 只修改文件
find . -type f -exec chmod 644 {} \;

本章总结

核心命令回顾

命令用途示例
ls -l查看权限ls -l file.txt
chmod修改权限chmod 755 script.sh
chown修改所有者sudo chown user:group file
umask设置默认权限umask 0022
getfacl查看ACLgetfacl file.txt
setfacl设置ACLsetfacl -m u:alice:rw file

权限数字速记

7 = rwx (读+写+执行)
6 = rw- (读+写)
5 = r-x (读+执行)
4 = r-- (只读)
0 = --- (无权限)

常用权限组合

755  # 目录、脚本
644  # 普通文件
600  # 敏感配置
700  # 私有目录

下一步

  • 学习用户和进程管理(第8章)
  • 了解如何管理系统用户
  • 掌握进程监控和控制

练习题:

  1. 创建一个脚本文件,设置为只有所有者可以执行
  2. 创建一个团队共享目录,使用SGID
  3. 修复SSH密钥的权限问题
  4. 使用ACL给特定用户访问权限

参考答案:

# 1.
touch my-script.sh
chmod 700 my-script.sh

# 2.
sudo mkdir /opt/team
sudo groupadd team
sudo chown :team /opt/team
sudo chmod 2775 /opt/team

# 3.
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_rsa

# 4.
setfacl -m u:alice:rw file.txt

💡 提示: 权限管理是Linux安全的基础,务必理解每个权限位的含义!