Windows Server 2019 自定义只读iSCSI目标(物理磁盘导出)
Windows Server 2019 自定义只读iSCSI目标实现方案指导
核心需求回顾
- 将物理磁盘
\.\PhysicalDriveX以无VHD/VHDX封装的方式导出 - 客户端识别为本地SCSI磁盘,可见完整GPT/MBR分区布局
- 严格拦截所有WRITE类SCSI命令,确保磁盘只读
技术问题解答
1. 用户态实现 vs 内核态驱动必要性
用户态(Winsock+原始磁盘读取)无法满足需求,必须结合内核态虚拟SCSI驱动实现:
- 用户态程序无法向Windows存储栈注册虚拟SCSI设备,客户端iSCSI发起方无法将其识别为本地磁盘(仅能通过自定义应用访问,不符合“本地SCSI磁盘”的要求)。
- 完整的SCSI设备模拟需要处理大量底层命令(如
INQUIRY、MODE SENSE、READ CAPACITY等),用户态实现难以覆盖所有规范场景,且性能、稳定性远不如内核态驱动。 - 原始磁盘的只读访问在用户态存在权限和缓存风险,内核态驱动可通过更严格的打开参数(如
FILE_READ_ACCESS+FILE_FLAG_NO_BUFFERING)避免意外写入。
正确的架构是:用户态处理iSCSI协议的网络PDU交互,内核态虚拟SCSI驱动负责模拟SCSI设备、拦截WRITE命令、对接原始磁盘的只读读取。
2. 所需组件与工具
- Windows Driver Kit (WDK) 1903+:用于开发基于StorPort框架的虚拟SCSI内核驱动,这是实现虚拟磁盘设备的核心工具。
- Windows SDK 1903+:用于开发用户态iSCSI服务,处理Winsock网络通信、iSCSI PDU编解码。
- WinDbg:用于内核驱动的调试与问题排查,确保驱动稳定性。
- 可选参考:Windows Server 2019自带的iSCSI Target角色,可参考其协议交互逻辑,但无需依赖该角色运行自定义实现。
3. SCSI层只读实现的安全性
在SCSI层严格拦截WRITE命令,结合内核态只读磁盘访问,架构上可完全确保磁盘不被损坏:
- 驱动层面:以只读权限打开
\.\PhysicalDriveX,系统会拒绝任何写入请求的底层调用,从根源上阻断写入路径。 - SCSI命令层面:拦截所有WRITE类命令(包括
WRITE(10)、WRITE(16)、WRITE SAME等),直接返回CHECK CONDITION状态码,让客户端感知只读限制。 - 双重保障:即使驱动逻辑出现疏漏,只读打开的磁盘句柄也无法执行写入操作,不会损坏原始磁盘数据。
架构实现路径指导
1. 内核态虚拟SCSI驱动开发
- 基于StorPort框架创建虚拟SCSI目标设备,实现SCSI命令处理回调。
- 针对所有WRITE类命令,直接返回
SCSI_STATUS_CHECK_CONDITION,并设置对应的Sense Key(如DATA_PROTECT)。 - 以
FILE_READ_ACCESS、FILE_FLAG_NO_BUFFERING、FILE_FLAG_WRITE_THROUGH参数打开\.\PhysicalDriveX,确保只读访问。 - 处理READ类命令时,从原始磁盘读取数据并返回给用户态服务。
2. 用户态iSCSI服务开发
- 基于Winsock创建TCP监听端口(默认iSCSI端口3260),处理客户端的iSCSI连接请求。
- 实现iSCSI协议的PDU编解码,将客户端发送的SCSI命令转发给内核态驱动。
- 接收驱动返回的读取数据或命令状态,打包为iSCSI响应PDU发送给客户端。
- 处理iSCSI会话管理、登录、注销等流程,符合RFC 3720规范。
3. 权限与安全配置
- 内核驱动需签名(测试阶段可启用测试签名模式,生产环境需EV代码签名)。
- 用户态服务需运行在具有磁盘读取权限的账户下,但需限制其写入权限,避免越权操作。
- 客户端侧配置iSCSI发起方,连接到自定义目标的IP与端口,完成磁盘枚举后验证只读属性。
4. 测试验证
- 验证客户端磁盘管理器中显示为本地SCSI磁盘,可见完整GPT/MBR分区布局。
- 尝试通过磁盘写入工具(如
diskpart、dd)写入磁盘,确认操作被拒绝。 - 检查原始磁盘的修改时间与数据完整性,确保无写入操作发生。
内容的提问来源于stack exchange,提问作者andrew
相关产品推荐
相关产品推荐

