网络安全 03:Linux 用户、权限与最小暴露

文件在磁盘上存在,并不意味着任何进程都应该能够读取它。Linux 的访问检查与进程身份、文件所有者、组和权限位有关。理解这一点,才能判断一个服务究竟能读什么、改什么。

本篇只在配套容器的临时目录里操作,不修改宿主 SSH、防火墙或账户设置。

一、先确认“谁在执行”

在仓库根目录执行:

./bin/site.sh security-up
./bin/site.sh security-shell

接下来直到 exit 都是在容器内:

id
pwd
umask

预期 UID 为 10001,而不是 root。权限判断关注的是进程的有效身份,不是你的终端窗口显示了什么名字。实验镜像故意使用普通用户,这样权限被撤销时,程序确实会遭遇拒绝。

umask 影响新建文件的默认权限,不会追溯修改已存在的文件。它对初始申请权限做位屏蔽:普通文件通常从 666 出发,目录通常从 777 出发。例如常见 022 屏蔽组与其他人的写权限,并不凭空给普通文件增加执行位。

二、读懂 rwx 与数字模式

-rw-------  owner group ... private.txt
││ │ │
││ │ └── 其他人
││ └───── 所属组
│└──────── 所有者
└───────── 文件类型

每一组三个位分别是 r=4、w=2、x=1,相加得到一位八进制数。600 表示所有者可读写,组与其他人没有权限;700 常用于只允许所有者访问的目录。

权限 普通文件 目录
r 读取内容 列举条目名字
w 修改内容 与适当的 x 配合创建、删除、重命名条目
x 尝试作为程序执行,仍需合法格式/解释器等条件 搜索、穿越目录路径

删除文件主要受其父目录权限控制,不是简单看文件本身有没有写位。ACL、特殊权限、挂载选项和特权能力会进一步影响行为;本篇先固定在普通用户和基础权限位这个范围。Linux 路径解析与权限说明

三、实验 A:拒绝读取,再恢复最小权限

在容器 shell 中逐行执行:

work=$(mktemp -d /tmp/security-permissions.XXXXXX)
printf 'fictional training note\n' > "$work/private.txt"
chmod 600 "$work/private.txt"
ls -l "$work/private.txt"
cat "$work/private.txt"

chmod 000 "$work/private.txt"
cat "$work/private.txt"

最后一条应出现 Permission denied,这是实验预期,不是需要绕过的故障。

chmod 600 "$work/private.txt"
cat "$work/private.txt"

恢复为 600 后可以重新读取。所有者即使暂时不能读文件,通常仍能修改这个文件的权限。这里不需要把权限改成 777。

**记录:**修改前后的 ls -l、当前 id、哪一步成功或失败,以及为什么同一个路径结果会变化。

四、实验 B:目录 x 位与路径穿越

mkdir "$work/box"
printf 'inside\n' > "$work/box/note.txt"
chmod 600 "$work/box"
ls "$work/box"
cat "$work/box/note.txt"

没有 x 位时,列出名字与访问名字指向的文件是两回事。cat 应失败;不要用“我已经能看到名字”推断自己一定能读取内容。

chmod 700 "$work/box"
cat "$work/box/note.txt"

恢复目录 x 位后,再解释为什么结果改变。这里的 700 是目录权限,和普通文件的可执行意义不同。

五、把文件权限联系到服务权限

一个 Web 服务的能力可以按三个问题分开检查:

  1. 身份:进程以哪个 UID/GID 运行?
  2. 资源:哪些目录可写?是否挂载了宿主敏感目录?
  3. 可达性:哪些端口被发布给了谁?

本实验 Compose 中的普通 UID、只读 root、临时 /tmp 和回环端口分别约束不同边界。容器内监听 0.0.0.0:8080 与宿主只发布 127.0.0.1:18080 可以同时成立,因为它们属于不同网络命名空间。

避免把“跑在 Docker 里”当作自动安全的证明。例如挂入 Docker socket、给予过多能力或把敏感目录可写挂载进去,会改变它拥有的权限。这里没有这些挂载。容器隔离也不是对内核漏洞的绝对保证。

六、清理与复习

仍在同一个容器 shell 中:

rm "$work/box/note.txt" "$work/private.txt"
rmdir "$work/box" "$work"
exit

随后回到仓库终端,可继续下一篇,或执行 ./bin/site.sh security-down。实验文件只存在于这次容器的临时文件系统。

自测:为什么不把所有权限错误都修成 chmod 777?

这样会把读写或目录遍历能力给不需要它的身份,掩盖实际的所有权、组或路径问题。应先确定哪个进程需要什么操作,再授予对应身份需要的最小权限。本实验只需恢复所有者的权限。

自测:文件只读,就一定不能被删除吗?

不一定。删除涉及父目录中的条目;需要结合父目录写与搜索权限、sticky bit 等约束判断。不要把文件写权限与目录条目管理混为一谈。

下一篇:Web 对象越权、SQL 注入与修复验证。返回学习路线。

知识共享许可协议