第33集:特殊权限设置
教学目标
- 理解Linux系统中特殊权限的基本概念和作用
- 掌握SUID权限的设置方法和使用场景
- 掌握SGID权限的设置方法和使用场景
- 掌握Sticky Bit的设置方法和使用场景
- 理解特殊权限的安全考虑和潜在风险
- 能够根据实际需求正确设置和管理特殊权限
- 掌握特殊权限的审计和监控方法
核心知识点讲解
1. 特殊权限概述
Linux系统除了基本的读、写、执行权限外,还提供了三种特殊权限:SUID(Set User ID)、SGID(Set Group ID)和Sticky Bit。这些特殊权限为系统管理和应用程序运行提供了额外的灵活性和安全性。
2. SUID(Set User ID)权限
作用
- 当设置了SUID权限的可执行文件被执行时,进程的有效用户ID(EUID)会被设置为文件所有者的用户ID,而不是执行该文件的用户的ID
- 这允许普通用户以文件所有者的权限执行特定命令,而不需要知道文件所有者的密码
表示方法
- 符号表示法:
u+s - 数字表示法:在权限数字前添加4,如4755
- 权限位显示:在所有者执行权限位显示为
s(如果原执行权限已设置)或S(如果原执行权限未设置)
典型应用场景
passwd命令:允许普通用户修改自己的密码,需要写入/etc/shadow文件的权限sudo命令:允许授权用户以其他用户身份执行命令- 其他需要临时提升权限的系统命令
安全考虑
- 潜在风险:如果设置了SUID权限的程序存在安全漏洞,攻击者可能会利用它获取文件所有者的权限
- 最小权限原则:只对必要的程序设置SUID权限
- 定期审计:定期检查系统中设置了SUID权限的文件
3. SGID(Set Group ID)权限
作用
- 对于可执行文件:当执行设置了SGID权限的文件时,进程的有效组ID(EGID)会被设置为文件所属组的ID
- 对于目录:当在设置了SGID权限的目录中创建新文件时,新文件的所属组会继承目录的所属组,而不是创建者的主组
表示方法
- 符号表示法:
g+s - 数字表示法:在权限数字前添加2,如2755
- 权限位显示:在所属组执行权限位显示为
s(如果原执行权限已设置)或S(如果原执行权限未设置)
典型应用场景
- 目录共享:在团队共享目录中,确保所有新创建的文件都属于同一个组
- 权限继承:确保特定目录下的文件保持一致的组所有权
- 特定权限的程序:需要以特定组权限运行的程序
安全考虑
- 目录权限管理:确保设置了SGID的目录权限适当,防止未授权访问
- 文件权限继承:注意SGID对目录中所有新文件的影响
4. Sticky Bit权限
作用
- 对于目录:当目录设置了Sticky Bit权限时,只有文件的所有者、目录的所有者或root用户可以删除或重命名该目录中的文件
- 对于可执行文件:在传统Unix系统中,Sticky Bit会使程序在执行后保持在内存中,但在现代Linux系统中,这个功能已经被内存管理系统替代
表示方法
- 符号表示法:
o+t - 数字表示法:在权限数字前添加1,如1777
- 权限位显示:在其他用户执行权限位显示为
t(如果原执行权限已设置)或T(如果原执行权限未设置)
典型应用场景
/tmp目录:允许所有用户创建文件,但只能删除自己的文件- 公共共享目录:允许多用户访问,但防止用户删除其他用户的文件
安全考虑
- 目录权限:通常与777权限配合使用,如1777
- 文件保护:确保用户只能管理自己的文件
5. 特殊权限的设置方法
使用符号表示法设置特殊权限
- 设置SUID:
chmod u+s file - 设置SGID:
chmod g+s file或chmod g+s directory - 设置Sticky Bit:
chmod o+t directory
使用数字表示法设置特殊权限
- 设置SUID:
chmod 4755 file - 设置SGID:
chmod 2755 file或chmod 2755 directory - 设置Sticky Bit:
chmod 1777 directory
移除特殊权限
- 移除SUID:
chmod u-s file - 移除SGID:
chmod g-s file或chmod g-s directory - 移除Sticky Bit:
chmod o-t directory
6. 特殊权限的安全考虑
潜在风险
- SUID风险:如果设置了SUID权限的程序存在缓冲区溢出或其他安全漏洞,攻击者可能会获取文件所有者的权限(通常是root)
- SGID风险:如果设置了SGID权限的目录权限过于宽松,可能会导致未授权用户获取敏感文件的访问权限
- Sticky Bit风险:如果设置了Sticky Bit的目录同时设置了777权限,可能会被用于存储恶意文件
安全最佳实践
- 最小权限原则:只对必要的文件和目录设置特殊权限
- 定期审计:定期检查系统中设置了特殊权限的文件和目录
- 权限限制:对于设置了特殊权限的文件,确保其权限尽可能严格
- 文件完整性监控:监控设置了特殊权限的文件的完整性,防止被篡改
- 使用sudo替代:对于许多场景,使用sudo命令可能比设置SUID权限更安全
7. 特殊权限的审计和监控
查找系统中设置了特殊权限的文件
- 查找SUID文件:
find / -type f -perm -4000 -ls 2>/dev/null - 查找SGID文件:
find / -type f -perm -2000 -ls 2>/dev/null - 查找设置了Sticky Bit的目录:
find / -type d -perm -1000 -ls 2>/dev/null
监控特殊权限的变更
- 使用文件完整性监控工具(如AIDE、Tripwire)监控设置了特殊权限的文件
- 使用系统审计工具(如auditd)记录特殊权限的变更
8. 特殊权限的实际应用
SUID的实际应用
- passwd命令:允许普通用户修改自己的密码
- sudo命令:允许授权用户以其他用户身份执行命令
- mount/umount命令:允许特定用户挂载和卸载文件系统
SGID的实际应用
- 共享目录:团队项目共享目录,确保所有新文件都属于同一个组
- 邮件目录:确保邮件文件的组所有权正确
- 数据库目录:确保数据库文件的组所有权一致
Sticky Bit的实际应用
- /tmp目录:系统临时目录,允许所有用户使用,但防止删除其他用户的文件
- 公共下载目录:允许用户上传和下载文件,但防止删除其他用户的文件
- 打印队列目录:管理打印作业,防止用户删除其他用户的打印作业
9. 特殊权限与普通权限的关系
- 特殊权限是对普通权限的补充,而不是替代
- 设置特殊权限时,通常需要保留适当的普通权限
- 特殊权限的效果取决于文件类型(可执行文件或目录)和普通权限的设置
10. 特殊权限的注意事项
- SUID只对可执行文件有效:对非可执行文件设置SUID权限没有实际效果
- SGID对目录的影响:在设置了SGID的目录中创建的文件会继承目录的所属组
- Sticky Bit主要对目录有效:对文件设置Sticky Bit在现代Linux系统中没有实际效果
- 权限位显示:大写的S或T表示特殊权限已设置,但对应的执行权限未设置
操作示例
示例1:SUID权限的设置和使用
# 查看passwd命令的权限(默认设置了SUID)
ls -l /usr/bin/passwd
# 创建一个测试程序,展示SUID的效果
cat > test_suid.c << 'EOF'
#include <stdio.h>
#include <unistd.h>
int main() {
printf("Real UID: %d\n", getuid());
printf("Effective UID: %d\n", geteuid());
return 0;
}
EOF
# 编译程序
gcc test_suid.c -o test_suid
# 查看初始权限
ls -l test_suid
# 运行程序(无SUID)
./test_suid
# 设置SUID权限
chmod u+s test_suid
# 查看权限变化
ls -l test_suid
# 再次运行程序(有SUID)
./test_suid
# 切换到普通用户测试
# su - testuser
# ./test_suid
# exit
# 移除SUID权限
chmod u-s test_suid
ls -l test_suid
# 清理测试文件
rm test_suid test_suid.c示例2:SGID权限的设置和使用
# 示例2.1:对可执行文件设置SGID
# 创建测试程序
cat > test_sgid.c << 'EOF'
#include <stdio.h>
#include <unistd.h>
int main() {
printf("Real GID: %d\n", getgid());
printf("Effective GID: %d\n", getegid());
return 0;
}
EOF
# 编译程序
gcc test_sgid.c -o test_sgid
# 创建一个测试组
groupadd testgroup
# 修改文件所属组
chown :testgroup test_sgid
# 查看初始权限
ls -l test_sgid
# 运行程序(无SGID)
./test_sgid
# 设置SGID权限
chmod g+s test_sgid
# 查看权限变化
ls -l test_sgid
# 再次运行程序(有SGID)
./test_sgid
# 移除SGID权限
chmod g-s test_sgid
# 示例2.2:对目录设置SGID
# 创建测试目录
mkdir test_sgid_dir
# 修改目录所属组
chown :testgroup test_sgid_dir
# 设置SGID权限
chmod g+s test_sgid_dir
ls -ld test_sgid_dir
# 在目录中创建文件
cd test_sgid_dir
touch test_file.txt
ls -l test_file.txt # 查看文件所属组,应该继承目录的所属组
cd ..
# 清理测试文件和目录
rm -rf test_sgid test_sgid.c test_sgid_dir
groupdel testgroup示例3:Sticky Bit的设置和使用
# 查看/tmp目录的权限(默认设置了Sticky Bit)
ls -ld /tmp
# 创建测试目录
mkdir test_sticky_dir
# 设置777权限
chmod 777 test_sticky_dir
ls -ld test_sticky_dir
# 设置Sticky Bit
chmod +t test_sticky_dir
ls -ld test_sticky_dir
# 测试Sticky Bit的效果
# 以用户A身份创建文件
touch test_sticky_dir/file_by_userA
ls -l test_sticky_dir/file_by_userA
# 尝试以用户B身份删除用户A的文件
# su - userB
# rm test_sticky_dir/file_by_userA # 应该失败
# exit
# 移除Sticky Bit
chmod -t test_sticky_dir
ls -ld test_sticky_dir
# 清理测试目录
rm -rf test_sticky_dir示例4:特殊权限的组合使用
# 创建一个需要特殊权限的目录结构
mkdir -p /tmp/special_dir
# 设置SGID和Sticky Bit
chmod 3777 /tmp/special_dir # 3=2+1,同时设置SGID和Sticky Bit
ls -ld /tmp/special_dir
# 查看权限位含义
# rwxrwsrwt: 所有者rwx,所属组rwx+s,其他用户rwx+t
# 测试目录功能
cd /tmp/special_dir
touch test_file
ls -l test_file
cd ..
# 清理测试目录
rm -rf /tmp/special_dir示例5:特殊权限的审计
# 查找系统中所有设置了SUID权限的文件
find / -type f -perm -4000 -ls 2>/dev/null
# 查找系统中所有设置了SGID权限的文件
find / -type f -perm -2000 -ls 2>/dev/null
# 查找系统中所有设置了Sticky Bit的目录
find / -type d -perm -1000 -ls 2>/dev/null
# 查找系统中所有设置了特殊权限的文件和目录
find / -type f -perm /6000 -o -type d -perm /1000 -ls 2>/dev/null
# 检查可疑的SUID文件(不在标准位置的SUID文件)
find / -type f -perm -4000 -not -path "/usr/*" -not -path "/bin/*" -not -path "/sbin/*" -ls 2>/dev/null示例6:特殊权限的安全加固
# 检查并修复不必要的SUID权限
# 1. 列出所有SUID文件
find / -type f -perm -4000 -ls 2>/dev/null > suid_files.txt
# 2. 检查每个SUID文件的必要性,移除不必要的SUID权限
# 例如:移除games目录下文件的SUID权限
find /usr/games -type f -perm -4000 -exec chmod u-s {} \; 2>/dev/null
# 3. 验证权限变更
find /usr/games -type f -perm -4000 -ls 2>/dev/null
# 检查并修复过于宽松的SGID目录
find / -type d -perm -2000 -perm -002 -ls 2>/dev/null
# 修复/tmp目录权限(确保设置了Sticky Bit)
chmod 1777 /tmp
ls -ld /tmp示例7:特殊权限的脚本管理
# 创建特殊权限管理脚本
cat > special_perm_manager.sh << 'EOF'
#!/bin/bash
# 显示菜单
echo "特殊权限管理脚本"
echo "1. 列出系统中的SUID文件"
echo "2. 列出系统中的SGID文件"
echo "3. 列出系统中的Sticky Bit目录"
echo "4. 设置文件SUID权限"
echo "5. 设置文件SGID权限"
echo "6. 设置目录Sticky Bit"
echo "7. 移除文件SUID权限"
echo "8. 移除文件SGID权限"
echo "9. 移除目录Sticky Bit"
echo "10. 退出"
read -p "请选择操作:" choice
case $choice in
1)
echo "系统中的SUID文件:"
find / -type f -perm -4000 -ls 2>/dev/null
;;
2)
echo "系统中的SGID文件:"
find / -type f -perm -2000 -ls 2>/dev/null
;;
3)
echo "系统中的Sticky Bit目录:"
find / -type d -perm -1000 -ls 2>/dev/null
;;
4)
read -p "请输入文件路径:" path
if [ -f "$path" ]; then
chmod u+s "$path"
echo "已设置SUID权限"
ls -l "$path"
else
echo "错误:路径不存在或不是文件"
fi
;;
5)
read -p "请输入文件或目录路径:" path
if [ -e "$path" ]; then
chmod g+s "$path"
echo "已设置SGID权限"
ls -l "$path"
else
echo "错误:路径不存在"
fi
;;
6)
read -p "请输入目录路径:" path
if [ -d "$path" ]; then
chmod +t "$path"
echo "已设置Sticky Bit"
ls -ld "$path"
else
echo "错误:路径不存在或不是目录"
fi
;;
7)
read -p "请输入文件路径:" path
if [ -f "$path" ]; then
chmod u-s "$path"
echo "已移除SUID权限"
ls -l "$path"
else
echo "错误:路径不存在或不是文件"
fi
;;
8)
read -p "请输入文件或目录路径:" path
if [ -e "$path" ]; then
chmod g-s "$path"
echo "已移除SGID权限"
ls -l "$path"
else
echo "错误:路径不存在"
fi
;;
9)
read -p "请输入目录路径:" path
if [ -d "$path" ]; then
chmod -t "$path"
echo "已移除Sticky Bit"
ls -ld "$path"
else
echo "错误:路径不存在或不是目录"
fi
;;
10)
echo "退出脚本"
exit 0
;;
*)
echo "无效的选择"
;;
esac
EOF
# 使脚本可执行
chmod +x special_perm_manager.sh
# 运行脚本
./special_perm_manager.sh示例8:SUID与sudo的对比
# 示例:使用sudo替代SUID
# 1. 传统方法:使用SUID权限
# 创建一个需要root权限的脚本
cat > system_check.sh << 'EOF'
#!/bin/bash
echo "系统检查开始..."
df -h
free -m
uptime
echo "系统检查完成"
EOF
# 使脚本可执行
chmod +x system_check.sh
# 设置SUID权限(需要root权限)
# chown root:root system_check.sh
# chmod u+s system_check.sh
# ls -l system_check.sh
# 2. 现代方法:使用sudo
# 编辑sudoers文件
# visudo
# 添加以下行:
# %users ALL=(ALL) NOPASSWD: /path/to/system_check.sh
# 普通用户执行
# sudo /path/to/system_check.sh
# 清理测试文件
rm system_check.sh示例9:特殊权限的安全审计
# 创建安全审计脚本
cat > special_perm_audit.sh << 'EOF'
#!/bin/bash
echo "=== 特殊权限安全审计报告 ==="
echo "生成时间:$(date)"
echo ""
echo "1. 系统中的SUID文件:"
echo "-------------------"
find / -type f -perm -4000 -ls 2>/dev/null | sort
echo ""
echo "2. 系统中的SGID文件:"
echo "-------------------"
find / -type f -perm -2000 -ls 2>/dev/null | sort
echo ""
echo "3. 系统中的Sticky Bit目录:"
echo "-------------------"
find / -type d -perm -1000 -ls 2>/dev/null | sort
echo ""
echo "4. 可疑的特殊权限设置:"
echo "-------------------"
# 查找非标准位置的SUID文件
find / -type f -perm -4000 -not -path "/usr/*" -not -path "/bin/*" -not -path "/sbin/*" -ls 2>/dev/null
# 查找权限过于宽松的SGID目录
find / -type d -perm -2000 -perm -002 -ls 2>/dev/null
# 查找权限过于宽松的Sticky Bit目录
find / -type d -perm -1000 -perm -002 -not -path "/tmp/*" -not -path "/var/tmp/*" -ls 2>/dev/null
echo ""
echo "=== 审计完成 ==="
EOF
# 使脚本可执行
chmod +x special_perm_audit.sh
# 运行审计
./special_perm_audit.sh
# 清理测试文件
rm special_perm_audit.sh示例10:特殊权限的故障排查
# 问题1:SUID程序无法正常运行
# 检查权限设置
ls -l /path/to/program
# 检查文件是否为可执行文件
file /path/to/program
# 检查文件所有者
ls -l /path/to/program
# 问题2:SGID目录中的文件不继承组所有权
# 检查目录权限
ls -ld /path/to/directory
# 检查目录所属组
ls -ld /path/to/directory
# 检查是否设置了SGID
ls -ld /path/to/directory | grep 's'
# 问题3:Sticky Bit不生效
# 检查目录权限
ls -ld /path/to/directory
# 检查是否设置了Sticky Bit
ls -ld /path/to/directory | grep 't'
# 检查目录是否设置了777权限
ls -ld /path/to/directory | grep '777'课后练习
基础练习:
- 设置一个可执行文件的SUID权限,并测试其效果
- 设置一个目录的SGID权限,并验证在该目录中创建的文件是否继承目录的所属组
- 设置一个目录的Sticky Bit,并测试是否可以防止删除其他用户的文件
进阶练习:
- 编写一个脚本,定期审计系统中设置了特殊权限的文件和目录
- 分析系统中哪些SUID程序是必要的,哪些可能是多余的
- 设计一个安全的目录结构,使用SGID和Sticky Bit管理团队共享文件
思考问题:
- 为什么passwd命令需要设置SUID权限?
- 在什么情况下,使用SGID权限比使用SUID权限更安全?
- 为什么/tmp目录需要同时设置777权限和Sticky Bit?
- 特殊权限可能带来哪些安全风险?如何防范这些风险?
- 在现代Linux系统中,sudo命令如何替代SUID权限的部分功能?
总结
本集详细介绍了Linux系统中的三种特殊权限:SUID、SGID和Sticky Bit,包括它们的作用、设置方法、使用场景以及安全考虑。
- SUID权限:允许普通用户以文件所有者的权限执行特定命令,适用于需要临时提升权限的场景
- SGID权限:对于可执行文件,允许以文件所属组的权限执行;对于目录,使新创建的文件继承目录的所属组
- Sticky Bit:对于目录,防止用户删除其他用户的文件,适用于公共目录
特殊权限是Linux系统权限管理的重要组成部分,正确使用它们可以提高系统管理的效率和灵活性。然而,特殊权限也可能带来安全风险,因此需要谨慎设置和定期审计。
在实际应用中,应该遵循最小权限原则,只对必要的文件和目录设置特殊权限,并结合sudo等工具,构建更加安全和高效的权限管理体系。