4、权限管理基础:用户与组的概念、权限位模型、特权与非特权模式
好,我们进入第四章。这一章讲的是权限管理的基础,说白了就是回答一个问题:谁,能对什么,做什么。
我在做QNX系统安全审计的时候,发现很多问题其实不是漏洞多高级,而是最基础的权限模型没搞对。你想想看,一个嵌入式设备,如果连用户和组的概念都模糊,那后面的安全策略就是空中楼阁。
4.1 用户与组:谁在操作?
QNX是一个多用户操作系统,虽然很多嵌入式场景下只有一个root用户跑着,但千万别养成这个习惯。我见过一个项目,所有进程都用root跑,结果一个缓冲区溢出直接让攻击者拿到了整个系统的控制权——嗯,教训很深刻。
在QNX中,每个进程都有一个用户ID(UID)和组ID(GID)。这两个ID决定了进程能访问哪些资源。
- UID 0:超级用户(root),拥有至高无上的权限。说白了,它想删什么就删什么,想读什么就读什么。
- UID 1-99:系统保留用户,用于运行系统服务。我个人习惯把关键服务(比如网络栈、存储管理)放在这些ID下,避免和普通应用混在一起。
- UID 100+:普通用户,权限受限。你想想看,一个跑在普通用户下的进程,就算被攻破了,攻击者也拿不到系统核心数据。
组的概念类似,它是一组用户的集合。比如你可以创建一个sensor_group,只有这个组的进程才能访问某个温度传感器设备文件。
核心原则:最小权限
每个进程只分配它完成任务所需的最小权限。不要图省事全给root。
4.2 权限位模型:rwx 与 数字模式
QNX的权限位模型和POSIX标准一致,就是经典的读(r)、写(w)、执行(x)三组权限,分别对应文件所有者(owner)、同组用户(group)、其他用户(others)。
举个例子,一个可执行文件/usr/bin/sensor_daemon,权限位可能是:
-rwxr-x--- 1 root sensor_group 12345 Jan 1 12:00 /usr/bin/sensor_daemon
这表示:
- 所有者(root)可以读、写、执行
- 同组用户(sensor_group)可以读、执行,但不能写
- 其他用户没有任何权限
数字模式更简洁:rwxr-x--- 对应 750。计算方法很简单:
| 权限 | 二进制 | 数字 |
|---|---|---|
| r | 100 | 4 |
| w | 010 | 2 |
| x | 001 | 1 |
| rwx | 111 | 7 |
| r-x | 101 | 5 |
| --- | 000 | 0 |
所以 750 就是:所有者7(rwx),同组5(r-x),其他0(---)。
我的习惯: 在QNX中,我几乎不用777。哪怕是一个临时调试脚本,用完也要立刻改回755或750。曾经有一次,一个同事把日志目录设成777,结果被一个低权限进程把日志文件全删了——排查了一整天。
4.3 特权模式 vs 非特权模式
QNX的微内核架构下,特权模式和非特权模式的区别非常关键。说白了,就是你能不能直接操作硬件。
- 特权模式(内核态):运行在QNX微内核中的代码(比如进程管理器、内存管理器)拥有完全权限。它们可以直接操作MMU、中断控制器、时钟等硬件资源。
- 非特权模式(用户态):普通进程运行在这里。它们不能直接访问硬件,必须通过系统调用(比如
MsgSend()、ChannelCreate())向内核请求服务。
为什么会这样设计?你想想看,如果每个进程都能直接操作硬件,那一个进程写错了内存地址,整个系统就崩了。QNX把关键操作收归内核,用户进程只能通过消息传递来请求——这就是它高可靠性的根基。
注意: 在QNX中,即使你是root用户,你的进程默认也是运行在非特权模式下的。root只是让你有权限调用某些系统调用,但不会让你直接操作物理内存。这一点和Linux不同,QNX更严格。
我曾经遇到过一个案例:一个硬件驱动团队把驱动逻辑全写在了用户态,结果频繁出现优先级反转和死锁。后来我们把核心时序逻辑移到了内核态的一个资源管理器中,问题就解决了。嗯,这就是特权模式的价值——它保证了关键操作的原子性和实时性。
4.4 实战:如何配置一个安全的进程权限
假设我们要启动一个网络监控进程net_monitor,它需要读取网络接口状态,但不需要修改网络配置。我会这样配置:
- 创建一个专用用户
netmon和组netgroup - 将
net_monitor可执行文件的所有者设为netmon:netgroup - 权限位设为
750(所有者rwx,同组r-x,其他无) - 在启动脚本中,使用
su netmon -c "/usr/bin/net_monitor"启动
这样,即使net_monitor被攻破,攻击者也拿不到root权限,更动不了系统核心文件。
避坑指南: 我曾经见过一个项目,把setuid位设在了ping命令上。结果攻击者利用ping的一个漏洞,直接以root权限执行了任意代码。所以,慎用setuid/setgid,能用能力(capability)解决的问题,就别用setuid。
4.5 小结
这一章我们讲了三个核心概念:
- 用户与组:区分谁在操作,实现权限隔离
- 权限位模型:rwx和数字模式,控制文件/设备访问
- 特权与非特权模式:内核态 vs 用户态,保护系统核心
记住一句话:权限不是越多越好,而是越精确越好。下一章我们会深入QNX特有的能力(capability)模型,那才是QNX权限管理的精髓所在。