WAFL与系统安全

WAFL —— NetApp的文件服务器

WAFL:Write Anywhere File Layout —— NetApp 设计的企业级文件系统

  1. 设计目标
    • 请求服务速度快:吞吐率(op/s)更多,I/O带宽更高
    • 支持大文件系统,且文件系统不断增长
    • 高性能软件RAID
    • 宕机后快速恢复
  2. 独特之处
    • 磁盘布局受 LFS 启发
    • 引入快照
    • 使用 NVRAM 记录日志(写前日志)

inode、间址块和数据块

  1. WAFL 使用4KB块
    • inode:借鉴 UNIX FS
    • 16个指针(64B)用于文件块索引
  2. 文件大小 <= 64B
    • 文件数据直接存储在 inode中
  3. 文件大小 <= 64KB
    • inode存储在16个指向数据块的指针
  4. 文件大小 <= 64MB
    • inode存储在16个指向间址块的指针
    • 每个间址块存储1024个指向数据块的指针
  5. 文件大小 > 64MB
    • inode存储在16个指向二级间址块的指针

WAFL的磁盘布局

  1. 主要数据结构
    • 一个根 inode:整个FS的根,位于磁盘上固定位置
    • 一个inode file:包含所有inode
    • 一个block map file:指示所有空闲块
    • 一个i-node map file:指示所有空闲inode

为什么将元数据存储于文件中?

  1. 元数据块可以写在磁盘上任何位置
    • 这是"WAFL"名字的由来,Write Anywhere File Layout
  2. 使得动态增加文件系统的大小变得容易
    • 增加一个磁盘会引发inode个数的增加
    • inode保存在文件,扩展inode文件大小即可
  3. 能够通过 Copy-on-Write 来创建快照
    • COW:未写前共享数据,写时拷贝
    • 新的数据和元数据都可以COW写到磁盘上的新位置
    • 固定元数据位置无法使用COW,否则无法定位元数据

快照(snapshot)

  1. 快照是文件系统的一个只读版本 – 1993 年提出
    • 成为文件服务器必备特性
  2. 快照用法
    • 系统管理员配置快照的个数和频率
    • 最初系统能支持 20 个快照
    • 用快照可以恢复其中任何一个文件

快照的实现

WAFL:所有的块构成一棵树

  1. 创建快照
    • 复制根 inode
    • 新的根 inode 用于当前的 Active FS
    • 旧的根 inode 指向快照
  2. 创建快照之后
    • 第一次写一个块: 把从它到根的数据块都复制(COW)
    • Active FS 的根 inode 指向新数据块
    • 写数据块
    • 后续对这些数据块的写不再触发 COW
  3. 每个快照都是一个一致状态的只读 FS

快照数据结构

Block Map File —— 每个 4KB 磁盘块对应一个 32位的表项

  1. 表项值为0:该块为空闲块
  2. 第0位=1:该块属于活动文件系统
  3. 第1位=1:该块属于第一个快照
  4. 第2位=1:该块属于第二个快照

...

快照创建

  1. 问题
    • 创建快照时,除了拷贝根inode,需要把缓存的文件块写回磁盘
    • 此时,可能仍然有很多文件写请求到来
    • 若这些写请求都不处理,会导致文件系统长时间挂起
  2. WAFL的解决方案
    • 在创建快照前,将块缓存中的脏块标记为"in-snapshot",表示要写回磁盘
    • 所有对"in-snapshot"缓存块的修改请求被挂起
    • 没有标记为"in-snapshot"的缓存数据可以修改(即处理写请求),但不能写回磁盘
    • 本质:区分需要被写回的脏块和其他块,减少挂起的写请求数量
    • 步骤
      • 为所有"in-snapshot"的缓存块分配磁盘空间
        • 包括数据、inode
      • 更新 block map file
        • 对每个表项,将 Active FS位的值(即1)拷贝到新快照位
      • 刷回
        • 把所有的"in-snapshot"缓存块写到它们新的磁盘位置
        • 每写回一个块,重启它上面被挂起文件请求
      • 复制根inode
    • 性能较快

快照删除

  1. 删除快照的根inode
  2. 清除block map file中的位
    • 对于block map file的每一个表项,清除与该快照对应的位

文件系统一致性

  1. 定期创建一致点
    • 一致点:存储控制器中使用 NVRAM 缓存的数据被刷回磁盘,并更新了文件系统中相应的指针
    • 每10秒创建一个一致点
    • 特殊的内部快照,用户不可见
  2. 在一致点之间的多个请求
    • 第i个一致点
    • 若干写操作
    • 第 i+1 个一致点(自动增长)
    • 若干写操作
    • ...
  3. 宕机恢复
    • 将文件系统恢复到最后一个一致点
    • 最后一个一致点之后到宕机前的写操作:靠日志进行恢复

非易失RAM(Non-Volatile RAM)

  1. NVRAM
    • 闪存:写比较慢 vs NVRAM
    • 带电池的 DRAM:快
      • 电池容量有限,持续时间不长
      • DRAM容量有限
  2. 日志写入 NVRAM
    • 记录自上一个一致点以来的所有写请求
    • 正常关机:先停止 NFS 服务,再创建一个快照,然后关闭 NVRAM
    • 宕机恢复:用 NVRAM 中的日志来恢复从最后一个一致点以后的修改
  3. 使用两个日志
    • 一个日志写回磁盘时,另一个日志写入 NVRAM 中缓冲
    • 可以避免写日志时,无法处理新的写请求

安全保护

安全与保护

  1. 数据机密性:未经许可,不能看到数据
    • 任何用户不能读写其他用户的文件
  2. 数据完整性:未经许可,不能修改或删除数据
    • 数据在网络传输过程中被拦截和修改,可以采用加密
  3. 系统可用性:干扰系统使得它不可用
    • 给一个服务器发送大量的请求

保护:策略与机制

  1. 安全策略:定义目标,即要达到的效果
    • 通常是一组规则,定义可接受的行为和不可接受的行为
    • 例子
      • /etc/password 文件只有 root 能写
      • 每个用户最多只能用 50GB 的磁盘空间
      • 任何用户都不允许读其他用户的 mail 文件
  2. 机制:用什么样的方法来达到目标

保护机制

  1. Authentication(身份认证)
    • 验明身份
      • UNIX:密码/口令
      • 类比机场:身份证或护照
  2. Authorization(授权)
    • 决定"A是不是准许做某件事"
    • 通常使用角色(role)定义授予的操作权限,使用简单的数据库保存角色定义
  3. Admission Control(访问控制)
    • 做出“访问是否准许”的决定
    • 有时和系统承载压力相关联,系统负载高时,进行访问控制

身份认证

  1. 通常是用密码来验证
    • 一串字符(字母 + 数字)
    • 用户必须记住密码
  2. 密码是以加密形式存储
    • 使用一种单向的“安全Hash”算法
  3. 缺点
    • 每个用户都要记很多密码
    • 弱密码风险,"dictionary attack"

访问控制表(ACL)

  1. 每个对象有一个 ACL 表
    • 定义每个用户的权限
    • 每个表项为 <user,privilege>
  2. 简单,大多数系统都采用
    • UNIX 的 owner,group,other
  3. 实现
    • ACL 实现在内核中
    • 在登录系统时进行身份验证
    • ACL 存储在每个文件中或文件元数据中
    • 打开文件时检查 ACL

Capabilities

  1. 超级用户具有特权,可以执行高权限操作
    • 例如passwd,chown,chmod等
  2. 权能:将超级用户特权细分,分成不同的、细粒度权限
    • CAP_CHOWN: 对文件 UIDs 和 GIDs 做修改
    • CAP_KILL: 绕过发送信号时的权限检查
    • CAP_NET_ADMIN: 执行多种网络有关的操作
  3. 可以为每个线程独立设置权能
  4. 实现
    • 权能表保存在内核

访问控制

  1. 需要一个可信权威
    • 进行访问控制
    • ACL或权能表都需要保护
  2. 内核是一个可信权威
    • 内核什么事可以做
    • 如果有 bug ,整个系统都可能被破坏
    • 它越小、越简单越好
  3. 安全的强度由保护系统链上最薄弱的环节决定

一些简单的攻击

  1. 滥用合法权利
    • UNIX: root能做任何事情
      • 例如:读你的 mail 文件, 以你的身份发送email, 把你的邮箱删除, ...
  2. 拒绝服务(DoS)
    • 耗尽系统所有资源
    • 例如
      • 运行一个 shell 脚本:while (1) {mkdir foo; cd foo;}
      • 运行一个 C 程序:while (1) {fork(); malloc(1000)[40]=1;}
  3. 偷听
    • 侦听网络上传输的包