
文章来源:运维派
Linux文件权限是操作系统安全的基础设施,却也是新手最容易忽视和误解的领域。在生产环境中,因权限配置错误导致的数据泄露、服务中断、恶意软件入侵案例屡见不鲜。2026年的Linux生态中,容器化、Kubernetes集成、rootless容器等新技术的普及,使得权限管理的重要性更加凸显。
本文面向初中级运维工程师,系统讲解Linux权限体系的工作原理,澄清常见误解,提供可落地的排障思路和最佳实践。文章基于Ubuntu 24.04 LTS、RHEL 9.4、kernel 6.x内核,结合2026年最新的文件系统特性(e.g., idmapped mounts用于容器权限映射)。
Linux权限体系将权限分为三类,每类对应不同的用户:
每类用户拥有三种权限:
# 查看文件权限的符号表示ls -la /etc/passwd# -rw-r--r-- 1 root root 3805 Apr 7 10:00 /etc/passwd# 解读:# - : 文件类型(- 普通文件,d 目录,l 符号链接,c 字符设备,b 块设备)# rw- : 所有者权限(rw- = r=4 + w=2 + x=1 = 6)# r-- : 所属组权限(r-- = r=4 + -=0 + -=0 = 4)# r-- : 其他用户权限(r-- = 4)# 1 : 硬链接数# root : 所有者# root : 所属组# 3805 : 文件大小(字节)# Apr 7 10:00 : 修改时间# /etc/passwd : 文件名权限数值对照表
Linux权限检查的顺序是:所有者 -> 所属组 -> 其他用户。一旦匹配即应用对应权限,不再继续检查后续类别。
# 创建测试环境mkdir -p /tmp/test_permstouch /tmp/test_perms/file.txtchmod 640 /tmp/test_perms/file.txtls -la /tmp/test_perms/file.txt# -rw-r----- 1 root root 0 Apr 7 10:00 /tmp/test_perms/file.txt# 当前用户如果是所有者,应用所有者权限(rw-)# 当前用户如果在所属组中,应用所属组权限(r--)# 都不满足则应用其他用户权限(---)目录权限与文件权限含义不同:
# 目录权限详解# r (读):可以列出目录内容(ls)ls /tmp/test_perms# 需要x配合才能使用ls -l的详细格式# w (写):可以在目录中创建、删除、重命名文件touch /tmp/test_perms/newfile.txtrm /tmp/test_perms/file.txt# 需要x配合才能真正执行# x (执行):可以进入目录(cd),访问目录下的文件属性cd /tmp/test_perms# x是目录的基本权限,没有x则无法访问目录内容# 示例:只有r没有xchmod 644 /tmp/test_permsls /tmp/test_perms# 可以看到文件名列表ls -l /tmp/test_perms# ls: cannot access '/tmp/test_perms/file.txt': Permission denied# 只有xchmod 111 /tmp/test_permsls /tmp/test_perms# ls: cannot open directory /tmp/test_perms: Permission deniedcd /tmp/test_permspwd# 可以进入目录ls /tmp/test_perms/file.txt# 可以访问文件属性(如果知道文件名)数字模式是权限设置最直接的方式,每个权限位用0-7的八进制数表示。
# 基本用法chmod 755 /path/to/file # 所有者rwx(7),组rx(5),其他rx(5)chmod 644 /path/to/file # 所有者rw(6),组r(4),其他r(4)chmod 600 /path/to/file # 所有者rw(6),组无,其他无chmod 700 /path/to/file # 所有者rwx(7),组无,其他无# 特殊权限也可以用数字表示chmod 4755 /path/to/file # SUID(4) + rwx(7) + rx(5) + rx(5)chmod 2755 /path/to/file # SGID(2) + rwx(7) + rx(5) + rx(5)chmod 1755 /path/to/file # SBIT(1) + rwx(7) + rx(5) + rx(5)chmod 6755 /path/to/file # SUID(4) + SGID(2) + rwx(7) + rx(5) + rx(5)符号模式更加灵活,支持精细的权限调整。
# 基本语法:chmod [who] [+|-|=] [permissions] file# who 选项:# u - 所有者 (user/owner)# g - 所属组 (group)# o - 其他用户 (others)# a - 所有人 (all),默认# 操作符:# + - 添加权限# - - 移除权限# = - 设置权限(覆盖原有权限)# permissions 选项:# r - 读# w - 写# x - 执行# s - SUID/SGID# t - SBIT# X - 条件执行(仅对目录或已有执行权限的文件设置执行)# 示例chmod u+x script.sh # 给所有者添加执行权限chmod g-w file.txt # 从组移除写权限chmod o=r file.txt # 设置其他用户只有读权限chmod a+rw file.txt # 给所有人添加读写权限chmod u=rw,go=r file.txt # 设置所有者rw,组和其他r# X 权限的特殊用法chmod -R 755 directory/ # 所有文件都设置执行权限(包括普通文件)chmod -R u+X,go+X directory/ # 只对目录和已有执行权限的文件设置执行# 递归设置目录权限chmod -R 755 /var/www/html# 风险:会修改所有文件的权限,包括普通文件# 更好的方式:目录和文件分开处理find /var/www/html -type d -exec chmod 755 {} \; # 目录find /var/www/html -type f -exec chmod 644 {} \; # 文件# 或者使用 find + xargsfind /var/www/html -type d -print0 | xargs -0 chmod 755find /var/www/html -type f -print0 | xargs -0 chmod 644# 只设置特定条件的文件find /var/www/html -name "*.sh" -exec chmod 755 {} \; # 所有shell脚本find /var/www/html -user www-data -exec chmod 640 {} \; # 属于www-data的文件# 常用权限配置参考# 600 - 私有文件(只有所有者可读写)# 644 - 普通文件(所有者读写,其他人读)# 700 - 私有目录(只有所有者可访问)# 755 - 公共目录(所有者全部权限,其他人读和执行)# 775 - 共享目录(组内协作)# 664 - 共享文件(组内可写)# 666 - 不推荐(有安全风险)# Web服务常见配置chmod -R 755 /var/www/html # 网站文件chmod -R 644 /var/www/html/*.html # HTML文件chmod -R 644 /var/www/html/*.css # CSS文件chmod -R 644 /var/www/html/*.js # JS文件chmod 600 /var/www/html/wp-config.php # WordPress配置(包含数据库密码)# 数据库文件(MySQL)chown -R mysql:mysql /var/lib/mysqlchmod -R 700 /var/lib/mysql # 仅MySQL用户可访问umask(user file creation mask)决定了新建文件和目录的默认权限。它是一个遮罩码,从最大权限中减去遮罩位得到最终权限。
# 查看当前umaskumask# 输出:0022( RHEL/CentOS默认)# 输出:0002( Ubuntu/Debian默认)# 符号形式umask -S# u=rwx,g=rwx,o=rx# 文件最大权限:666(因为文件默认不设置执行权限)# 目录最大权限:777# umask 0022 遮罩的含义:# 0 - 所有者:不遮罩任何位# 2 - 所属组:遮罩写权限(w)# 2 - 其他用户:遮罩写权限(w)# 新建文件权限 = 666 & ~022 = 666 & 755 = 644touch /tmp/test_filels -la /tmp/test_file# -rw-r--r-- 1 root root 0 Apr 7 10:00 /tmp/test_file# 新建目录权限 = 777 & ~022 = 777 & 755 = 755mkdir /tmp/test_dirls -la /tmp/test_dir# drwxr-xr-x 2 root root 4096 Apr 7 10:00 /tmp/test_dir# 临时设置(当前shell生效)umask 0027# 永久设置 - 用户级别(~/.bashrc 或 ~/.profile)echo"umask 0027" >> ~/.bashrcsource ~/.bashrc# 永久设置 - 系统级别(/etc/profile 或 /etc/bash.bashrc)echo"umask 0027" >> /etc/bash.bashrc# 系统安全配置(RHEL/CentOS)cat >> /etc/profile << 'EOF'# Set default umask for new usersif [ $UID -ge 1000 ]; thenumask 0027fiEOF# Apache/Nginx Web服务用户(不允许登录)# umask 应该设置为 022,避免文件权限过严grep UMASK /etc/sysconfig/httpd# UMASK=027# 数据库服务(MySQL/PostgreSQL)# 数据目录需要严格权限,通常 0700# 但运行用户需要适当的umask# 共享目录(团队协作)# umask 0002,允许组成员编辑文件# 配合 setfacl 使用效果更好# 脚本中临时修改umask(umask 0027# 这里创建的文件权限将是 640echo"secret" > /tmp/shared_file)# 子shell退出后,父shell的umask不受影响SUID允许程序以文件所有者的权限运行,而非执行者的权限。
# SUID 设置chmod u+s /path/to/program# 或chmod 4755 /path/to/program# 查看SUIDls -la /usr/bin/passwd# -rwsr-xr-x 1 root root 27856 Apr 7 2024 /usr/bin/passwd# ^# 注意 s 替代了 x,表示设置了SUID# SUID 的典型应用:passwd 命令# 普通用户可以修改自己的密码(写入 /etc/shadow)# 这是因为 passwd 程序以 root 权限运行# SUID 风险示例:危险的配置chmod 4755 /bin/sh # 极其危险!任何用户都可以以root身份执行sh# 绝对不要这样做!SGID允许程序以文件所属组的权限运行。对于目录,SGID会使目录下新建的文件继承该目录的组。
# SGID 设置chmod g+s /path/to/program# 或chmod 2755 /path/to/program# 查看SGIDls -la /usr/bin/write# -rwxr-sr-x 1 root tty 19552 Jan 27 2024 /usr/bin/write# 目录的SGID:子文件继承目录组mkdir /home/sharedchgrp developers /home/sharedchmod 2775 /home/shared# 现在任何在 developers 组内的用户,在 /home/shared 下创建的文件# 都会自动属于 developers 组# 验证ls -la /home/shared# drwxrwsr-x 2 root root 4096 Apr 7 10:00 /home/shared# ^# 注意 s 表示SGIDSBIT(也称 RestrictedDeletion Bit)保护目录中的文件:只有文件所有者或root可以删除或重命名目录中的文件。
# SBIT 设置chmod +t /path/to/directory# 或chmod 1755 /path/to/directory# 查看SBITls -la /tmp# drwxrwxrwt 10 root root 4096 Apr 7 10:00 /tmp# ^# 注意 t 替代了x,表示设置了SBIT# 如果小写t,表示原来有x但被遮罩# /tmp 目录的SBIT解释:# 任何用户都可以在 /tmp 中创建文件# 但只有文件所有者(或root)可以删除自己的文件# 这防止用户A删除用户B的文件# 查找所有设置了SUID的文件find / -perm -4000 -type f 2>/dev/null# 查找所有设置了SGID的文件find / -perm -2000 -type f 2>/dev/null# 查找所有设置了SBIT的目录find / -perm -1000 -type d 2>/dev/null# 综合查找find / \( -perm -4000 -o -perm -2000 \) -type f 2>/dev/null# 安全审计:检查可疑的SUID文件# 正常系统应该有的SUID文件(参考)/usr/bin/passwd/usr/bin/sudo/usr/bin/su/usr/bin/chfn/usr/bin/chsh/usr/bin/gpasswd/usr/bin/mount/usr/bin/umount/usr/bin/newgrp/usr/libexec/sudo/sudoers_parser/usr/sbin/unix_chkpwd/usr/sbin/pwdb_chkpwd#!/bin/bash# check_special_perms.sh - 检查特殊权限配置set -euo pipefailREPORT="/tmp/special_perms_report_$(date +%Y%m%d_%H%M%S).txt"echo"=== Linux 特殊权限安全审计 ===" > "$REPORT"echo"审计时间: $(date)" >> "$REPORT"echo"" >> "$REPORT"# SUID 文件检查echo"【SUID 文件检查】" >> "$REPORT"echo"正常范围外的高风险SUID文件:" >> "$REPORT"find / -perm -4000 -type f -ls 2>/dev/null | \ grep -v -E "^(/usr/bin/passwd|/usr/bin/sudo|/usr/bin/su|/usr/bin/chfn|/usr/bin/chsh|/usr/bin/gpasswd|/usr/sbin/unix_chkpwd)" >> "$REPORT" || true# SGID 文件检查echo"" >> "$REPORT"echo"【SGID 文件检查】" >> "$REPORT"echo"高风险SGID文件:" >> "$REPORT"find / -perm -2000 -type f -ls 2>/dev/null | \ grep -v -E "^(/usr/bin/write|/usr/bin/wall|/usr/bin/lpr|/usr/bin/lprm)" >> "$REPORT" || true# SBIT 目录检查echo"" >> "$REPORT"echo"【SBIT 目录检查】" >> "$REPORT"echo"缺少SBIT保护的公共目录:" >> "$REPORT"find / -maxdepth 2 -perm -0002 -type d -ls 2>/dev/null | \ grep -v -E "^/tmp|^/var/tmp" >> "$REPORT" || true# 权限过高的文件echo"" >> "$REPORT"echo"【高风险权限配置】" >> "$REPORT"echo"777权限的可执行文件:" >> "$REPORT"find / -type f -perm -777 -ls 2>/dev/null | head -20 >> "$REPORT"echo"" >> "$REPORT"echo"【建议】" >> "$REPORT"cat >> "$REPORT" << 'EOF'1. SUID/SGID文件应定期审计,移除不必要的特殊权限2. 高风险SUID文件(如有shell的SUID)应立即修复3. 公共目录应设置SBIT保护4. 使用 RPM/DPKG 验证系统文件完整性 rpm -Va | grep -E '^\.\.5.*P'# 检查SUID文件变化EOFcat "$REPORT"echo""echo"报告已保存到: $REPORT"传统的Unix权限模型(owner/group/others)过于简单,无法满足精细化权限控制需求。ACL(Access Control List)扩展了权限模型,支持对单个用户或组设置独立的权限。
# 检查文件系统是否支持ACL# 主流文件系统 ext4, XFS, Btrfs 默认支持ACL# 检查ACL支持dumpe2fs -h /dev/sda1 | grep "Default mount options"# 或mount | grep acl# RHEL/CentOS 默认启用ACL# Ubuntu 默认启用ACL# 启用ACL(如果需要手动开启)mount -o remount,acl /dev/sda1# 或在 /etc/fstab 中配置# /dev/sda1 /data ext4 defaults,acl 0 2# 查看ACLgetfacl /path/to/file# 示例touch /tmp/acl_test.txtgetfacl /tmp/acl_test.txt# # file: acl_test.txt# # owner: root# # group: root# user::rw-# group::r--# other::r--# 为单个用户设置权限setfacl -m u:john:rw /tmp/acl_test.txtgetfacl /tmp/acl_test.txt# # file: acl_test.txt# # owner: root# # group: root# user::rw-# user:john:rw-# group::r--# mask::rw-# other::r--# 为单个组设置权限setfacl -m g:developers:rx /tmp/acl_test.txtgetfacl /tmp/acl_test.txt# # file: acl_test.txt# # owner: root# # group: root# user::rw-# user:john:rw-# group::r--# group:developers:r-x# mask::rw-# other::r--# 为多个用户/组设置setfacl -m u:alice:rwx,u:bob:r-x,g:qa:rx /tmp/acl_test.txt默认ACL应用于目录,新建的子文件/子目录会自动继承。
# 设置目录的默认ACLmkdir -p /home/sharedsetfacl -R -m u:alice:rwx /home/shared # 递归设置setfacl -R -m g:team:rx /home/shared# 设置默认ACL(仅影响新建文件)setfacl -d -m u:bob:rw /home/sharedsetfacl -d -m g:team:rx /home/sharedsetfacl -d -m o::r /home/shared # 其他用户默认读权限# 查看默认ACLgetfacl /home/shared# # file: shared# # owner: root# # group: root# user::rwx# user:alice:rwx# group::r-x# group:team:r-x# mask::rwx# other::r-x# default:user::rwx# default:user:bob:rw-# default:group::r-x# default:group:team:r-x# default:mask::rwx# default:other::r--# 测试继承效果touch /home/shared/testfile.txtgetfacl /home/shared/testfile.txt# 新文件自动继承默认ACL# 移除特定用户的ACLsetfacl -x u:john /tmp/acl_test.txt# 移除特定组的ACLsetfacl -x g:developers /tmp/acl_test.txt# 移除所有扩展ACL(保留基础权限)setfacl -b /tmp/acl_test.txt# 备份ACLgetfacl -R /home/shared > /tmp/acl_backup.txt# 恢复ACLsetfacl --restore=/tmp/acl_backup.txt# 复制ACL到其他文件getfacl file1.txt | setfacl --set-file=- file2.txt# ACL 权限检查顺序# 1. 如果进程以文件owner身份运行 -> 应用 owner ACL 条目# 2. 如果进程属于文件关联的group或ACL中的某个group -> 应用匹配的最优ACL组条目# 3. 应用 other ACL 条目# mask 对扩展ACL的影响# mask 限制了所有ACL条目的有效权限(除了owner和other)# 即使单独设置了 u:john:rwx,如果mask是r--,实际权限也是r--# 调整masksetfacl -m m::r /tmp/acl_test.txt # 设置mask为r--setfacl -m m::rw /tmp/acl_test.txt # 设置mask为rw-#!/bin/bash# setup_shared_directory.sh - 配置共享目录的ACL权限set -euo pipefailSHARE_DIR="${1:-/home/shared}"PRIMARY_GROUP="${2:-developers}"PERMISSIONS="${3:-2775}"# 用户列表(根据实际情况修改)declare -a ALLOWED_USERS=("alice""bob""charlie")declare -a READONLY_USERS=("qa_user""auditor")if [ ! -d "$SHARE_DIR" ]; thenecho"错误:目录不存在: $SHARE_DIR"exit 1fiecho"=== 共享目录 ACL 配置 ==="echo"目录: $SHARE_DIR"echo"主组: $PRIMARY_GROUP"echo"权限: $PERMISSIONS"echo""# 设置基础权限echo"[1/4] 设置基础权限..."chown root:"$PRIMARY_GROUP""$SHARE_DIR"chmod "$PERMISSIONS""$SHARE_DIR"# 清理现有ACLecho"[2/4] 清理现有ACL..."setfacl -b "$SHARE_DIR"# 设置默认ACL(递归)echo"[3/4] 设置默认ACL..."for user in"${ALLOWED_USERS[@]}"; doif id "$user" &>/dev/null; then setfacl -R -m u:"$user":rwx "$SHARE_DIR" setfacl -d -R -m u:"$user":rwx "$SHARE_DIR"echo" - 添加读写用户: $user"elseecho" - 警告:用户不存在: $user"fidonefor user in"${READONLY_USERS[@]}"; doif id "$user" &>/dev/null; then setfacl -R -m u:"$user":r-x "$SHARE_DIR" setfacl -d -R -m u:"$user":r-x "$SHARE_DIR"echo" - 添加只读用户: $user"elseecho" - 警告:用户不存在: $user"fidone# 设置组默认权限setfacl -d -R -m g::rwx "$SHARE_DIR"setfacl -d -R -m g:"$PRIMARY_GROUP":rwx "$SHARE_DIR"setfacl -d -R -m o::rx "$SHARE_DIR"# 设置masksetfacl -R -m m::rwx "$SHARE_DIR"echo"[4/4] 验证配置..."echo""getfacl "$SHARE_DIR"echo""echo"=== 配置完成 ==="echo""echo"测试方法:"for user in"${ALLOWED_USERS[@]}"; doecho"su - $user -c 'touch $SHARE_DIR/${user}_test.txt'"done# 基本语法chown [OPTIONS] OWNER[:GROUP] FILE...# 只改所有者chown john /path/to/file# 所有者:组一起改chown john:developers /path/to/file# 只改组(使用 chgrp 等效)chown :developers /path/to/file# 递归修改chown -R john:developers /path/to/directory# 保留原有组chown -R john /path/to/directory# 数字所有者chown 1000:1000 /path/to/file# 使用 --reference 复制另一个文件的owner和groupchown --reference=/etc/passwd /path/to/file# 批量复制for f in /var/www/html/*.php; do chown --reference=/var/www/html/index.php "$f"done# find 配合使用find /var/www/html -user www-data -type f -exec chown apache:apache {} \;# 基本语法chgrp [OPTIONS] GROUP FILE...# 改组chgrp developers /path/to/file# 递归chgrp -R developers /path/to/directory# 参考文件chgrp --reference=/etc/group /path/to/file# 组必须存在于 /etc/groupsgrep "^developers:" /etc/group# developers:x:1001:alice,bob,charlie#!/bin/bash# fix_ownership.sh - 批量修复文件所有权set -euo pipefailTARGET_DIR="${1:-/var/www/html}"OWNER="${2:-www-data}"GROUP="${3:-www-data}"if [ ! -d "$TARGET_DIR" ]; thenecho"错误:目录不存在: $TARGET_DIR"exit 1fiecho"=== 批量修复所有权 ==="echo"目录: $TARGET_DIR"echo"所有者: $OWNER"echo"组: $GROUP"echo""# 验证用户和组是否存在if ! id "$OWNER" &>/dev/null; thenecho"错误:用户不存在: $OWNER"exit 1fiif ! getent group "$GROUP" &>/dev/null; thenecho"错误:组不存在: $GROUP"exit 1fi# 目录和文件分开处理echo"[1/3] 设置目录权限..."find "$TARGET_DIR" -type d -exec chown "$OWNER:$GROUP" {} \;echo"[2/3] 设置文件权限..."find "$TARGET_DIR" -type f -exec chown "$OWNER:$GROUP" {} \;echo"[3/3] 设置标准权限..."find "$TARGET_DIR" -type d -exec chmod 755 {} \;find "$TARGET_DIR" -type f -exec chmod 644 {} \;# 可执行文件特殊处理find "$TARGET_DIR" -name "*.cgi" -type f -exec chmod 755 {} \;find "$TARGET_DIR" -name "*.pl" -type f -exec chmod 755 {} \;find "$TARGET_DIR" -name "*.sh" -type f -exec chmod 755 {} \;echo"=== 完成 ==="echo""echo"验证:"ls -la "$TARGET_DIR" | head -10# Step 1: 检查文件权限ls -la /path/to/problematic/file# Step 2: 检查当前用户身份whoamiid# Step 3: 检查用户所属组id username# Step 4: 检查目录结构(父目录权限)ls -ld /parent/directorynamei -l /path/to/file # 显示完整路径的权限链# Step 5: 检查ACLgetfacl /path/to/file# Step 6: 检查SELinux(如果启用)getenforcels -Z /path/to/filesestatus# Step 7: 检查AppArmor(如果启用)aa-status场景一:Web服务无法读取文件
# 错误现象:nginx返回403 Forbidden# 排查步骤# 1. 检查文件权限ls -la /var/www/html/index.html# -rw-r----- 1 root www-data 644 ...# 2. 检查nginx运行用户grep "^user" /etc/nginx/nginx.conf# user nginx;# 3. nginx以nginx用户运行,但文件属于www-data# 解决方案:chown nginx:nginx /var/www/html/index.html# 或将用户加入www-data组usermod -a -G www-data nginx# 或修改nginx运行用户场景二:用户无法写入共享目录
# 错误现象:用户创建文件提示Permission denied# 排查步骤# 1. 检查目录权限ls -ld /home/shared# drwxr-x--- 3 root developers 4096 Apr 7 10:00 ...# 2. 检查用户是否在组中id username# uid=1001(username) gid=1001(username) groups=1001(username)# 3. 用户不在developers组# 解决方案:usermod -a -G developers username# 需要重新登录生效,或使用 newgrp 立即切换newgrp developers场景三:sudoers配置的权限问题
# 检查sudo权限sudo -l# 以特定用户测试sudo -u username /path/to/command# 检查sudoers语法visudo -c# 输出:/etc/sudoers.tmp parsed OK# 查看用户特定配置ls -la /etc/sudoers.d/cat /etc/sudoers.d/username#!/bin/bash# diagnose_permissions.sh - 权限问题诊断工具set -euo pipefailTARGET="${1:-.}"echo"=== 权限问题诊断报告 ==="echo"目标: $TARGET"echo"时间: $(date)"echo"用户: $(whoami) ($(id))"echo""# 基础权限信息echo"【基础信息】"namei -l "$TARGET" 2>/dev/null || ls -ld "$TARGET"echo""# 文件/目录权限echo"【权限详情】"ls -la "$TARGET"echo""# ACL信息ifcommand -v getfacl &>/dev/null; thenecho"【ACL信息】" getfacl "$TARGET" 2>/dev/null || echo"ACL不可用"echo""fi# SELinux状态(如果存在)ifcommand -v getenforce &>/dev/null; thenecho"【SELinux状态】" getenforce ls -Z "$TARGET" 2>/dev/null || echo"SELinux未启用或不支持"echo""fi# AppArmor状态(如果存在)ifcommand -v aa-status &>/dev/null; thenecho"【AppArmor状态】" aa-status --profiled 2>/dev/null | head -5echo""fi# 组信息echo"【组成员资格】"current_user=$(whoami)groupsecho""# 权限计算echo"【权限分析】"perms=$(stat -c %a "$TARGET" 2>/dev/null)echo"八进制权限: $perms"echo"解读: "echo" 所有者: $(echo $perms | cut -c1) - $([ $(echo $perms | cut -c1) -ge 4 ] && echo "r" || echo "-")$([ $(echo $perms | cut -c1) -ge 2 ] && echo "w" || echo "-")$([ $(echo $perms | cut -c1) -ge 1 ] && echo "x" || echo "-")"echo" 所属组: $(echo $perms | cut -c2) - $([ $(echo $perms | cut -c2) -ge 4 ] && echo "r" || echo "-")$([ $(echo $perms | cut -c2) -ge 2 ] && echo "w" || echo "-")$([ $(echo $perms | cut -c2) -ge 1 ] && echo "x" || echo "-")"echo" 其他用户: $(echo $perms | cut -c3) - $([ $(echo $perms | cut -c3) -ge 4 ] && echo "r" || echo "-")$([ $(echo $perms | cut -c3) -ge 2 ] && echo "w" || echo "-")$([ $(echo $perms | cut -c3) -ge 1 ] && echo "x" || echo "-")"echo""# 访问测试echo"【访问测试】"if [ -r "$TARGET" ]; thenecho"[OK] 可读"elseecho"[NO] 不可读"fiif [ -w "$TARGET" ]; thenecho"[OK] 可写"elseecho"[NO] 不可写"fiif [ -x "$TARGET" ]; thenecho"[OK] 可执行"elseecho"[NO] 不可执行"fiecho""echo"=== 诊断完成 ==="777权限(rwxrwxrwx)意味着所有者、组、所有人都有读写执行权限。这在生产环境中是严重的安全风险。
# 777权限的风险# 1. 任何本地用户都可以修改文件chmod 777 /etc/passwd # 允许任何用户修改密码文件!# 2. 目录777允许任意创建/删除文件chmod 777 /tmp/shared # 任何用户可以删除他人文件# 3. Web目录777可能导致远程代码执行chmod 777 /var/www/html/uploads # 上传目录777 = 潜在RCE# 4. 系统配置777可能导致提权chmod 777 /etc/sudoers # 语法错误会导致sudo不可用!Web应用目录
# 网站根目录/var/www/html/ 所有者: nginx(或apache) 组: nginx(或apache) 目录权限: 755 (drwxr-xr-x) 文件权限: 644 (-rw-r--r--) 可写目录: 775 (drwxrwxr-x) + ACL控制# 上传目录(需要可写)mkdir -p /var/www/html/uploadschown nginx:nginx /var/www/html/uploadschmod 755 /var/www/html/uploads# 使用ACL限制可写用户setfacl -m u:nginx:rwX /var/www/html/uploadssetfacl -m u:apache:rwX /var/www/html/uploadssetfacl -d -m u:nginx:rwX /var/www/html/uploads数据库目录
# MySQL数据目录chown -R mysql:mysql /var/lib/mysqlchmod -R 700 /var/lib/mysql# PostgreSQL数据目录chown -R postgres:postgres /var/lib/postgresqlchmod -R 700 /var/lib/postgresql# 只允许数据库用户访问日志目录
# 应用日志mkdir -p /var/log/myappchown -R myapp:myapp /var/log/myappchmod 755 /var/log/myapp# 日志文件find /var/log/myapp -type f -exec chown myapp:myapp {} \;find /var/log/myapp -type f -exec chmod 640 {} \;# 允许日志轮转(logrotate需要读取)chmod 755 /var/log/myapp# 或配置logrotate以root运行#!/bin/bash# security_check.sh - 权限安全检查脚本set -euo pipefailREPORT="/tmp/security_check_$(date +%Y%m%d_%H%M%S).txt"echo"=== Linux 权限安全检查 ===" > "$REPORT"echo"检查时间: $(date)" >> "$REPORT"echo"" >> "$REPORT"# 1. 检查777权限文件echo"【1. 777权限文件检查】" >> "$REPORT"echo"高风险!任何用户都可读写执行:" >> "$REPORT"find / -type f -perm -777 2>/dev/null | \ grep -v -E "^(/tmp|/var/tmp)" | head -20 >> "$REPORT" || echo"未发现" >> "$REPORT"echo"" >> "$REPORT"# 2. 检查777权限目录echo"【2. 777权限目录检查】" >> "$REPORT"echo"高风险!任何用户都可创建/删除文件:" >> "$REPORT"find / -type d -perm -777 2>/dev/null | \ grep -v -E "^(/tmp|/var/tmp)" | head -20 >> "$REPORT" || echo"未发现" >> "$REPORT"echo"" >> "$REPORT"# 3. 检查无主文件echo"【3. 无主文件检查】" >> "$REPORT"echo"这些文件没有有效的所有者:" >> "$REPORT"find / -nouser -o -nogroup 2>/dev/null | head -20 >> "$REPORT" || echo"未发现" >> "$REPORT"echo"" >> "$REPORT"# 4. 检查危险SUID文件echo"【4. 危险SUID文件检查】" >> "$REPORT"echo"带有shell的SUID文件(紧急风险):" >> "$REPORT"find / -perm -4000 -type f 2>/dev/null | \ xargs -I {} bash -c 'file {} | grep -q "shell" && echo {}' 2>/dev/null >> "$REPORT" || echo"未发现" >> "$REPORT"echo"" >> "$REPORT"# 5. 检查密码文件权限echo"【5. 密码相关文件权限】" >> "$REPORT"for f in /etc/passwd /etc/shadow /etc/group /etc/gshadow; doif [ -f "$f" ]; then perms=$(stat -c %a "$f") owner=$(stat -c %U "$f") group=$(stat -c %G "$f")echo"$f: $owner:$group$perms" >> "$REPORT"fidoneecho"" >> "$REPORT"# 6. 检查SSH密钥权限echo"【6. SSH密钥权限】" >> "$REPORT"for f in ~/.ssh/id_rsa ~/.ssh/id_ed25519 ~/.ssh/authorized_keys; doif [ -f "$f" ]; then perms=$(stat -c %a "$f")echo"$f: $perms" >> "$REPORT"fidoneecho"" >> "$REPORT"# 7. 检查重要系统目录echo"【7. 重要系统目录权限】" >> "$REPORT"for d in /etc /bin /sbin /usr/bin /usr/sbin /lib; doif [ -d "$d" ]; then perms=$(stat -c %a "$d")echo"$d: $perms" >> "$REPORT"fidoneecho"" >> "$REPORT"# 总结建议cat >> "$REPORT" << 'EOF'【安全建议】1. 系统文件应保持644权限,所有者为root2. /etc/shadow 应为 000 或 0000,所有者为root3. 用户的SSH私钥应为 6004. 用户的SSH公钥应为 6445. authorized_keys 应为 6006. 避免使用777权限,使用ACL实现精细控制7. 定期审计SUID/SGID文件8. 清理无主文件EOFcat "$REPORT"echo""echo"报告已保存到: $REPORT"# 最小权限原则# 1. 优先使用ACL而非组权限共享# 2. 目录755/文件644是通用安全默认值# 3. 共享目录使用2775 + ACL# 4. 敏感文件使用600或400# 权限分层# 系统层: root拥有所有权限# 服务层: 各服务使用独立用户/组# 应用层: 应用数据使用应用专用账户# 用户层: 普通用户使用自己的账户# 定期审计# 每周: 审计新增的SUID文件# 每月: 审计高权限目录变化# 每次部署: 检查新文件权限# 容器内非root用户运行# Dockerfile 示例FROM ubuntu:24.04RUN groupadd -r appuser && useradd -r -g appuser appuserWORKDIR /appCOPY --chown=appuser:appuser . .USER appuser# Kubernetes 安全上下文securityContext: runAsUser: 1000 runAsGroup: 1000 fsGroup: 1000 runAsNonRoot: true readOnlyRootFilesystem: true# idmapped mounts(kernel 6.x特性)# 用于容器和主机间的UID/GID映射# 避免容器内root映射到主机rootLinux权限管理是运维工作的基础中的基础。本篇文章覆盖了从基础概念到高级ACL的完整知识体系,重点澄清了"777万能钥匙"的误区,强调了最小权限原则的重要性。
核心要点:
生产环境中的权限管理需要结合业务需求和安全要求,在便利性与安全性之间找到平衡点。建议将本文的检查脚本集成到日常运维工作中,形成制度化的权限审计流程。

版权申明:内容来源网络,版权归原创者所有。除非无法确认,我们都会标明作者及出处,如有侵权烦请告知,我们会立即删除并致歉。祝愿每一位读者生活愉快!
本公号发布、转载的文章中所涉及的技术、思路和工具仅供以安全为目的的学习交流使用,任何人不得将其用于非法用途及盈利等目的,否则后果自行承担!
推荐阅读


*【已复现】OpenCode 远程代码执行漏洞(CVE-2026-22812)

