A pure Rust iSCSI target implementation for building custom storage solutions.
iscsi-target is a library that provides a reusable iSCSI target server. Users implement the ScsiBlockDevice trait to provide their own storage backend (in-memory, file-based, network-attached, etc.), and the library handles all iSCSI and SCSI protocol details.
- Full iSCSI Protocol Support: Login, logout, discovery sessions, normal sessions
- SCSI Block Commands: READ(6/10/16), WRITE(6/10/16), INQUIRY, READ CAPACITY(10/16), TEST UNIT READY, MODE SENSE, SYNCHRONIZE CACHE, REQUEST SENSE, REPORT LUNS, VERIFY
- CHAP Authentication: One-way and mutual CHAP support for secure connections
- Discovery Sessions: SendTargets protocol for target discovery
- Write Operations: Immediate data and multi-PDU Data-Out support
- Real-World Tested: Verified with Linux open-iscsi and iscsiadm
- Builder Pattern API: Easy configuration and setup
Add to your Cargo.toml:
[dependencies]
iscsi-target = "0.1.0"Create a simple in-memory target:
use iscsi_target::{IscsiTarget, ScsiBlockDevice, ScsiResult};
struct MemoryStorage {
data: Vec<u8>,
}
impl ScsiBlockDevice for MemoryStorage {
fn read(&self, lba: u64, blocks: u32, block_size: u32) -> ScsiResult<Vec<u8>> {
let offset = (lba * block_size as u64) as usize;
let len = (blocks * block_size) as usize;
Ok(self.data[offset..offset + len].to_vec())
}
fn write(&mut self, lba: u64, data: &[u8], block_size: u32) -> ScsiResult<()> {
let offset = (lba * block_size as u64) as usize;
self.data[offset..offset + data.len()].copy_from_slice(data);
Ok(())
}
fn capacity(&self) -> u64 {
(self.data.len() / 512) as u64
}
fn block_size(&self) -> u32 {
512
}
fn flush(&mut self) -> ScsiResult<()> {
Ok(())
}
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let storage = MemoryStorage {
data: vec![0u8; 100 * 1024 * 1024], // 100 MB
};
let target = IscsiTarget::builder()
.bind_addr("0.0.0.0:3260")
.target_name("iqn.2025-12.local:storage.disk1")
.build(storage)?;
target.run()?;
Ok(())
}# Discover targets
sudo iscsiadm -m discovery -t sendtargets -p 127.0.0.1:3260
# Login to target
sudo iscsiadm -m node -T iqn.2025-12.local:storage.disk1 -p 127.0.0.1:3260 --login
# Find device
lsblk
# Use the device (e.g., /dev/sdb)
sudo mkfs.ext4 /dev/sdb
sudo mount /dev/sdb /mnt/iscsiThe examples/ directory contains several examples:
- simple_target.rs - Basic in-memory storage target
- chap_target.rs - One-way CHAP authentication example
- mutual_chap_target.rs - Mutual CHAP authentication example
- discover_targets.rs - Discovery session client
- graceful_shutdown.rs - Handling shutdown signals
- inspect_pdu_serialization.rs - PDU serialization debugging tool
Run an example:
cargo run --example simple_targetEnable CHAP authentication for secure connections:
use iscsi_target::{IscsiTarget, AuthConfig};
let auth = AuthConfig::new_oneway_chap("username", "password123");
let target = IscsiTarget::builder()
.bind_addr("0.0.0.0:3260")
.target_name("iqn.2025-12.local:storage.secure-disk")
.auth_config(Some(auth))
.build(storage)?;- INQUIRY (Standard and VPD pages)
- READ CAPACITY (10/16)
- READ (6/10/16)
- WRITE (6/10/16)
- TEST UNIT READY
- MODE SENSE (6/10)
- REQUEST SENSE
- REPORT LUNS
- SYNCHRONIZE CACHE (10/16)
- START STOP UNIT
- VERIFY
- API Documentation
- Implementation Guide
- CHAP Authentication
- RFC 3720 Implementation
- Project Status
- Roadmap
- Testing Guide
Run unit tests:
cargo test --libRun integration tests:
cargo testCurrent test status: 55 tests passing, 0 failures
- Rust 1.82 or later (2021 edition)
- Linux (for testing with open-iscsi)
- Standard iSCSI port 3260 (or use custom port)
byteorder- Binary protocol parsingthiserror- Error handlinglog- Logging frameworkmd5- CHAP authenticationrand- Challenge generationhex- Hex encoding
Current version: 0.1.0
- Core iSCSI protocol: Complete
- SCSI commands: Complete for basic operations
- Write operations: Complete with immediate data and multi-PDU support
- CHAP authentication: Complete (one-way and mutual)
- Discovery sessions: Complete
- Real-world testing: Verified with Linux initiators
See PROJECT_STATUS.md for detailed status.
Licensed under either of:
- MIT License (LICENSE-MIT or http://opensource.org/licenses/MIT)
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
at your option.
Contributions are welcome! Please see the documentation for architectural details and implementation guidelines.
https://github.com/lawless-m/iscsi-crate
Matt Lawless