3. 权限管理基础:用户与组管理、文件系统权限、特殊权限位

好,咱们进入第三章。这一章讲的是权限管理,说白了就是「谁能在系统里干什么」。我在QNX上栽过最大的跟头,十有八九都和权限有关。你想想看,一个嵌入式设备跑着跑着突然挂了,结果一查是某个进程权限给多了,被人钻了空子。嗯,这种事我遇到过不止一次。

3.1 用户与组管理:QNX里的身份体系

QNX的用户管理,和Linux很像,但又不完全一样。它本质上是一个POSIX兼容的系统,所以用户(User)和组(Group)的概念是通用的。

用户就是一个个的身份标识。每个进程、每个文件,都得有个主人。QNX系统里默认有个 root 用户,UID是0。这个用户啥都能干,我一般只在调试阶段才用root跑东西。生产环境里,我习惯给每个服务创建一个专用用户。

就是用户的集合。你可以把一堆用户塞到一个组里,然后统一给这个组授权。比如,调试人员一个组,运维人员一个组,各管各的。

常用的管理命令就这几个:

# 查看当前用户
whoami

# 查看用户ID和组ID
id

# 添加用户(需要root权限)
passwd -a myuser

# 添加组
groupadd mygroup

# 把用户加到组里
usermod -G mygroup myuser
我的习惯: 在QNX上,我从来不用 useradd,因为QNX的 passwd -a 更稳定。有一次我在一个老版本QNX上用了 useradd,结果用户是创建了,但家目录没生成,搞得我排查了半天。

3.2 文件系统权限:ugo/rwx 模型

文件权限,这是权限管理的核心。QNX用的是经典的UNIX权限模型:ugo/rwx

ugo 代表三类对象:

  • u:文件所有者(user)
  • g:文件所属组(group)
  • o:其他人(others)

rwx 代表三种权限:

  • r:读权限(4)
  • w:写权限(2)
  • x:执行权限(1)

你看一个文件权限,比如 -rwxr-xr--,怎么拆解?

位置 含义
第1位 文件类型(- 普通文件,d 目录) -
第2-4位 所有者权限(u) rwx (7)
第5-7位 组权限(g) r-x (5)
第8-10位 其他人权限(o) r-- (4)

说白了,这个文件所有者能读写执行,同组的人只能读和执行,其他人只能读。

修改权限用 chmod

# 数字法:给所有者所有权限,组读+执行,其他人读
chmod 754 myfile

# 符号法:给所有者加执行权限
chmod u+x myfile

# 递归修改目录权限
chmod -R 755 mydir/
注意: 在QNX上,chmod -R 对某些特殊文件系统(比如 /proc)可能会报错。我曾经在脚本里直接对整个根目录递归改权限,结果系统直接挂了。千万别这么干。

3.3 特殊权限位:SUID、SGID、Sticky Bit

普通权限之外,还有三个特殊权限位。它们不常用,但一旦用错,就是安全漏洞。

3.3.1 SUID(Set User ID)

SUID 位的作用是:当一个可执行文件设置了SUID,其他用户运行它时,会临时拥有文件所有者的权限。

举个例子,/usr/bin/passwd 这个命令就设置了SUID。普通用户运行它,可以修改自己的密码,而密码文件 /etc/shadow 只有root能写。为什么普通用户能改?就是因为 passwd 有SUID位,运行时临时变成了root身份。

设置SUID:

chmod u+s myprogram
# 或者用数字法:4xxx
chmod 4755 myprogram
避坑指南: 我曾经在项目里给一个网络服务程序设置了SUID,想着方便它读写配置文件。结果被安全审计发现了,说这是严重漏洞。因为一旦这个程序被攻破,攻击者就能以root身份执行任意代码。所以,非必要不设SUID

3.3.2 SGID(Set Group ID)

SGID 和 SUID 类似,但作用在组上。文件设置了SGID,运行时临时拥有文件所属组的权限。

SGID 还有一个特殊用途:用在目录上。如果目录设置了SGID,那么在这个目录下创建的新文件,会自动继承目录的组,而不是创建者的默认组。这在团队协作中很有用。

设置SGID:

chmod g+s mydir
# 数字法:2xxx
chmod 2755 mydir

我记得有一次,一个团队在共享目录里写代码,结果每个人创建的文件组都不一样,权限乱成一锅粥。后来我给目录加了SGID,问题就解决了。说白了,就是让新文件「认祖归宗」。

3.3.3 Sticky Bit(粘滞位)

Sticky Bit 只对目录有效。设置了粘滞位的目录,用户只能删除自己的文件,不能删别人的。

最典型的例子就是 /tmp 目录。任何人都能往 /tmp 里写文件,但你不能删别人的临时文件。

设置Sticky Bit:

chmod o+t /tmp
# 数字法:1xxx
chmod 1777 /tmp
检查特殊权限:ls -l 查看时,SUID 显示为 s(在所有者执行位),SGID 显示为 s(在组执行位),Sticky Bit 显示为 t(在其他人执行位)。如果看到大写 ST,说明对应的执行位没设置,权限配置有问题。

3.4 实战:一个安全的权限配置示例

假设我们要部署一个QNX上的服务程序 my_service,它需要读写 /var/log/myapp/ 目录下的日志文件。我的做法是这样的:

# 1. 创建专用用户和组
passwd -a myapp
groupadd myappgroup
usermod -G myappgroup myapp

# 2. 设置程序文件权限
# 所有者是root,组是myappgroup
# 只有root能改,组内用户能执行,其他人不能碰
chown root:myappgroup /usr/bin/my_service
chmod 750 /usr/bin/my_service

# 3. 设置日志目录权限
# 所有者是myapp,组是myappgroup
# 所有者能读写执行,组内用户能读写,其他人不能碰
mkdir -p /var/log/myapp
chown myapp:myappgroup /var/log/myapp
chmod 770 /var/log/myapp

# 4. 绝对不设SUID/SGID
# 如果程序需要提权,用QNX的procmgr或权限代理机制

你看,这样配置下来,my_service 只能由 myapp 用户或 myappgroup 组的成员运行,日志也只有这些人能读写。就算程序被攻破,攻击者也拿不到root权限。

嗯,这一章的内容就这些。权限管理看着简单,但细节里全是坑。下一章我们聊聊更高级的QNX特有安全机制,到时候你就知道为什么我总说「权限是安全的第一道防线」了。