Skip to content

lawless-m/iscsi-crate

Repository files navigation

iscsi-target

A pure Rust iSCSI target implementation for building custom storage solutions.

Overview

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.

Features

  • 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

Quick Start

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(())
}

Connecting from Linux

# 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/iscsi

Examples

The 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_target

CHAP Authentication

Enable 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)?;

Supported SCSI Commands

  • 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

Documentation

Testing

Run unit tests:

cargo test --lib

Run integration tests:

cargo test

Current test status: 55 tests passing, 0 failures

Requirements

  • Rust 1.82 or later (2021 edition)
  • Linux (for testing with open-iscsi)
  • Standard iSCSI port 3260 (or use custom port)

Dependencies

  • byteorder - Binary protocol parsing
  • thiserror - Error handling
  • log - Logging framework
  • md5 - CHAP authentication
  • rand - Challenge generation
  • hex - Hex encoding

Project Status

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.

License

Licensed under either of:

at your option.

Contributing

Contributions are welcome! Please see the documentation for architectural details and implementation guidelines.

Repository

https://github.com/lawless-m/iscsi-crate

Author

Matt Lawless

About

iSCSI target implementation in pure Rust

Resources

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Generated from lawless-m/claude-skills