Linux-write-blocker, 内核补丁和用户空间工具来支持Linux软件写入阻塞

分享于 

12分钟阅读

GitHub

  繁體 雙語
The kernel patch and userspace tools to enable Linux software write blocking
  • 源代码名称:Linux-write-blocker
  • 源代码网址:http://www.github.com/msuhanov/Linux-write-blocker
  • Linux-write-blocker源代码文档
  • Linux-write-blocker源代码下载
  • Git URL:
    git://www.github.com/msuhanov/Linux-write-blocker.git
    Git Clone代码到本地:
    git clone http://www.github.com/msuhanov/Linux-write-blocker
    Subversion代码到本地:
    $ svn co --depth empty http://www.github.com/msuhanov/Linux-write-blocker
    Checked out revision 1.
    $ cd repo
    $ svn up trunk
    
    Linux写阻止程序

    内核补丁和用户空间工具来支持Linux软件写入阻塞。 用于计算机取证,事件响应和数据恢复。

    背景

    目前,没有通用的方法可以在 [vanilla] Linux中真正地读取文件系统。 例如使用"ro"选项挂载文件系统( 命令行 示例: 安装 -o ro/dev/sda1/mnt/sda1/ ) 不保证内核驱动程序不会写入相应的块设备。 根据手册页( ,mount"R"选项):

    - R,--read-only
    挂载 文件系统 只读。同义词为 -o ro。
    请注意,根据 文件系统 类型。状态和内核行为,系统仍然可以写入设备。 例如如果 文件系统 是脏的,ext3和ext4将重播日志。 如果你希望使用 ro mount 文件系统 或者ext4安装选项,或者设置块设备本身以读取只读模式,请参阅收费( 8 ) 命令。

    各种文件系统驱动程序支持额外的挂载选项以禁用恢复和/或者日志操作。 例如可以在挂载 ext3/4 文件系统"只读"时使用"ro"和"noload"挂载选项的组合禁用日志恢复,如上面的命令行 示例所示: 这是在-o服务器上执行的,但是这些选项不保护/4 文件系统,因为在"只读"文件系统( 而且没有显式的挂载选项来禁用孤立的inode删除) 上由内核驱动程序执行的自动孤立inode删除。 同样,你不能完全禁用 ReiserFS (的支持"nolog"不能在驱动程序中完全实现挂载选项- 日志重播未被这里选项禁用) 中的日志。 其他数据更改问题也可能隐藏在Linux源代码中。

    挂载文件系统"只读"的另一种方法是在运行挂载命令之前标记相应块设备( 使用blockdev或者hdparm命令将块设备标记为只读;命令行 示例:示例) blockdev --setro/dev/sda1; blockdev --setro/dev/sda 和 hdparm -r1/dev/sda1; hdparm -r1/dev/sda。 根据手册页(,,"R"选项):

    R 获取/设置设备的只读标志。 设置时,Linux不允许在设备上写入操作。

    不幸的是,这里功能不是以forensically声音方式实现的: 由文件系统驱动程序来检查基础块设备是否被标记为只读并拒绝写入该设备。 如果文件系统驱动程序缺少这些检查( 比如。 由于 Bug ),这里驱动程序发送的写入请求将成功地通过块设备驱动程序成功地通过物理驱动器。 在过去发现了以下几个问题: 内核正在将XFS超块写入只读块设备,内核正在从 nautilus/4 文件系统中删除 on。 在目前,已知 ext3/4 驱动程序将把日志中记录的错误代码传输到超级块,即使底层块设备是只读的,也会这样。 支持批处理功能的许多文件系统驱动程序允许用户空间程序丢弃文件系统未使用的( 免费) 空间,即使底层块设备是只读的。

    此外,安装文件系统并不是威胁数字证据完整性的唯一危险措施。 现代Linux发行版会自动激活 Linux RAID。伪RAID和LVM卷。 这些操作受上述所描述的问题的影响: 例如,LVM驱动程序将同步两个RAID1-like卷,如果它们不同步,这将只读取块设备。 在进行数据恢复时注意 !

    阻止可能写入块设备的最成功的尝试是使用只读循环设备。 循环设备是由独立内核驱动程序管理的块设备: 来自文件系统驱动程序的所有 I/O 请求将首先到达循环设备驱动程序,然后到达块设备驱动程序( 循环设备在这里充当代理,在文件系统驱动程序和块设备之间转换 I/O 请求和应答)。 幸好,循环设备驱动程序将停止所有写入和丢弃请求到只读块设备。 很不幸,没有简单的方法来代替循环设备来实现真正的块设备。 对于驻留在单个块设备上的文件系统( 比如。 /dev/sda1 only只能使用"ro"和"循环"挂载选项的组合,从 linux的挂载命令( 例如: 2.安装 -o ro,循环/dev/sda1/mnt/sda1/- 两个选项一起用于指定一个特定块设备,并使用它来创建一个循环设备( 这类似于下面的命令,该命令类似于以下命令: losetup R/dev/loop0/dev/sda1 ;安装 -o ro/dev/loop0/mnt/sda1/)。 但是,本机文件系统支持多种设备配置: 例如 ext3/4 文件系统支持外部日志( 文件系统在两个块设备之间拆分- 一个具有文件和目录,另一个用于日志。) 和Btrfs支持类似于( 原生,没有额外硬件或者软件层( 如 Linux RAID )的换句话说,)的RAID。 在多设备配置中,文件系统驱动程序从挂载文件系统的其他块设备( 比如 ) 中获取指向其他块设备的指针。 "logdev="。当外部日志发生时,为XFS设置) 或者从指定给挂载命令的块设备的超块。 在后一种情况下,无法强制文件系统驱动程序使用循环设备而不是块设备。 另外,Linux RAID和LVM的配置文件需要修改才能启用驻留在循环设备上的卷。

    为了支持本地多设备配置中的文件系统,我们需要更好的写阻塞方法。

    概念

    我们利用现有的设备作为读取只读,并在块设备驱动程序中将读取只添加到公共点。 这允许我们阻止来自内核驱动程序的所有写入和丢弃请求;。 我们的修改正在删除循环设备驱动程序,因为它的主要优点是停止写入和丢弃请求。

    特别是在将写入或者丢弃请求发送到只读块设备时,我们将修改 generic_make_request_checks函数并插入用于结束处理的代码。 这种修改允许我们在块设备驱动程序的最低级别上拦截写入和丢弃请求。

    如何安装

    将补丁应用到内核的源代码并重新编译它。

    补丁最初是为 Linux 3.15.1编写的,但它仍然与一些较新版本的Linux兼容。 此外,Linux 4.10的新版本可用。

    :如何使用

    只需运行以下命令: blockdev --setro/dev/sdb* ( 假设 /dev/sdb 是写入 protected的证据)。

    重要提示:始终将父块设备标记为只读 ! 将一个特定分区标记为只读是不够的。

    可能的缺点

    比赛条件

    操作系统可以在将相应的块设备标记为只读之前写入驱动器。 考虑禁用自动挂载文件系统和自动激活 Linux RAID。假RAID和LVM卷。

    实时发行版( Live CD,Live USB )的问题。

    许多动态发行版在引导( 如果你需要在一个文件系统中搜索特定的签名或者在指定的文本文件中搜索一个可以引导的媒体,那么可以使用一个特定的目录来加载一个文件) 期间自动在各种驱动器上挂载文件系统。 考虑在初始RAM文件系统( initramfs ) 中将所有块设备标记为只读之前,将尝试定位可以引导介质。

    注意,即使在操作系统加载后没有看到块设备挂载,也可以在早期的( 在启动过程的开始阶段) 中挂载和卸载块设备。

    当建立基于Debian或者Ubuntu的实时发行版时,请注意这一点 !

    同时,确保你的实时发布永远不会从证据驱动程序中执行程序。

    恼人的行为

    修补程序成功阻止将刷新请求发送到设备。 一些程序(。比如。部分) 不喜欢这个,并且抛出恼人但无害的异常;你可以安全地忽略它们。

    如果使用内置的ntfs-3g驱动程序挂载文件系统遇到任何问题,请确保包含"ro"挂载选项( 使用安装 -t ntfs-3g -o ro/dev/sda1/mnt/sda1/,而不是安装 -t ntfs-3g/dev/sda1/mnt/sda1/)。

    磁盘分区的问题

    当一个新分区出现在系统中时,udev规则( 请参见下面) 标记它和一个对应的父块设备作为读取。 因此在磁盘上新建分区将导致磁盘上立即启用写阻塞。

    内存修改中的

    尽管文件系统驱动程序不能到达物理驱动器,但是对由文件系统驱动程序所做的挂载文件系统所做的一些更改可以。 在这种情况下,使用用户空间程序读取"已经修改"数据块( 比如。 数据存储程序or或者 md5sum md5sum会导致用户空间程序和实际存储在驱动器上的数据之间的不一致,换句话说,用户空间程序将从缓存( 包含来自驱动程序的修改) 获取字节,而不是从驱动器( 这里无修改)。 卸载文件系统将使事情恢复正常。

    用户空间助手

    这里知识库中有几个用户空间助手:

    • 01wrtblk_all: 将所有可用块设备的( 循环设备除外) 标记为只读的脚本;
    • wrtblk: 标记指定块设备的脚本( 比如。 ;"或者或或者"sdc") 及其父块设备作为只读;
    • wrtblk禁用: 将指定块设备及其父块设备标记为读
    • wrtblk-ioerr: 将指定块设备及其子块设备标记为只读的脚本;
    • system - config - 01-forensic-readonly.rules: 使用 wrtblk脚本标记新块设备,并使用脚本来标记出现错误的块设备,以及使用 wrtblk ioerr脚本( 警告:警告: 内部硬编码路径)。

    限制

    其他程序可以绕过任何活动软件写阻止程序。 特别是,修补程序不保护设备against通过 SG_IO 接口( 这里接口允许程序向设备发送任意SCSI命令) 发送的写命令。 因此,在运行来自 sg3_utils的命令时,要注意更改设备( 使用的是SG_IO接口) 上的数据。

    有关进一步讨论,请参阅这里存储库中的研究目录。

    性能降低

    应用修补程序后未检测到性能下降。

    命令行调试

    这个存储库包含简单的内核 MODULE ( forensic ) 来记录点击 generic_make_request_checks 函数( 感谢的subsystem子系统)的所有写和丢弃请求。 点击这里函数比在 submit_bio 中拦截请求更好。

    这里 MODULE 不再受支持 !

    验证

    请参见这里知识库中的验证目录。

    作者

    Maxim Suhanov


    tool  USE  用户  Block  users  内核  
    相关文章