Linux 高级权限管理:特殊权限和ACL详解

目录

一、特殊权限深度解析

1.1 SUID(Set User ID)权限

原理说明

  • 作用:程序运行时以文件所有者的身份执行,而不是执行者身份
  • 设置位置:用户执行位(x → s)
  • 安全风险:高!需谨慎设置

设置方法

# 字符方式设置
chmod u+s filename
chmod u-s filename      # 移除SUID

# 数字方式设置(在普通权限前加4)
chmod 4755 filename     # rwsr-xr-x
chmod 755 filename       # 移除SUID,rwxr-xr-x

实际案例演示

# 查看系统已有的SUID程序
find /usr/bin -perm -4000 -ls | head -10
# 输出示例:
# 4755 /usr/bin/passwd
# 4755 /usr/bin/sudo
# 4755 /usr/bin/pkexec

# 创建测试SUID程序
echo '#!/bin/bash
echo "当前用户: $(whoami)"
echo "实际用户: $USER"
id' > /tmp/test_suid.sh
chmod +x /tmp/test_suid.sh

# 设置SUID前测试
chmod 755 /tmp/test_suid.sh
sudo -u nobody /tmp/test_suid.sh
# 输出:当前用户: nobody

# 设置SUID后测试
chmod 4755 /tmp/test_suid.sh
sudo chown root /tmp/test_suid.sh
sudo -u nobody /tmp/test_suid.sh
# 输出:当前用户: root (因为以root身份运行)

安全SUID程序示例

# 系统关键SUID程序
ls -l /usr/bin/passwd
# -rwsr-xr-x 1 root root 密码修改程序,需要修改/etc/shadow

ls -l /usr/bin/sudo  
# -rwsr-xr-x 1 root root 权限提升程序

ls -l /bin/ping
# -rwsr-xr-x 1 root root 需要原始套接字权限

# 检查危险的SUID文件
find / -perm -4000 -type f 2>/dev/null | xargs ls -l

1.2 SGID(Set Group ID)权限

原理说明

  • 文件作用:程序运行时以文件所属组的身份执行
  • 目录作用新建文件自动继承目录的所属组
  • 设置位置:组执行位(x → s)

设置方法

# 字符方式设置
chmod g+s filename      # 设置SGID
chmod g+s directory     # 对目录设置SGID
chmod g-s filename      # 移除SGID

# 数字方式设置(在普通权限前加2)
chmod 2755 directory    # drwxr-sr-x
chmod 755 directory      # 移除SGID

目录SGID实战案例

# 创建共享目录
sudo mkdir /shared
sudo groupadd developers
sudo chown :developers /shared
sudo chmod 2775 /shared    # 设置SGID

# 测试SGID效果
ls -ld /shared
# drwxr-sr-x 2 root developers 共享目录,SGID已设置

# 不同用户创建文件测试
sudo -u alice touch /shared/file_by_alice.txt
sudo -u bob touch /shared/file_by_bob.txt

# 检查文件属组(应该都是developers)
ls -l /shared/
# -rw-r--r-- 1 alice developers 文件由developers组拥有
# -rw-r--r-- 1 bob   developers 自动继承目录的组

文件SGID案例

# 查看系统SGID程序
find /usr/bin -perm -2000 -ls | head -5
# 示例:/usr/bin/wall(向所有终端发消息)

# 创建测试SGID程序
echo '#!/bin/bash
echo "运行组: $(id -gn)"
groups' > /tmp/test_sgid.sh
chmod +x /tmp/test_sgid.sh

# 设置SGID前
chmod 755 /tmp/test_sgid.sh
sudo chown :developers /tmp/test_sgid.sh
sudo -u alice /tmp/test_sgid.sh
# 运行组: alice

# 设置SGID后  
chmod 2755 /tmp/test_sgid.sh
sudo -u alice /tmp/test_sgid.sh
# 运行组: developers (以文件所属组运行)

1.3 Sticky Bit(粘滞位)权限

原理说明

  • 作用:在公共目录中,用户只能删除自己创建的文件
  • 典型应用:/tmp、/var/tmp 目录
  • 设置位置:其他用户执行位(x → t)

设置方法

# 字符方式设置
chmod +t directory      # 设置粘滞位
chmod -t directory      # 移除粘滞位

# 数字方式设置(在普通权限前加1)
chmod 1777 directory    # drwxrwxrwt
chmod 777 directory     # 移除粘滞位

粘滞位实战演示

# 查看系统粘滞位目录
ls -ld /tmp /var/tmp
# drwxrwxrwt 根临时目录,粘滞位已设置

# 创建测试目录
mkdir /tmp/test_sticky
chmod 1777 /tmp/test_sticky    # 设置粘滞位

# 测试粘滞位效果
sudo -u alice touch /tmp/test_sticky/file_alice.txt
sudo -u bob touch /tmp/test_sticky/file_bob.txt

# 尝试删除他人文件(应该失败)
sudo -u alice rm /tmp/test_sticky/file_bob.txt
# rm: 无法删除 'file_bob.txt': 不允许的操作

# 只能删除自己的文件
sudo -u alice rm /tmp/test_sticky/file_alice.txt    # 成功

特殊权限组合显示

权限组合 字符显示 说明
SUID生效 -rwsr-xr-x 用户执行位显示s
SUID未生效 -rwSr-xr-x 大写S表示无执行权限
SGID生效 drwxr-sr-x 组执行位显示s
SGID未生效 drwxr-Sr-x 大写S表示无执行权限
Sticky Bit drwxrwxrwt 其他执行位显示t
Sticky Bit未生效 drwxrwxrwT 大写T表示无执行权限

二、ACL(访问控制列表)高级权限

2.1 ACL基本概念

传统UGO权限的局限性

# 问题场景:需要给特定用户特殊权限,但不影响其他用户
# 传统方案:创建新用户组,但管理复杂
# ACL解决方案:直接为用户/组设置精确权限

ACL权限类型

  • 用户ACL:为特定用户设置权限
  • 组ACL:为特定组设置权限
  • 掩码ACL:限制最大有效权限
  • 其他ACL:默认权限、递归权限等

2.2 setfacl 命令 - 设置ACL权限

基本语法

setfacl [选项] 规则 文件/目录

常用选项

选项 说明 示例
-m 修改ACL规则 setfacl -m u:alice:rw file
-x 删除ACL规则 setfacl -x u:alice file
-b 删除所有ACL规则 setfacl -b file
-R 递归设置 setfacl -R -m u:alice:rx dir
-d 设置默认ACL setfacl -d -m u:alice:rwx dir

ACL规则格式

# 用户规则
u:用户名:权限    # setfacl -m u:alice:rwx file

# 组规则  
g:组名:权限      # setfacl -m g:developers:rx file

# 其他用户规则
o:权限          # setfacl -m o:rx file

# 掩码规则
m:权限          # setfacl -m m:rx file

2.3 getfacl 命令 - 查看ACL权限

基本语法

getfacl [选项] 文件/目录

常用选项

选项 说明
-a 显示文件ACL
-d 显示默认ACL
-R 递归显示
-p 不显示绝对路径

2.4 ACL实战案例

基础ACL设置示例

# 创建测试环境
mkdir /tmp/acl_test
touch /tmp/acl_test/shared_file.txt
echo "敏感数据" > /tmp/acl_test/confidential.txt

# 查看初始权限
getfacl /tmp/acl_test/shared_file.txt
# 输出:只有基本的UGO权限

# 为特定用户添加读写权限
setfacl -m u:alice:rw /tmp/acl_test/shared_file.txt
setfacl -m u:bob:r /tmp/acl_test/shared_file.txt

# 为特定组添加权限
setfacl -m g:developers:rw /tmp/acl_test/shared_file.txt

# 查看ACL权限
getfacl /tmp/acl_test/shared_file.txt

典型输出示例

$ getfacl /tmp/acl_test/shared_file.txt
# file: shared_file.txt
# owner: root
# group: root
user::rw-
user:alice:rw-        # ← alice的特殊权限
user:bob:r--          # ← bob的只读权限
group::r--
group:developers:rw-  # ← developers组的权限
mask::rw-
other::r--

递归ACL设置(目录继承)

# 设置目录默认ACL(新文件自动继承)
setfacl -d -m u:alice:rwx /tmp/acl_test
setfacl -d -m g:developers:rx /tmp/acl_test

# 递归设置现有文件ACL
setfacl -R -m u:alice:r /tmp/acl_test/

# 创建新文件测试继承
touch /tmp/acl_test/new_file.txt
getfacl /tmp/acl_test/new_file.txt

掩码(Mask)权限控制

# 掩码限制最大有效权限
setfacl -m u:alice:rwx /tmp/acl_test/test_mask.txt
setfacl -m m:r-x /tmp/acl_test/test_mask.txt        # 掩码限制为r-x

getfacl /tmp/acl_test/test_mask.txt
# 即使alice有rwx权限,实际只有r-x权限(受掩码限制)

2.5 ACL高级应用场景

场景1:Web服务器精细权限控制

# Web目录需要多种访问权限
chown -R www-data:www-data /var/www/example.com

# 开发者需要写权限
setfacl -R -m g:developers:rwx /var/www/example.com/app/
setfacl -d -m g:developers:rwx /var/www/example.com/app/

# 内容编辑者需要部分写权限
setfacl -R -m g:editors:rw /var/www/example.com/content/
setfacl -m g:editors:-wx /var/www/example.com/uploads/

# 只读用户组
setfacl -R -m g:readers:r-x /var/www/example.com/

# 查看最终权限
getfacl /var/www/example.com/ | head -20

场景2:多团队项目协作

# 项目目录结构
mkdir -p /projects/{frontend,backend,database,docs}

# 前端团队权限
setfacl -R -m g:frontend:rwx /projects/frontend/
setfacl -d -m g:frontend:rwx /projects/frontend/

# 后端团队权限  
setfacl -R -m g:backend:rwx /projects/backend/
setfacl -m g:backend:r-x /projects/frontend/  # 可读前端代码

# 数据库团队权限
setfacl -R -m g:dba:rwx /projects/database/
setfacl -m g:dba:r-x /projects/backend/        # 可读后端代码

# 项目经理完全权限
setfacl -R -m u:project_manager:rwx /projects/

# 清理ACL权限
setfacl -b /projects/frontend/file.txt        # 清除单个文件ACL
setfacl -Rb /projects/                        # 递归清除所有ACL

三、特殊权限与ACL的组合应用

3.1 综合权限管理策略

权限管理最佳实践

# 1. 先用基本UGO权限
chmod 755 /shared_directory
chown :team /shared_directory

# 2. 需要精细控制时使用ACL
setfacl -m u:specific_user:rwx /shared_directory
setfacl -d -m g:team:rwx /shared_directory

# 3. 特殊场景使用特殊权限
chmod 2755 /shared_directory    # SGID确保文件继承组
chmod +t /shared_directory      # 粘滞位防止误删

权限检查脚本

#!/bin/bash
# check_advanced_permissions.sh

check_permissions() {
    local target=$1
    echo "=== 检查: $target ==="

    # 基本权限
    ls -la "$target"
    echo

    # 特殊权限标识
    local perms=$(stat -c %A "$target")
    if [[ $perms == *"s"* ]] || [[ $perms == *"t"* ]]; then
        echo "⚠️  检测到特殊权限:"
        if [[ $perms == *"s"* ]]; then
            [[ $perms == *"rws"* ]] && echo "  - SUID权限已设置"
            [[ $perms == *"r-s"* ]] && echo "  - SGID权限已设置"
        fi
        [[ $perms == *"rwt"* ]] && echo "  - 粘滞位已设置"
        echo
    fi

    # ACL权限检查
    if getfacl "$target" 2>/dev/null | grep -q -v "^#"; then
        echo "📋 ACL权限设置:"
        getfacl "$target" | grep -v "^#"
    else
        echo "📋 无ACL权限设置"
    fi
    echo "────────────────────"
}

# 检查系统关键目录
check_permissions /tmp
check_permissions /usr/bin/passwd
check_permissions /var/www/html

四、安全风险与防护

4.1 特殊权限安全风险

危险的SUID/SGID程序查找

# 查找所有SUID程序
find / -perm -4000 -type f 2>/dev/null | xargs ls -l

# 查找所有SGID程序  
find / -perm -2000 -type f 2>/dev/null | xargs ls -l

# 查找世界可写文件
find / -perm -0002 -type f ! -path "/proc/*" 2>/dev/null

# 查找无属主的文件
find / -nouser -o -nogroup 2>/dev/null

安全加固脚本

#!/bin/bash
# secure_special_perms.sh

# 移除不必要的SUID权限
dangerous_suid_programs=(
    "/usr/bin/find"
    "/usr/bin/vi"
    "/usr/bin/vim"
    "/bin/cp"
    "/bin/mv"
)

for program in "${dangerous_suid_programs[@]}"; do
    if [ -f "$program" ] && [ -u "$program" ]; then
        echo "移除危险SUID权限: $program"
        chmod u-s "$program"
    fi
done

# 检查可疑的粘滞位目录(不应有粘滞位的目录)
suspicious_sticky_dirs=(
    "/home"
    "/etc"
    "/var/log"
)

for dir in "${suspicious_sticky_dirs[@]}"; do
    if [ -d "$dir" ] && [ -k "$dir" ]; then  # -k 检查粘滞位
        echo "警告: 可疑的粘滞位目录: $dir"
    fi
done

4.2 ACL权限审计

ACL权限审计脚本

#!/bin/bash
# acl_audit.sh

echo "=== ACL权限审计报告 ==="
echo "生成时间: $(date)"
echo

# 查找有ACL权限的文件
echo "1. 具有ACL权限的文件/目录:"
find / -type f -exec getfacl {} \; 2>/dev/null | grep -l ":" | xargs ls -ld 2>/dev/null | head -20

echo
echo "2. 特殊权限文件统计:"
echo "SUID文件数量: $(find / -perm -4000 -type f 2>/dev/null | wc -l)"
echo "SGID文件数量: $(find / -perm -2000 -type f 2>/dev/null | wc -l)"
echo "粘滞位目录数量: $(find / -perm -1000 -type d 2>/dev/null | wc -l)"

echo
echo "3. 世界可写文件检查:"
find / -perm -0002 -type f ! -path "/proc/*" ! -path "/sys/*" 2>/dev/null | head -10

五、综合课堂练习

练习1:特殊权限实战(20分钟)

任务:创建完整的权限测试环境

# 要求:
# 1. 创建SUID测试程序
# 2. 设置SGID共享目录
# 3. 测试粘滞位功能
# 4. 验证权限效果

参考实现

#!/bin/bash
# special_perms_lab.sh

# 创建测试环境
mkdir -p /tmp/special_perms_lab
cd /tmp/special_perms_lab

# 1. SUID测试
echo '#!/bin/bash
echo "运行用户: $(whoami)"
echo "实际用户: $USER"
echo "当前目录文件:"
ls -l 2>/dev/null | head -5' > suid_test.sh
chmod +x suid_test.sh
sudo chown root suid_test.sh
chmod 4755 suid_test.sh    # 设置SUID

# 2. SGID目录测试
mkdir shared_dir
sudo groupadd testgroup
sudo chown :testgroup shared_dir
chmod 2775 shared_dir      # 设置SGID

# 3. 粘滞位测试  
mkdir sticky_dir
chmod 1777 sticky_dir      # 设置粘滞位

# 测试验证
echo "=== 权限设置完成 ==="
ls -l

echo "=== SUID测试 ==="
./suid_test.sh

echo "=== 请手动测试以下场景: ==="
echo "1. 在shared_dir中创建文件,观察组继承"
echo "2. 在sticky_dir中测试文件删除限制"
echo "3. 验证SUID程序以root身份运行"

练习2:ACL精细权限设计(25分钟)

任务:为公司设计项目权限管理系统

# 场景:项目需要多种角色协作
# 角色:项目经理、开发员、测试员、访客
# 要求:使用ACL实现精细权限控制

参考解决方案

#!/bin/bash
# acl_project_setup.sh

# 创建项目目录结构
mkdir -p /tmp/project_{name}/{src,doc,test,build,release}

# 设置基本权限
chmod 755 /tmp/project_{name}
chown -R root:root /tmp/project_{name}

# 设置ACL权限
# 项目经理:完全权限
setfacl -R -m u:pm:rwx /tmp/project_{name}
setfacl -d -m u:pm:rwx /tmp/project_{name}

# 开发员:代码目录读写,文档只读
setfacl -R -m g:dev:rwx /tmp/project_{name}/src/
setfacl -R -m g:dev:rx /tmp/project_{name}/doc/
setfacl -d -m g:dev:rwx /tmp/project_{name}/src/

# 测试员:测试目录读写,构建目录只读
setfacl -R -m g:tester:rwx /tmp/project_{name}/test/
setfacl -R -m g:tester:rx /tmp/project_{name}/build/
setfacl -m g:tester:r-- /tmp/project_{name}/release/

# 访客:只读权限
setfacl -R -m g:guest:r-x /tmp/project_{name}/

# 创建测试文件
touch /tmp/project_{name}/src/main.c
touch /tmp/project_{name}/doc/readme.txt
touch /tmp/project_{name}/test/test_suite.txt

# 生成权限报告
echo "=== 项目ACL权限报告 ==="
getfacl /tmp/project_{name}/src/main.c
echo
getfacl /tmp/project_{name}/doc/readme.txt

练习3:权限问题排查(15分钟)

任务:诊断和修复复杂权限问题

# 场景:
# 1. 用户无法访问特定文件
# 2. SUID程序不工作
# 3. ACL权限冲突
# 4. 特殊权限异常

诊断脚本

#!/bin/bash
# permission_debug.sh

debug_permission() {
    local target=$1
    local user=$2

    echo "🔍 调试: $target (用户: $user)"
    echo "=== 基本权限 ==="
    ls -la "$target"

    echo "=== 特殊权限 ==="
    if [ -u "$target" ]; then echo "SUID: 是"; else echo "SUID: 否"; fi
    if [ -g "$target" ]; then echo "SGID: 是"; else echo "SGID: 否"; fi
    if [ -k "$target" ]; then echo "粘滞位: 是"; else echo "粘滞位: 否"; fi

    echo "=== ACL权限 ==="
    getfacl "$target" 2>/dev/null | grep -v "^#"

    echo "=== 路径权限 ==="
    namei -l "$target"

    echo "=== 测试访问 ==="
    sudo -u "$user" ls -la "$target" 2>&1 | head -2
}

# 使用示例
debug_permission "/path/to/problem" "testuser"

练习4:安全审计实战(20分钟)

任务:编写系统权限安全审计脚本

# 要求:
# 1. 检测危险的SUID/SGID程序
# 2. 检查不必要的世界可写文件
# 3. 审计ACL权限设置
# 4. 生成安全报告

安全审计脚本

#!/bin/bash
# security_audit.sh

echo "🔒 系统权限安全审计报告"
echo "生成时间: $(date)"
echo "========================================"

# 1. 危险的SUID程序检查
echo "⚠️  可疑SUID程序:"
find / -perm -4000 -type f 2>/dev/null | while read file; do
    if [[ ! $file =~ ^/(proc|sys|dev) ]]; then
        # 检查是否系统关键程序
        case $(basename "$file") in
            passwd|sudo|mount|umount|su|ping|at|chsh|chfn)
                continue ;;  # 系统必要程序
            *)
                echo "可疑: $file"
                ls -l "$file" ;;
        esac
    fi
done

# 2. 世界可写文件检查
echo
echo "🌍 世界可写文件 (前10个):"
find / -perm -0002 -type f ! -path "/proc/*" ! -path "/sys/*" 2>/dev/null | head -10

# 3. ACL权限统计
echo
echo "📋 ACL权限统计:"
acl_count=$(find / -type f -exec getfacl {} \; 2>/dev/null | grep -l ":" | wc -l 2>/dev/null)
echo "设置ACL的文件数量: $acl_count"

# 4. 粘滞位目录检查
echo
echo "📁 粘滞位目录检查:"
find /tmp /var/tmp -type d -perm -1000 2>/dev/null | while read dir; do
    if [ -k "$dir" ]; then
        echo "正常: $dir"
    else
        echo "警告: 应设置粘滞位: $dir"
    fi
done

通过本教程的深入学习,你应该能够掌握Linux高级权限管理,包括特殊权限和ACL的实战应用,并具备权限安全审计和问题排查能力。

作者:严锋  创建时间:2025-11-01 11:28
最后编辑:严锋  更新时间:2025-11-04 14:01