访问控制
访问控制
访问控制
访问控制
进程 + 虚拟内存已经实现了隔离
进程只能以 ELF 规定的权限访问自己的虚拟地址空间
系统调用是
唯一
访问操作系统对象的途径
(假设,内核没有被漏洞攻破)
操作系统还有虚拟化机制:虚拟机、容器 (cgroups, namespaces, ...)
访问控制:
限制程序对操作系统对象的访问
拒绝越权访问
→
\to
→
Confidentiality
拒绝越权修改
→
\to
→
Integrity
(再加上公平资源调度
→
\to
→
Availability)
访问控制
访问控制原理:一张表
进程
对象
访问
权限
1
/etc/passwd
read
1
/etc/passwd
write
4132
/etc/passwd
write
4132
/tmp/hello.txt
write
“谁能怎么访问什么”
越权访问,直接返回 EACCESS (Permission denied)
缺点:这个表
非常大
,而且很难维护
我们需要一个更简单的机制
访问控制
UNIX: 用整数表示身份
uid, gid, mode
uid = 0
→
\to
→
root, 其他都是 “普通用户”
root 可以访问所有对象,也可以 setuid
子进程继承父进程的 uid
gid “完全自由” (虽然一般 0 是 root)
一个用户可以属于多个组
mode: r, w, x 的权限
例子:owner 只写不可读,audit 组可以读的日志文件
操作系统完全看不到用户名
通过 setuid, setgid, chmod 系统调用实现访问控制
访问控制
/etc/passwd: 每行一个用户
username:password:uid:gid:comment:home:shell
现代系统通常使用 shadow 文件存储密码的 hash
chsh, passwd 只是直接修改了文件
操作系统就真的只管 uid,不管如何解读 “用户”
访问控制
UID:没有那么简单
没有 system (abstraction) 能逃脱成为
Real uid (ruid)
Saved uid (suid)
为了实现 “恢复权限” 而设计
Effective uid (euid)
这是实际访问控制使用的 uid
Filesystem uid (fsuid)
(Since Linux 1.2,已经没人用了
)
chmod +s (ls -l /bin/passwd)
Setuid demystified
访问控制
回到访问控制
进程
对象
访问
权限
4132
/etc/passwd
write
uid, gid, mode 并不是实现访问控制的唯一方法
Access Control List (ACL)
基于 xattr 实现,支持为任意数量的用户和组设置权限
SELinux/AppArmor
sudo apparmor_status | ag --gpt -q Explain
Capabilities
capsh --drop=cap_net_raw -- -c 'ping 127.0.0.1' (注意这是 fail on execve; getcap 查看 capabilities)