第31集:权限数字表示法

教学目标

  • 理解Linux系统中权限数字表示法的基本原理
  • 掌握权限位的计算规则和方法
  • 熟悉常见的数字权限组合及其含义
  • 掌握使用数字表示法设置文件和目录权限的方法
  • 能够根据实际需求选择合适的权限设置
  • 理解数字表示法与符号表示法的对应关系

核心知识点讲解

1. 权限数字表示法概述

权限数字表示法是Linux系统中表示文件和目录权限的一种简洁方法,使用八进制数字(0-7)来表示不同的权限组合。这种表示方法在脚本编写和自动化操作中尤为常用,因为它更加简洁明了。

2. 权限位的计算规则

Linux系统中的权限由9个权限位组成,分为3组,每组3位,分别对应所有者(owner)、所属组(group)和其他用户(others)的权限。

基本权限位

权限 二进制 八进制 含义
--- 000 0 无权限
--x 001 1 执行权限
-w- 010 2 写入权限
-wx 011 3 写入和执行权限
r-- 100 4 读取权限
r-x 101 5 读取和执行权限
rw- 110 6 读取和写入权限
rwx 111 7 读取、写入和执行权限

权限组的组合

每个权限组(所有者、所属组、其他用户)的权限用一个八进制数字表示,然后将三个数字组合起来,形成一个三位数的八进制数,用于表示完整的权限设置。

例如:

  • 所有者权限:rwx(7)
  • 所属组权限:r-x(5)
  • 其他用户权限:r--(4)
  • 完整权限表示:754

3. 特殊权限位的数字表示

除了基本权限外,Linux还支持三种特殊权限:SUID、SGID和Sticky Bit。这些特殊权限也可以用数字表示:

特殊权限 八进制值 位置 作用
SUID 4 第一位 执行文件时使用文件所有者的权限
SGID 2 第一位 执行文件时使用文件所属组的权限;对目录,新文件继承目录的所属组
Sticky Bit 1 第一位 对目录,只有文件所有者和root可以删除文件

特殊权限的数字表示方法是在基本权限数字前添加对应的八进制值,形成一个四位数的八进制数。

例如:

  • 4755:设置了SUID权限的755权限
  • 2755:设置了SGID权限的755权限
  • 1777:设置了Sticky Bit的777权限

4. 常见的数字权限组合

数字权限 符号表示 含义 适用场景
755 rwxr-xr-x 所有者有全部权限,其他用户有读取和执行权限 可执行文件、脚本、目录
700 rwx------ 只有所有者有全部权限,其他用户无权限 个人配置文件、敏感目录
644 rw-r--r-- 所有者有读取和写入权限,其他用户只有读取权限 普通文件、文档
600 rw------- 只有所有者有读取和写入权限,其他用户无权限 敏感配置文件、密码文件
777 rwxrwxrwx 所有用户都有全部权限 公共临时目录(谨慎使用)
1777 rwxrwxrwt 所有用户都有全部权限,且设置了Sticky Bit 公共临时目录,如/tmp
2755 rwxr-sr-x 设置了SGID的755权限 需要保持组所有权的目录
4755 rwsr-xr-x 设置了SUID的755权限 需要特殊权限的可执行文件

5. 目录权限的特殊考虑

对于目录,执行权限(x)尤为重要,因为它允许用户进入目录。没有执行权限,即使有读取权限,也无法进入目录查看其内容。

常见的目录权限设置:

  • 755:标准目录权限,允许所有用户进入和查看
  • 700:个人目录,只有所有者可以访问
  • 1777:公共临时目录,所有用户可以创建文件,但只能删除自己的文件

6. 权限计算示例

示例1:基本权限计算

需求:设置文件权限为所有者有读取、写入和执行权限,所属组有读取和执行权限,其他用户只有读取权限。

计算过程:

  • 所有者权限:rwx = 4 + 2 + 1 = 7
  • 所属组权限:r-x = 4 + 0 + 1 = 5
  • 其他用户权限:r-- = 4 + 0 + 0 = 4
  • 完整权限:754

示例2:包含特殊权限的计算

需求:设置目录权限为所有用户有读取、写入和执行权限,并设置Sticky Bit。

计算过程:

  • 基本权限:rwxrwxrwx = 777
  • 添加Sticky Bit:1 + 777 = 1777
  • 完整权限:1777

7. 数字表示法的优缺点

优点

  • 简洁明了:用一个数字表示完整的权限设置,更加简洁
  • 易于记忆:常见权限组合的数字表示容易记忆
  • 脚本友好:在脚本和自动化操作中使用方便
  • 计算准确:通过简单的加法计算权限,不容易出错

缺点

  • 不够直观:对于初学者来说,数字表示法不如符号表示法直观
  • 难以调整:修改部分权限时,需要重新计算整个权限数字
  • 特殊权限理解复杂:包含特殊权限的数字表示需要额外学习

8. 数字表示法与符号表示法的对应关系

数字表示 符号表示 数字表示 符号表示
0 --- 4 r--
1 --x 5 r-x
2 -w- 6 rw-
3 -wx 7 rwx

操作示例

示例1:使用数字表示法设置文件权限

# 设置文件权限为755(rwxr-xr-x)
chmod 755 script.sh

# 设置文件权限为644(rw-r--r--)
chmod 644 document.txt

# 设置文件权限为700(rwx------)
chmod 700 private.key

# 设置文件权限为600(rw-------)
chmod 600 .bash_history

# 查看权限设置结果
ls -l script.sh document.txt private.key .bash_history

示例2:使用数字表示法设置目录权限

# 设置目录权限为755(rwxr-xr-x)
mkdir public_dir
chmod 755 public_dir

# 设置目录权限为700(rwx------)
mkdir private_dir
chmod 700 private_dir

# 设置目录权限为1777(rwxrwxrwt)
mkdir temp_dir
chmod 1777 temp_dir

# 设置目录权限为2755(rwxr-sr-x)
mkdir shared_dir
chmod 2755 shared_dir

# 查看权限设置结果
ls -ld public_dir private_dir temp_dir shared_dir

示例3:递归设置权限

# 递归设置目录及其所有内容的权限为755
chmod -R 755 project/

# 递归设置目录及其所有内容的权限为644
chmod -R 644 documents/

# 注意:递归设置权限时要谨慎,特别是对于包含可执行文件和目录的混合内容
# 正确的做法是先设置目录权限,再设置文件权限
find project/ -type d -exec chmod 755 {} \;
find project/ -type f -exec chmod 644 {} \;
find project/ -name "*.sh" -exec chmod 755 {} \;

示例4:设置特殊权限

# 设置SUID权限(4755)
chmod 4755 /usr/local/bin/special_command

# 设置SGID权限(2755)
chmod 2755 /var/shared

# 设置Sticky Bit(1777)
chmod 1777 /var/tmp

# 查看特殊权限设置结果
ls -l /usr/local/bin/special_command
ls -ld /var/shared /var/tmp

示例5:根据文件类型设置不同权限

# 创建测试文件和目录
mkdir test_dir
touch test_dir/file1.txt
touch test_dir/file2.sh
mkdir test_dir/sub_dir

# 查看初始权限
ls -la test_dir/

# 设置目录权限为755
find test_dir/ -type d -exec chmod 755 {} \;

# 设置普通文件权限为644
find test_dir/ -type f ! -name "*.sh" -exec chmod 644 {} \;

# 设置脚本文件权限为755
find test_dir/ -name "*.sh" -exec chmod 755 {} \;

# 查看最终权限
ls -la test_dir/
ls -la test_dir/sub_dir/

示例6:权限计算练习

# 创建测试文件
touch permission_test.txt

# 练习1:设置权限为rwxrwxrwx(777)
chmod 777 permission_test.txt
ls -l permission_test.txt

# 练习2:设置权限为rwxr-xr--(754)
chmod 754 permission_test.txt
ls -l permission_test.txt

# 练习3:设置权限为rw-r-----(640)
chmod 640 permission_test.txt
ls -l permission_test.txt

# 练习4:设置权限为r--------(400)
chmod 400 permission_test.txt
ls -l permission_test.txt

# 练习5:设置权限为--------x(001)
chmod 001 permission_test.txt
ls -l permission_test.txt

示例7:权限脚本

# 创建权限管理脚本
cat > permission_manager.sh << 'EOF'
#!/bin/bash

# 显示菜单
echo "权限管理脚本(数字表示法)"
echo "1. 设置文件为755权限(rwxr-xr-x)"
echo "2. 设置文件为644权限(rw-r--r--)"
echo "3. 设置文件为700权限(rwx------)"
echo "4. 设置文件为600权限(rw-------)"
echo "5. 设置目录为755权限(rwxr-xr-x)"
echo "6. 设置目录为700权限(rwx------)"
echo "7. 设置目录为1777权限(rwxrwxrwt)"
echo "8. 自定义权限"
echo "9. 退出"

read -p "请选择操作:" choice

case $choice in
    1)
        read -p "请输入文件路径:" path
        if [ -f "$path" ]; then
            chmod 755 "$path"
            echo "权限设置成功:755 (rwxr-xr-x)"
            ls -l "$path"
        else
            echo "错误:路径不存在或不是文件"
        fi
        ;;
    2)
        read -p "请输入文件路径:" path
        if [ -f "$path" ]; then
            chmod 644 "$path"
            echo "权限设置成功:644 (rw-r--r--)"
            ls -l "$path"
        else
            echo "错误:路径不存在或不是文件"
        fi
        ;;
    3)
        read -p "请输入文件路径:" path
        if [ -f "$path" ]; then
            chmod 700 "$path"
            echo "权限设置成功:700 (rwx------)"
            ls -l "$path"
        else
            echo "错误:路径不存在或不是文件"
        fi
        ;;
    4)
        read -p "请输入文件路径:" path
        if [ -f "$path" ]; then
            chmod 600 "$path"
            echo "权限设置成功:600 (rw-------)"
            ls -l "$path"
        else
            echo "错误:路径不存在或不是文件"
        fi
        ;;
    5)
        read -p "请输入目录路径:" path
        if [ -d "$path" ]; then
            chmod 755 "$path"
            echo "权限设置成功:755 (rwxr-xr-x)"
            ls -ld "$path"
        else
            echo "错误:路径不存在或不是目录"
        fi
        ;;
    6)
        read -p "请输入目录路径:" path
        if [ -d "$path" ]; then
            chmod 700 "$path"
            echo "权限设置成功:700 (rwx------)"
            ls -ld "$path"
        else
            echo "错误:路径不存在或不是目录"
        fi
        ;;
    7)
        read -p "请输入目录路径:" path
        if [ -d "$path" ]; then
            chmod 1777 "$path"
            echo "权限设置成功:1777 (rwxrwxrwt)"
            ls -ld "$path"
        else
            echo "错误:路径不存在或不是目录"
        fi
        ;;
    8)
        read -p "请输入文件或目录路径:" path
        read -p "请输入权限数字(例如:755):" permission
        if [ -e "$path" ]; then
            chmod "$permission" "$path"
            echo "权限设置成功:$permission"
            if [ -d "$path" ]; then
                ls -ld "$path"
            else
                ls -l "$path"
            fi
        else
            echo "错误:路径不存在"
        fi
        ;;
    9)
        echo "退出脚本"
        exit 0
        ;;
    *)
        echo "无效的选择"
        ;;
esac
EOF

# 使脚本可执行
chmod +x permission_manager.sh

# 运行脚本
./permission_manager.sh

示例8:权限审计与修复

# 查找系统中权限为777的文件和目录
find / -type f -perm 0777 -ls 2>/dev/null
find / -type d -perm 0777 -ls 2>/dev/null

# 查找系统中权限过于宽松的配置文件
find /etc -type f -perm /022 -name "*.conf" -ls 2>/dev/null

# 修复权限示例:将过于宽松的配置文件权限设置为644
find /etc -type f -perm /022 -name "*.conf" -exec chmod 644 {} \; 2>/dev/null

# 修复权限示例:将可执行文件权限设置为755
find /usr/local/bin -type f -exec chmod 755 {} \; 2>/dev/null

# 修复权限示例:将目录权限设置为755
find /usr/local -type d -exec chmod 755 {} \; 2>/dev/null

示例9:特殊权限的应用

# 创建一个需要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 4755 test_suid

# 查看权限变化
ls -l test_suid

# 再次运行程序(有SUID)
./test_suid

# 创建一个需要SGID权限的目录
mkdir test_sgid_dir
chmod 2755 test_sgid_dir
ls -ld test_sgid_dir

# 在目录中创建文件,验证所属组继承
touch test_sgid_dir/test_file
ls -l test_sgid_dir/test_file

示例10:权限与安全

# 检查敏感文件的权限
ls -l /etc/passwd /etc/shadow /etc/sudoers

# 确保shadow文件权限为600
chmod 600 /etc/shadow

# 确保sudoers文件权限为440
chmod 440 /etc/sudoers

# 检查SSH配置文件权限
ls -l /etc/ssh/sshd_config

# 确保SSH私钥文件权限为600
find /home -name "id_rsa" -exec chmod 600 {} \; 2>/dev/null

# 检查并修复家目录权限
find /home -type d -maxdepth 1 -exec chmod 755 {} \; 2>/dev/null

课后练习

  1. 基础练习

    • 创建一个文件,使用数字表示法设置其权限为755,然后验证权限设置
    • 创建一个目录,使用数字表示法设置其权限为700,然后验证权限设置
    • 将一个脚本文件的权限设置为755,确保其可以执行
  2. 进阶练习

    • 计算并设置以下权限组合:
      • 所有者有全部权限,所属组有读取和执行权限,其他用户无权限
      • 所有者有读取和写入权限,所属组有读取权限,其他用户无权限
      • 所有用户都有读取和执行权限,但只有所有者有写入权限
    • 创建一个公共临时目录,设置权限为1777,并测试其功能
    • 编写一个脚本,批量设置目录及其内容的权限
  3. 思考问题

    • 为什么/tmp目录通常设置为1777权限?
    • 什么是最小权限原则?如何应用数字表示法实现这一原则?
    • 特殊权限(SUID、SGID、Sticky Bit)在什么情况下使用?
    • 如何根据文件类型选择合适的数字权限设置?
    • 数字表示法和符号表示法各有什么优缺点?在什么场景下使用哪种表示法更合适?

总结

本集详细介绍了Linux系统中权限的数字表示方法,包括:

  • 权限数字表示法的基本原理和计算规则
  • 常见的数字权限组合及其含义
  • 特殊权限的数字表示方法
  • 使用数字表示法设置文件和目录权限的方法
  • 权限数字与符号表示法的对应关系
  • 权限设置的最佳实践和安全考虑

数字表示法是Linux系统中管理权限的重要工具,掌握这种表示方法对于系统管理、脚本编写和自动化操作都非常重要。通过本集的学习,您应该能够理解权限数字的计算规则,熟悉常见的权限组合,并且能够根据实际需求选择合适的权限设置。

在实际应用中,数字表示法和符号表示法各有优缺点,应该根据具体场景选择合适的表示方法。对于简单的权限设置,符号表示法可能更加直观;而对于脚本编写和批量操作,数字表示法则更加简洁高效。

« 上一篇 权限管理基础 下一篇 » 权限字母表示法