# Linux 文件权限

URL: https://caijiao.org/linux/file-system/permissions
Source: docs/linux/file-system/permissions.md
Description: 全面介绍Linux文件权限系统，包括UGO权限模型、特殊权限、ACL访问控制列表以及权限管理的最佳实践。

Linux 文件权限系统是保障系统安全的核心机制之一，它控制着用户对文件和目录的访问权限。了解和正确管理文件权限对于系统安全性和用户数据保护至关重要。

## 文件权限基础

### 权限模型概述
Linux 使用基于用户（User）、组（Group）和其他用户（Other）的 UGO 权限模型。每个文件和目录都有三组权限：

- **用户权限（u）**：文件所有者的权限
- **组权限（g）**：文件所属组的权限
- **其他用户权限（o）**：系统中其他用户的权限

### 权限表示方法

#### 符号表示法
使用字符表示权限：
- `r`：读权限
- `w`：写权限
- `x`：执行权限
- `-`：无权限

例如：`rwxr-xr--` 表示所有者有读写执行权限，组成员有读执行权限，其他用户只有读权限。

#### 数字表示法
使用八进制数字表示权限：
- `4`：读权限（2²）
- `2`：写权限（2¹）
- `1`：执行权限（2⁰）
- `0`：无权限

权限值为各权限值之和：
- `7`：读+写+执行（4+2+1）
- `6`：读+写（4+2）
- `5`：读+执行（4+1）
- `3`：写+执行（2+1）
- `其他组合类似`

例如：`754` 表示 `rwxr-xr--`

## 查看文件权限

### 使用 `ls -l` 命令

```bash
ls -l filename
```

输出格式：
```
-rwxr-xr-- 1 user group 1024 Feb 10 14:30 filename
```

各字段含义：
1. 权限字符串（10个字符）
2. 硬链接数
3. 文件所有者
4. 文件所属组
5. 文件大小（字节）
6. 最后修改时间
7. 文件名

### 使用 `stat` 命令

```bash
stat filename
```

提供更详细的文件信息，包括 inode 信息、权限、时间戳等。

## 修改文件权限

### 使用 `chmod` 命令

#### 符号模式

```bash
# 为所有者添加执行权限
chmod u+x filename

# 为组成员移除写权限
chmod g-w filename

# 为所有用户添加读权限
chmod a+r filename

# 设置特定权限组合
chmod u=rw,g=r,o=r filename
```

符号模式语法：`[who][operator][permissions]`
- **who**: `u`（用户）、`g`（组）、`o`（其他）、`a`（全部）
- **operator**: `+`（添加）、`-`（移除）、`=`（设置）
- **permissions**: `r`、`w`、`x`

#### 数字模式

```bash
# 设置权限为 rwxr-xr--
chmod 754 filename

# 设置权限为 rw-r--r--
chmod 644 filename

# 设置权限为 rwx------
chmod 700 filename
```

#### 递归修改目录权限

```bash
# 递归修改目录及其内容的权限
chmod -R 755 directory
```

### 特殊权限

#### Set User ID (SUID)
当设置了 SUID 位的可执行文件被执行时，进程将拥有文件所有者的权限。

```bash
# 设置 SUID 位
chmod u+s filename
# 或使用数字 4000
chmod 4755 filename
```

常见示例：`/usr/bin/passwd`

#### Set Group ID (SGID)
当设置了 SGID 位的可执行文件被执行时，进程将拥有文件所属组的权限。在目录上设置 SGID 位，新创建的文件将继承目录的组所有权。

```bash
# 设置 SGID 位
chmod g+s filename
# 或使用数字 2000
chmod 2755 filename
```

#### Sticky Bit
在目录上设置 sticky bit，只有文件所有者、目录所有者或 root 可以删除该目录中的文件。

```bash
# 设置 sticky bit
chmod +t directory
# 或使用数字 1000
chmod 1777 directory
```

常见示例：`/tmp` 目录

## 文件所有权

### 修改文件所有者
使用 `chown` 命令修改文件所有者：

```bash
# 修改所有者
chown newowner filename

# 修改所有者和组
chown newowner:newgroup filename

# 递归修改目录及其内容的所有权
chown -R newowner:newgroup directory
```

### 修改文件所属组
使用 `chgrp` 命令修改文件所属组：

```bash
# 修改所属组
chgrp newgroup filename

# 递归修改目录及其内容的所属组
chgrp -R newgroup directory
```

## 高级权限管理

### 访问控制列表 (ACL)
ACL 提供了比基本 UGO 权限模型更细粒度的访问控制。

#### 启用 ACL 支持
确保文件系统挂载时启用了 ACL 支持：

```bash
# 修改 /etc/fstab 添加 acl 选项
/dev/sda1 / ext4 defaults,acl 0 1

# 重新挂载文件系统以应用更改
mount -o remount /
```

#### 使用 `setfacl` 设置 ACL

```bash
# 为用户设置权限
setfacl -m u:username:rwx filename

# 为组设置权限
setfacl -m g:groupname:rx filename

# 递归设置目录 ACL
setfacl -R -m u:username:rwx directory

# 设置默认 ACL（新创建的文件将继承）
setfacl -d -m u:username:rx directory
```

#### 使用 `getfacl` 查看 ACL

```bash
getfacl filename
```

### 文件属性

Linux 提供了额外的文件属性控制，通过 `chattr` 命令设置，`lsattr` 命令查看。

```bash
# 设置文件为不可变（不能删除或修改）
chattr +i filename

# 移除不可变属性
chattr -i filename

# 查看文件属性
lsattr filename
```

常用文件属性：
- `i`：不可变
- `a`：仅追加模式
- `s`：安全删除（删除时数据被零填充）
- `u`：可恢复删除

## 权限管理最佳实践

### 最小权限原则
授予用户完成任务所需的最小权限集。

### 常见文件权限设置

#### 配置文件
```bash
chmod 644 config_file  # 所有者可读写，其他可读
```

#### 可执行脚本
```bash
chmod 755 script.sh  # 所有者可读写执行，其他可读执行
```

#### 用户数据目录
```bash
chmod 700 /home/user/private  # 只有所有者可访问
```

#### 共享目录
```bash
# 设置 SGID 和适当权限
chmod 2775 shared_directory
chown :shared_group shared_directory
```

### 定期权限审计
定期检查系统中的文件权限，特别是敏感文件和目录：

```bash
# 查找具有 SUID/SGID 位的文件
find / -type f \( -perm -4000 -o -perm -2000 \) -exec ls -la {} \; 2>/dev/null

# 查找世界可写的文件
find / -type f -perm -o+w -exec ls -la {} \; 2>/dev/null

# 查找没有所有者的文件
find / -nouser -o -nogroup 2>/dev/null
```

## 权限相关命令总结

### 查看权限
- `ls -l`: 显示文件权限和详细信息
- `stat`: 显示文件的详细状态信息
- `getfacl`: 显示文件的访问控制列表
- `lsattr`: 显示文件的扩展属性

### 修改权限
- `chmod`: 修改文件权限
- `chown`: 修改文件所有者
- `chgrp`: 修改文件所属组
- `setfacl`: 设置访问控制列表
- `chattr`: 修改文件扩展属性

## 常见问题与解决方案

### 权限被拒绝错误

```bash
# 检查文件权限
ls -la problematic_file

# 确保有正确的权限
chmod +x executable_file  # 为可执行文件添加执行权限
chmod +r readable_file    # 添加读权限
```

### SUID/SGID 权限丢失

```bash
# 恢复常见系统命令的 SUID/SGID 权限
chmod 4755 /usr/bin/passwd
chmod 2755 /usr/bin/wall
```

### ACL 权限不生效

```bash
# 确保文件系统已启用 ACL
tune2fs -l /dev/sda1 | grep acl

# 如果没有启用，重新挂载文件系统
mount -o remount,acl /
```

通过本教程，您应该已经掌握了 Linux 文件权限系统的基础知识和管理方法。正确设置和管理文件权限对于维护系统安全和数据完整性至关重要。在实际工作中，应当始终遵循最小权限原则，并定期审查系统权限设置。
