AlmaLinux

Set up iSCSI Target and Initiator on Rocky Linux 10 / AlmaLinux 10

iSCSI (Internet Small Computer Systems Interface) is a transport layer protocol that allows block-level storage to be shared over a TCP/IP network. It enables servers to access remote storage as if it were a local disk. The server exporting the storage is the iSCSI target, and the server consuming it is the iSCSI initiator. This is widely used in virtualization, database storage, and SAN environments where dedicated Fibre Channel infrastructure is too expensive.

This guide walks through setting up an iSCSI target and initiator on Rocky Linux 10 / AlmaLinux 10 using targetcli for the target side and iscsi-initiator-utils for the initiator. We use two servers – a target server (10.0.1.10) that exports a 5GB disk image, and an initiator server (10.0.1.11) that connects and mounts it. The iSCSI protocol uses TCP port 3260. For full details, see the Linux-iSCSI project documentation.

Prerequisites

  • 2 servers running Rocky Linux 10 or AlmaLinux 10
  • Target server: 10.0.1.10 – the server exporting storage
  • Initiator server: 10.0.1.11 – the server consuming storage
  • Root or sudo access on both servers
  • Network connectivity between both servers on port 3260/TCP
  • SELinux in enforcing mode (recommended)
iSCSI target and initiator architecture diagram

Part 1: Configure iSCSI Target on Rocky Linux 10 / AlmaLinux 10

All commands in this section run on the target server (10.0.1.10).

Step 1: Update the system

Start with a fully updated system.

sudo dnf update -y

Reboot if kernel packages were updated.

sudo reboot

Step 2: Verify SELinux is enforcing

iSCSI works with SELinux in enforcing mode. Confirm it is active.

$ getenforce
Enforcing

Step 3: Install targetcli

The targetcli package provides the management shell for Linux-IO (LIO) iSCSI target. It is available in the default AppStream repository.

sudo dnf install -y targetcli

Enable and start the target service so it persists across reboots.

sudo systemctl enable --now target

Verify the service is running.

$ systemctl status target
● target.service - Restore LIO kernel target configuration
     Loaded: loaded (/usr/lib/systemd/system/target.service; enabled; preset: disabled)
     Active: active (exited)

Step 4: Prepare storage for iSCSI target

You can back iSCSI LUNs with a block device (like /dev/sdb) or a file-backed image. Block devices perform better, but file-backed images are simpler for testing. If you have a dedicated disk, use a block backstore. For this guide, we create a 5GB file-backed image.

Create a directory to hold the disk image.

sudo mkdir -p /var/iscsi-images

If you manage disk storage with LVM logical volumes, you can place this directory on a dedicated volume for better isolation.

Step 5: Configure iSCSI target with targetcli

Launch the targetcli interactive shell as root.

sudo targetcli

List the current configuration to confirm everything is empty.

/> ls
o- / ............................................................. [...]
  o- backstores .................................................. [...]
  | o- block ...................................... [Storage Objects: 0]
  | o- fileio ..................................... [Storage Objects: 0]
  | o- pscsi ...................................... [Storage Objects: 0]
  | o- ramdisk .................................... [Storage Objects: 0]
  o- iscsi ................................................ [Targets: 0]
  o- loopback .............................................. [Targets: 0]

The backstores section holds the storage backends. The main types are:

  • block – uses a raw block device like /dev/sdb. Best performance
  • fileio – uses a file on the filesystem. Easier to set up, slightly slower
  • pscsi – pass-through to a physical SCSI device
  • ramdisk – RAM-backed storage. Volatile, for testing only

Create a fileio backstore

Navigate to the fileio backstore path and create a 5GB disk image.

/> cd backstores/fileio
/backstores/fileio> create disk01 /var/iscsi-images/disk01.img 5G
Created fileio disk01 with size 5368709120

Verify the backstore was created.

/backstores/fileio> ls
o- fileio ......................................... [Storage Objects: 1]
  o- disk01 .... [/var/iscsi-images/disk01.img (5.0GiB) write-back deactivated]
    o- alua .......................................... [ALUA Groups: 1]
      o- default_tg_pt_gp ............. [ALUA state: Active/optimized]

Create the iSCSI target

Navigate to the iscsi path and create a target. iSCSI target names follow the iSCSI Qualified Name (IQN) format:

iqn.YYYY-MM.reversed.domain.name:label

Create the target with your own domain reversed.

/backstores/fileio> cd /iscsi
/iscsi> create iqn.2026-03.com.example:target01
Created target iqn.2026-03.com.example:target01.
Created TPG 1.
Global pref auto_add_default_portal=true
Created default portal listening on all IPs (0.0.0.0), port 3260.

The target was created along with a Target Portal Group (TPG 1) that listens on all interfaces on port 3260.

Create a LUN

A LUN (Logical Unit Number) maps a backstore to the target so initiators can access it. Navigate to the TPG luns path and create a LUN from the backstore.

/iscsi> cd iqn.2026-03.com.example:target01/tpg1/luns
/iscsi/iqn.20...et01/tpg1/luns> create /backstores/fileio/disk01
Created LUN 0.

Confirm the LUN.

/iscsi/iqn.20...et01/tpg1/luns> ls
o- luns ...................................................... [LUNs: 1]
  o- lun0 .. [fileio/disk01 (/var/iscsi-images/disk01.img) (default_tg_pt_gp)]

Configure the Access Control List (ACL)

ACLs restrict which initiators can connect. Each ACL entry matches the initiator’s IQN. Before configuring the ACL on the target, you need to know the initiator’s IQN. On the initiator server (10.0.1.11), the IQN is defined in /etc/iscsi/initiatorname.iscsi. We will set it to iqn.2026-03.com.example:initiator01 in Part 2.

Navigate to the ACL path and create an entry matching the initiator’s IQN.

/iscsi/iqn.20...et01/tpg1/luns> cd /iscsi/iqn.2026-03.com.example:target01/tpg1/acls
/iscsi/iqn.20...01/tpg1/acls> create iqn.2026-03.com.example:initiator01
Created Node ACL for iqn.2026-03.com.example:initiator01
Created mapped LUN 0.

Set CHAP authentication

CHAP (Challenge-Handshake Authentication Protocol) adds a layer of authentication. Navigate into the ACL entry and set a username and password. The password must be at least 12 characters.

/iscsi/iqn.20...01/tpg1/acls> cd iqn.2026-03.com.example:initiator01
/iscsi/iqn.20...:initiator01> set auth userid=initiator01
Parameter userid is now 'initiator01'.
/iscsi/iqn.20...:initiator01> set auth password=Str0ngP@ssw0rd
Parameter password is now 'Str0ngP@ssw0rd'.

Verify and save the configuration

Go back to the root and list the full configuration to confirm everything is correct.

/iscsi/iqn.20...:initiator01> cd /
/> ls
o- / ............................................................. [...]
  o- backstores .................................................. [...]
  | o- block ...................................... [Storage Objects: 0]
  | o- fileio ..................................... [Storage Objects: 1]
  | | o- disk01  [/var/iscsi-images/disk01.img (5.0GiB) write-back deactivated]
  | |   o- alua ...................................... [ALUA Groups: 1]
  | |     o- default_tg_pt_gp ......... [ALUA state: Active/optimized]
  | o- pscsi ...................................... [Storage Objects: 0]
  | o- ramdisk .................................... [Storage Objects: 0]
  o- iscsi ................................................ [Targets: 1]
  | o- iqn.2026-03.com.example:target01 .................... [TPGs: 1]
  |   o- tpg1 ................................. [no-gen-acls, no-auth]
  |     o- acls .............................................. [ACLs: 1]
  |     | o- iqn.2026-03.com.example:initiator01 ... [Mapped LUNs: 1]
  |     |   o- mapped_lun0 ......... [lun0 fileio/disk01 (rw)]
  |     o- luns .............................................. [LUNs: 1]
  |     | o- lun0  [fileio/disk01 (/var/iscsi-images/disk01.img) (default_tg_pt_gp)]
  |     o- portals ........................................ [Portals: 1]
  |       o- 0.0.0.0:3260 ........................................ [OK]
  o- loopback .............................................. [Targets: 0]

Exit targetcli to save the configuration. It auto-saves to /etc/target/saveconfig.json on exit.

/> exit
Global pref auto_save_on_exit=true
Last 10 configs saved in /etc/target/backup/.
Configuration saved to /etc/target/saveconfig.json

Step 6: Configure firewall for iSCSI target

Open port 3260/TCP in firewalld to allow initiator connections.

sudo firewall-cmd --add-port=3260/tcp --permanent
sudo firewall-cmd --reload

Verify the port is open.

$ sudo firewall-cmd --list-ports
3260/tcp

The iSCSI target is now ready to accept connections. Move on to the initiator server.

Part 2: Configure iSCSI Initiator on Rocky Linux 10 / AlmaLinux 10

All commands in this section run on the initiator server (10.0.1.11).

Step 1: Install iSCSI initiator utilities

Install the iscsi-initiator-utils package which provides the iscsiadm command and the iSCSI daemon.

sudo dnf install -y iscsi-initiator-utils

Step 2: Set the initiator IQN

Edit the initiator name file to match the IQN configured in the target’s ACL.

sudo vi /etc/iscsi/initiatorname.iscsi

Set the initiator name to match what was configured in the ACL on the target.

InitiatorName=iqn.2026-03.com.example:initiator01

Step 3: Configure CHAP authentication

Edit the iSCSI daemon configuration to enable CHAP and set the credentials matching the target’s ACL.

sudo vi /etc/iscsi/iscsid.conf

Find and update these lines (uncomment them if needed).

node.session.auth.authmethod = CHAP
node.session.auth.username = initiator01
node.session.auth.password = Str0ngP@ssw0rd

Step 4: Enable and start the iSCSI service

Enable and start the iscsid service.

sudo systemctl enable --now iscsid

Verify it is running.

$ systemctl status iscsid
● iscsid.service - Open-iSCSI
     Loaded: loaded (/usr/lib/systemd/system/iscsid.service; enabled; preset: disabled)
     Active: active (running)

Step 5: Discover iSCSI targets

Use iscsiadm in discovery mode to find available targets on the target server.

$ sudo iscsiadm -m discovery -t sendtargets -p 10.0.1.10:3260
10.0.1.10:3260,1 iqn.2026-03.com.example:target01

The target iqn.2026-03.com.example:target01 is discovered and available.

Step 6: Log in to the iSCSI target

Connect to the discovered target.

$ sudo iscsiadm -m node -T iqn.2026-03.com.example:target01 -p 10.0.1.10:3260 --login
Logging in to [iface: default, target: iqn.2026-03.com.example:target01, portal: 10.0.1.10,3260]
Login to [iface: default, target: iqn.2026-03.com.example:target01, portal: 10.0.1.10,3260] successful.

To automatically reconnect on boot, set the node to start up automatically.

sudo iscsiadm -m node -T iqn.2026-03.com.example:target01 -p 10.0.1.10:3260 --op update -n node.startup -v automatic

Step 7: Verify the iSCSI session and disk

Check the active iSCSI session.

$ sudo iscsiadm -m session -o show
tcp: [1] 10.0.1.10:3260,1 iqn.2026-03.com.example:target01 (non-flash)

The new iSCSI disk should appear as a SCSI device. Check with lsblk.

$ lsblk --scsi
NAME HCTL       TYPE VENDOR   MODEL             REV TRAN
sda  2:0:0:0    disk LIO-ORG  disk01           4.0  iscsi

The 5GB iSCSI disk appears as /dev/sda (the device name may vary on your system). You can also check it with fdisk.

$ sudo fdisk -l /dev/sda
Disk /dev/sda: 5 GiB, 5368709120 bytes, 10485760 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes

Step 8: Format and mount the iSCSI disk

Create a filesystem on the iSCSI disk. XFS is the default filesystem on Rocky Linux and AlmaLinux.

sudo mkfs.xfs /dev/sda

Create a mount point and mount the disk.

sudo mkdir -p /mnt/iscsi-disk
sudo mount /dev/sda /mnt/iscsi-disk

Verify the mount.

$ df -hT /mnt/iscsi-disk
Filesystem     Type  Size  Used Avail Use% Mounted on
/dev/sda       xfs   5.0G   68M  5.0G   2% /mnt/iscsi-disk

Step 9: Configure persistent mount with fstab

To survive reboots, add the iSCSI disk to /etc/fstab. Use the _netdev mount option so the system waits for the network and iSCSI session before mounting.

Get the disk UUID.

$ sudo blkid /dev/sda
/dev/sda: UUID="a1b2c3d4-e5f6-7890-abcd-ef1234567890" TYPE="xfs"

Add the mount entry to fstab. Replace the UUID with your actual value.

sudo vi /etc/fstab

Add this line at the end of the file.

UUID=a1b2c3d4-e5f6-7890-abcd-ef1234567890  /mnt/iscsi-disk  xfs  _netdev  0 0

The iSCSI disk will now mount automatically on boot after the iSCSI session is established. You can use this storage for KVM virtual machine storage pools or any application that needs shared block storage.

Managing iSCSI Sessions

Here are common management commands for the iSCSI initiator.

List all active sessions.

sudo iscsiadm -m session

Show detailed information about a session.

sudo iscsiadm -m session -P 3

Log out from a specific target (unmount the filesystem first).

sudo umount /mnt/iscsi-disk
sudo iscsiadm -m node -T iqn.2026-03.com.example:target01 -p 10.0.1.10:3260 --logout

Delete a discovered target record.

sudo iscsiadm -m node -T iqn.2026-03.com.example:target01 -p 10.0.1.10:3260 --op delete

Conclusion

We configured a complete iSCSI storage setup on Rocky Linux 10 / AlmaLinux 10 – a target server exporting a 5GB file-backed LUN with CHAP authentication, and an initiator server that discovers, connects, formats, and mounts the shared storage. The configuration persists across reboots on both sides.

For production use, consider using block backstores instead of fileio for better performance, enabling multipath I/O (DM-Multipath) for redundancy, and monitoring iSCSI session health. See the Red Hat iSCSI target documentation for advanced configuration options.

Related Articles

AlmaLinux Configure Vsftpd FTP Server on Rocky Linux 8|AlmaLinux 8 AlmaLinux Install Filebeat, Logstash , Kibana on Rocky | AlmaLinux Storage Automatically Clean Unused Temporary files in Linux AlmaLinux How To Install VirtualBox 7.1 on Rocky / AlmaLinux 8

Press ESC to close