Configuring the client (initiator)

# aptitude install open-iscsi

This is just a single package which installs neatly without needing to build anything.

Set up the Initiator's name

iSCSI clients (initiators) need an iSCSI-format name to use when communicating with the servers (targets). The name is stored in /etc/iscsi/initiatorname.iscsi

You can get the iSCSI system to create a pseudo-random name for you, but I prefer to use something a bit more meaningful to my own network.

DO NOT modify this file on Debian Buster / Devuan Beowulf or above. Read the comments at the top of the file and obey them.

Replace the content of /etc/iscsi/initiatorname.iscsi with:

InitiatorName=iqn.2017-04.domain.hostname:openiscsi

Feel free to replace "openiscsi" at the end of that string with anything you prefer.

Restart the open-iscsi process after changing the initiator name:

# /etc/init.d/open-iscsi restart

Discover the shares

# iscsiadm -m discovery -t st -p 192.168.42.xxx

(Use the IP address or hostname of the iSCSI server you configured above.)

You should get a response showing the IP address of the server followed by :3260 (the port number which ietd listens on) and a comma followed by another number, and then the name of the Target which you specified in /etc/iet/ietd.conf on the server.

Connect to a share

# iscsiadm -m node -T iqn.2017-04.de.dehy.retinal:SCSIshare -p 192.168.42.xxx -l

You can see what the new device is called by checking dmesg:

[ 3462.914271] scsi2 : iSCSI Initiator over TCP/IP
[ 3463.185451] scsi 2:0:0:0: Direct-Access     IET      VIRTUAL-DISK     0    PQ: 0 ANSI: 4
[ 3463.185920] scsi 2:0:0:0: Attached scsi generic sg1 type 0
[ 3463.192397] sd 2:0:0:0: [sda] 20119552 512-byte logical blocks: (10.3 GB/9.59 GiB)
[ 3463.192397] sd 2:0:0:0: [sda] Write Protect is off
[ 3463.192397] sd 2:0:0:0: [sda] Mode Sense: 77 00 00 08
[ 3463.192397] sd 2:0:0:0: [sda] Write cache: disabled, read cache: enabled, doesn't support DPO or FUA
[ 3463.196060]  sda: unknown partition table
[ 3463.198121] sd 2:0:0:0: [sda] Attached SCSI disk

So, in this case, my device is called /dev/sda (this is a virtual machine whose local disk is called /dev/vda, therefore /dev/sda was previously unused).

Additional iSCSI shares will be named /dev/sdb, /dev/sdc etc.

Using an iSCSI share

If the block device was already formatted, you can simply mount it:

# mount /dev/sda /mnt

If it wasn't formatted, you can do so:

# mkfs.ext3 /dev/sda
# mount /dev/sda /mnt

In other words, just use it like you would any standard block device. You can partition it, use it as a partition, or do anything else which you would with a USB stick, CD-ROM device, hard disk, etc.

Note: if you are using multiple shares on a single client, the names /dev/sda, /dev/sdb etc may not be the same every time the machine restarts, so if you are using a formatted ext(2,3 or 4) file system on the iSCSI shared device, it is a very good idea to give the file system a LABEL, and then connect to that instead of the device name:

# mkfs.ext3 -L iSCSIsharename /dev/sda

or

# tune2fs -L iSCSIsharename /dev/sda

if the device is already formatted.

You can then mount the device using something like:

# mount -L iSCSIsharename /mnt

You can also use UUIDs to reliably mount file systems, independently of the device name:

# mount -U d47c820a-2f16-462a-b609-8a54ba9a2c91 /mnt

Personally I find labels a bit more friendly, although UUIDs are less likely to conflict if you happen to move a disk from one machine to another and then find out there are two disks containing file systems with the name "home". One will win, one will lose, when it comes to mounting them.

Disconnect from a share

Make sure the client is not using the device before disconnecting!

If the device is in use, the effect is the same as unplugging a hard disk which is in use - the file system will very probably be corrupted, and the client machine may get very upset, depending on what it was doing with the device at the time.

# iscsiadm -m node -T iqn.2017-04.de.dehy.retinal:SCSIshare -p 192.168.42.xxx -u

Automatically re-connecting at boot time

To have the client automatically reconnect to the server and make the device available at boot time, change the file /etc/iscsi/iscsid.conf so that:

node.startup = automatic

Coping with connectivity problems

Obviously, if the client and the server lose connection with each other, the shared device becomes unavailable to the client.

By default, open-iscsi will wait up to 2 minutes for the share to become available again, and then time out (which means the application trying to use the device will get some sort of "I/O failure" error and very probably die ungracefully (since these hardware-level errors are not the sort of thing applications are generally designed to cope with - they assume "your computer has just broken, so this application falling over is the least of your problems").

You can change the timeout to anything you like, including infinity, which means that the client will wait forever for the share to become available again. What works best for you depends on a balance of:

  • how quickly you think you can restore connectivity
  • the consequences of the share being unavailable during the timeout period
  • the consequences of the service timing out and the application being told that the device has disappeared

See the comments regarding node.session.timeo.replacement_timeout in the configuration file /etc/iscsi/iscsid.conf.

Note that it is safe to restart the iSCSI service on the target (server), or even to reboot the server, while clients are connected. No data can be read or written while the service is unavailable, but the connection will be restored without the application/s realising that the service (or the server) has been restarted (unless the restart / reboot takes longer than the timeout interval (see above) - this could be a problem on some server hardware, where the reboot time can easily be >2 minutes).

Network Address Translation

iSCSI operates by default over TCP port 3260, so in principle it should be usable through NAT.

In practice the speed of the connection has a noticeable influence on the "short-term functionality" of the shared device, by which I mean that data copied to the device can take some time to really be there. It's a bit like writing a big file to a USB stick - it can take many many seconds after the copy says it has completed, before the data is fully written to the device and it's actually safe to remove it from your computer. This in itself is nothing to do with NAT, however it's most likely that any NATted connection will be (at one end or the other) on a low-speed, and probably asymmetric, ISP connection ("low" compared to a gigabit LAN, for example).

With that caveat in mind, here's how to make iSCSI work over NAT:

If your initiator (client) is on a private address behind outbound NAT, and your target (server) is on a public IP address, you don't need to do anything special to support iSCSI. It just works, like any other network protocol such as SSH or HTTP.

If both initiator and target are behind NAT, then you really should be using a VPN to connect your two networks together.

If the target is behind inbound NAT, then you should set up packet forwarding on your firewall:

iptables -A PREROUTING -t nat -s $initiator -p tcp --dport 3260 -j DNAT --to $target
iptables -A FORWARD -s $initiator -p tcp --dport 3260 -d $target -j ACCEPT

You'll then find that the "discovery" command works perfectly normally, although you'll see that it returns the private IP address of the target, and the login command will fail with the error:

iscsiadm: No records found

The solution is simple: you cd to the directory /etc/iscsi/nodes and find the sub-directory for the target you want to connect to. cd into this sub-directory, and there you'll see a further sub-directory named something like 192.168.236.42,3260,1

Rename this to have the public IP address you need to connect to instead of the private IP address, and then edit the single file default which is in this directory, again changing the single instance of the private IP address into the public address.

You can then log in to the target and start using it.

Just be aware that if you repeat the "discovery" command, it will re-create the subdirectory with the private IP address in the name. If you've changed anything about the target and the devices being shared, you'll need to delete the old directory (with the public IP address) and repeat the above rename and edit. If you have not changed anything about the target, you can either just ignore the new directory with the private IP address, or delete it.


Go up
Return to main index.