Solaris iSCSI CHAP and RADIUS Configuration - FAQ
Solaris iSCSI CHAP and RADIUS Configuration FAQ
Revision History
| Version 0.1 for internal comments | Peter Cudhea | June 26, 2008 |
| Version 0.2 as posted in blog. | Peter Cudhea | July 18, 2008 |
Scope of this FAQ
This document pulls together some well-known and not-so well-known information about how to configure the CHAP and RADIUS security features on Solaris iSCSI. It is necessarily incomplete, since it doesn't go into detail about any of the other aspects of iSCSI configuration.
What is iSCSI?
Internet SCSI (iSCSI) is a network protocol for allowing block-based access to remote storage devices across the Internet. Essentially, it allows mounting remote block devices on a target as if they were local block devices. The iSCSI protocol is described in RFC 3720 and associated other RFCs.
In iSCSI terminology, a particular iSCSI initiator system sets up a session to a particular target system requesting access to a particular storage target. A target device can then export multiple Logical Units, usually called LUNs. In iSCSI, each initiator node and each target node has a unique name, in either IQN or EUI format. For now the details of these formats are not relevant. A storage session links one initiator, one target, and one particular LUN, and makes that LUN available on the initiator system.
What iSCSI options does Solaris support?
Solaris supplies an implementation for the iSCSI initiator (which allows a system to import remote storage as if it were a local disk) and an iSCSI target (which allows a system to export local storage to be mountable by remote initiators). Most of this document is about the iSCSI target.
In addition to the classic iSCSI target, an advanced version of the iSCSI target is under development as part of the Common Multi-Protocol SCSI Target (COMSTAR) project on opensolaris.org. The COMSTAR iSCSI target will support iSCSI Extensions for RDMA (iSER). See the iSER and COMSTAR pages at opensolaris.org for more information on this project.
This document only goes into detail about the classic Solaris iSCSI target.
What is iSCSI target discovery?
There are multiple ways to set up a session from the initiator to a particular LUN on the target. This overall process is called target discovery. Target discovery interacts with authentication because targets that are not visible through target discovery do not need to be authenticated. Solaris supports three flavors of target discovery:
- Static Discovery - an entry on the initiator side directly identifies by name (eui or iqn) the particular target that it wants to connect to.
- SendTargets Discovery - the initiator is configured with the IP address of a target system. All the targets configured that are visible to that initiator on that system are automatically discovered.
- iSNS Discovery - the target registers its storage targets with a storage name services server. (the iSNS server) The initiator can ask the iSNS server which storage targets are available. This document does not go into detail about iSNS discovery.
What is a "local initiator"?
The Solaris iSCSI target can be configured with information about the initiators that may wish to connect to that target. The information about each initiator is recorded using the commands
iscsitadm create initiator -N <initiator-iqn> <initiator-alias>
iscsitadm modify initiator <options> <initiator-alias>
What is an Access Control List?
The access control list is a target-side per-target parameter that specifies a limited list of initiators that is allowed to see that target. The entries in an iSCSI target ACL should be a list of initiator aliases from the target's set of local initiators.
For a target without an ACL, all non-authenticated or authenticated initiators are allowed to list and to connect to that target.
For a target with an ACL, all initiators whose iqn matches an entry on the ACL are allowed to list that target, i.e. to see it with iscsiadm list discovery-address -v. Only authenticated initiators are allowed to connect to it.
Note that target-side Access Control Lists are not used with iSNS. The work of access control is completely delegated to the iSNS server.
What is iSCSI Authentication?
The initiator and the target must establish a relationship of trust. A target without an access control list automatically "trusts" all non-authenticated and authenticated initiators. A target with an access control list will only "trust" the initiators on that list, i.e. the initiators whose initiator-iqn is already known to the target. But simply knowing the right name is no security.
In classic storage area networks such as fiber channel networks, much of the trust between nodes is achieved by the physical security (i.e. isolation) of the nodes and links in the network.
Full iSCSI security depends on full security at the Internet Protocol level, such as is provided using the IPSec internet security suite. This document does not go into detail of how to use IPSec features with iSCSI.
iSCSI Authentication is a method whereby an initiator node and target node can assure themselves that each one has been specifically configured to connect with the other, i.e. that each side shares a "secret" that only the other side should know. iSCSI authentication can be used whether or not IPSec is used.
What is CHAP (Challenge Handshake Authentication protocol)?
iSCSI uses the Challenge Handshake Authentication Protocol (CHAP) as described in RFC1994 to verify the identity of the agent on the other side of the wire. In CHAP, each agent is configured with a CHAP name and CHAP secret, which are essentially a username and user password for that agent. The other side is then configured with a password database that includes the CHAP name and CHAP password for each agent that should be allowed to connect.
In CHAP, the passwords themselves never travel over the Internet in the clear. Instead, a Challenge token is sent across the wire. Only an agent that possesses the matching secret can return the appropriate Response. See RFC1994 for more details on this exchange, and RFC3720 for more details on how the exchange is embedded in iSCSI login request and response messages.
What is unidirectional authentication?
The simplest way of configuring CHAP authentication is for the target to authenticate initiators.
On the initiator side, an entry is created to specify the outgoing CHAP name and CHAP password for that initiator node. For the Solaris initiator, this is done with the iscsiadm modify initiator-node command.
iscsiadm modify initiator-node -H <initiator-CHAP-name>
iscsiadm modify initiator-node -C
Enter Secret: <initiator-CHAP-secret>
Repeat Secret: <initiator-CHAP-secret>
iscsiadm modify initiator-node -a CHAP
On the target side, the administrator must specify the user name and password to expect from the initiator. The way to do this on Solaris is to create a local initiator entry on the target for each initiator that might wish to connect via CHAP. The entry specifies the entity name (eui or iqn), and the incoming CHAP name, and the CHAP password for that entity. It is also possible to create a local initiator that does not specify a CHAP secret.
For the Solaris target, creating a local initiator is done with the iscsitadm create/modify initiator command.
iscsitadm create initiator -N <initiator-iqn> <initiator-alias>
iscsitadm modify initiator -H <initiator-CHAP-name> <initiator-alias>
iscsitadm modify initiator -C <initiator-alias>
Enter Secret: <initiator-CHAP-secret>
Repeat Secret: <initiator-CHAP-secret>
Authentication will be successful whenever there is a local initiator on the target that matches the iqn, the CHAP name, and the CHAP secret as configured on the initiator.
Any gotchas? Why is Unidirectional Authentication still failing?
Are you using a version of Nevada earlier than snv_93, or any version of Solaris 10 before at least Update 7?
Be aware of bug 6667315 and its following workaround. In earlier releases, even if all the above steps were followed unidirectional authentication would still fail. The bug was that unless an outgoing CHAP name and CHAP secret were configured on the target system, the CHAP negotiation would never be triggered, and authentication would always fail. The workaround is to configure an outgoing CHAP name and CHAP secret on the target system as described in the section on bidirectional authentication below. The outgoing CHAP information is not actually used for unidirectional authentication; it just has to be configured so that CHAP negotiation is triggered.
What is bidirectional authentication?
In bidirectional authentication, the initiator also gets a chance to authenticate the target (no rogue initiators AND no rogue targets). In this case, the target also configures an outgoing CHAP name and CHAP secret. If the initiator wishes to use bi-directional authentication, then it must request bi-directional authentication, and the initiator must be configured with an incoming CHAP name and CHAP secret for the target that matches the target's own information.
For the Solaris iSCSI target to participate in bidirectional CHAP, the target must be configured with an outgoing CHAP name and CHAP secret. The same secret is used for all separate initiators that wish to authenticate the target.
iscsitadm modify admin -H <target-CHAP-name>
iscsitadm modify admin -C
<target-CHAP-secret>
<target-CHAP-secret>
For the Solaris iSCSI initiator, bi-directional CHAP may be configured once the target is visible to the client. Configuration involves requesting bidirectional CHAP as well as setting up the expected incoming CHAP information for that target. There are four separate parameters that must be set.
iscsiadm modify target-param -a CHAP <target-iqn>
iscsiadm modify target-param -H <target-chap-name> <target-iqn>
iscsiadm modify target-param -C <target-iqn>
<target-CHAP-secret>
<target-CHAP-secret>
iscsiadm modify target-param -B enable <target-iqn>
Note that the secrets used in the initiator->target direction and the target->initiator direction must not match, or else a man-in-the-middle attack is possible. iSCSI partners are supposed to check incoming requests to validate that they do not share secrets.
The iscsiadm modify target-param command modifies parameters that are specific to one particular storage target. One interesting fact is that the -a CHAP flag from the above sequence overrides the -a CHAP flag for the initiator-node. Even if the initiator-node is set to -a none, if the target-param is set to -a CHAP, then CHAP will be requested. Moreover, if the initiator-node is set to -a CHAP, if the target-param specifies -a none, then CHAP will not be requested. When CHAP is used in bi-directional authentication, the outgoing CHAP name and CHAP secret are taken from the initiator-node of that initiator. In particular, note that once a system has been configured to use bi-directional authentication even if iscsiadm modify initiator-node -a none has been done to disable unidirectional authentication, the CHAP name and CHAP secret that were already defined for that initiator-node can still be used for bidirectional authentication. This is one observable difference between an initiator system that has never used CHAP and a system that used CHAP at one time and then turned it off.
What triggers CHAP authentication?
CHAP authentication is triggered in two different cases:
- 1. The initiator system requests authentication=CHAP during the iSCSI login process. For the Solaris initiator, this happens whenever iscsiadm modify initiator-node -a CHAP is selected.
- 2. The target system has a local initiator entry that matches the initiator's iSCSI name AND the local initiator is mentioned in the ACL for the storage target that is being logged into AND the local initiator includes a CHAP name and CHAP target for the initiator.
What is the result of authentication?
For each initiator that attempts to connect to the target, the results of authentication will be one of the following four states:
- non-authenticated
- the target did not have a local initiator configured that matched the incoming initiator.
- the initiator was not configured to request CHAP.
- named-but-not-authenticated
- the target did have a local initiator configured that matched the incoming initiator.
- the local initiator was not configured with an expected incoming CHAP name and CHAP secret
- the initiator was not configured to request CHAP
- unidirectional authentication complete
- the initiator was configured with an outgoing CHAP name and CHAP secret
- the initiator was configured to request CHAP
- the target did have a local initiator configured that matched the incoming iqn
- the target's local initiator was configured to match the initiator's incoming CHAP name and CHAP secret
- bidirectional authentication complete
- the initiator was configured with an outgoing CHAP name and CHAP secret
- the initiator was configured for bidirectional authentication, i.e. it has an target-param entry for the desired storage target, and that target-param contains an incoming CHAP name and CHAP secret that matches the target's actual CHAP information, and the target-param was configured to request bidirectional authentication
- the target did have a local initiator configured that matched the incoming iqn
- the local initiator was configured with an incoming CHAP name and CHAP secret that matched the initiator's
- the target was configured with an outgoing CHAP name and CHAP secret.
- the secret used in the initiator->target direction did not match the secret used in the target->initiator direction.
- authentication-failed
- CHAP was requested either at the initiator-side or the target side, and one of the above conditions was not met.
How do I configure the target to "require CHAP authentication"?
Putting a few of the above answers together, the only way for a target to require CHAP authentication is to
- have a local initiator for each expected initiator that will try to connect
- have an ACL on each possible target that mentions which initiators can connect to it.
- Each local initiator must specify a CHAP name and CHAP secret for that initiator.
With the above setup, the only initiators that will be allowed to connect to the target are those whose are on the ACL and whose CHAP name and CHAP secret match those of the local-initiator node that matches the initiator-iqn.
If the target administrator does not configure an ACL for a particular target, then as described above non-authenticated initiators are allowed to connect to that target. Hence, "require CHAP authentication" is not achieved.
If the target administrator does not configure a CHAP secret for each expected initiator, then non-authenticated initiators can impersonate one of the named-but-not-authenticated initiators mentioned in the ACLs. So once again, "require CHAP authentication" is not achieved.
The request to have an easier way to configure the target to require CHAP authentication is being tracked in RFE 6707657.
What is RADIUS, and how does it relate to CHAP?
Either the target side or the initiator side can offload the work of managing CHAP names and CHAP secrets to a RADIUS server. In this case, each entities outgoing CHAP name and CHAP secret are still configured in the normal place (either iscsiadm modify initiator-node for the initiator or iscsitadm modify admin for the target. But the matching incoming CHAP names and CHAP secrets are now configured on the RADIUS server. (Actually, the target-side must still have the accurate CHAP names; only the CHAP secret is delegated to RADIUS).
To make the communications with the RADIUS server secure, a shared "RADIUS secret" is configured between the radius client system (whether initiator or target) and the RADIUS server.
The RADIUS server is then configured with a database of expected usernames and passwords that match the expected set of CHAP names and CHAP secrets.
Note that for a RADIUS server to perform CHAP authentication, the CHAP secrets must be stored in the clear (non-encrypted) in the database on the RADIUS server. This is a constraint built into the CHAP protocol. Only with the password in the clear can the proper CHAP challenges and responses be computed. This characteristic of RADIUS has led some experts to recommend against the use of RADIUS for storing iSCSI CHAP secrets. Many bloggers contend that the convenience of configuring all your secret checking in one place is outweighed by the risk of having a clear-text database of all these usernames and passwords existing in some form on your network. It is a tempting plum to be plucked.
How do I configure the Solaris iSCSI Target to use RADIUS?
This is used on the target side to delegate to the RADIUS server the job of checking incoming CHAP names and CHAP secrets from the initiators. All other configuration information on the target is configured as usual.
iscsitadm modify admin -r <RADIUS-IP-address>
issitadm modify admin -P
Enter Secret: <RADIUS-shared-secret-for-target-ip-address>
Repeat Secret:<RADIUS-shared-secret-for-target-ip-address>
iscsitadm modify admin -R enable
How do I "Require CHAP Authentication" when using target-side RADIUS?
Currently (see RFE 6727351), it is difficult to "require CHAP authentication" when using RADIUS. The steps required are:
- Create a local-initiator for each initiator that will wish to connect. The local initiator must have an incoming CHAP name that matches the initiator system's actual outgoing CHAP name. It also needs to have a CHAP secret that is non-null, but the actual contents of the CHAP secret are ignored.
- Each target must have an access control list that mentions the specific initiators that should be able to view and mount that target.
In other words, the ONLY part of authentication that is currently being delegated to the RADIUS server is the actual password maintenance. All the rest of CHAP processing on the target, including CHAP name maintenance, is exactly the same whether or not RADIUS is being used.
How do I configure the Solaris iSCSI Initiator to use RADIUS?
This is used in bidirectional authentication to delegate to the RADIUS server the job of checking the target's CHAP name and CHAP secret. All other configuration information for bidirectional authentication should be set up as described above.
iscsiadm modify initiator-node -r <RADIUS-IP-address>
iscsiadm modify -P
Enter Secret: <RADIUS-shared-secret-for-initiator>
Repeat Secret: <RADIUS-shared-secret-for-initiator>
iscsiadm modify initiator-node -R enable
Be aware of bug 6679007. The capability for a Solaris iSCSI initiator to use a RADIUS server was not working until release snv_92.
How do I configure the FreeRADIUS server to check CHAP secrets?
I have done most testing on FreeRadius. FreeRadius is not currently shipped as part of Solaris. It can be downloaded from the Internet. I used someone else's FreeRadius server, so I didn't have to build it from scratch. I also have personal and dedicated use of this radius server, which facilitates debugging since I can stop and start the radius server whenever I want, as well as running it in debug mode.
That being said, here is a summary of the steps I took to configure the FreeRadius server to authenticate a new iSCSI initiator or target.
Modify clients.conf in /etc/raddb or equivalent directory to include an entry for the IP address of the initiator or target that is using RADIUS. This entry will also include the shared secret that was configured above.
Modify the users file in /etc/raddb to include an entry for the CHAP names and CHAP secrets that should be verified. To RADIUS, these look just like usernames and passwords.
Start the RADIUS server in debug mode and watch the output to see the results of each connection attempt. I manually restarted the RADIUS server each time I modified either of the above configuration files. Though I am not sure that was necessary, it was sufficient for my testing.
How do you run a CHAP "experiment"?
This is where target discovery comes in. The best method to experiment is to turn off your discovery method on the initiator system, change some CHAP parameters, and then turn on discovery again. Each time discovery is turned on, the initiator system discovers which storage targets are available, and provisions as many of them as possible to be available to the initiator system's OS level.
For example, to use SendTargets discovery, first tell the initiator system the IP address of the target system:
iscsiadm add discovery-address <IP-address of target system>
Verify the list of visible targets by executing
iscsiadm list discovery-address -v
For example:
-bash-3.2# iscsiadm list discovery-address -v
<snip>
Target name: iqn.1986-03.com.sun:02:361bf4f4-eb16-428c-9bd0-b00b4aecb2b1.tgt-no-acl
Target address: 129.148.168.14:3260, 1
You can set up for a new experiment by disabling discovery:
iscsiadm modify discovery -t disable
This will make all the targets disappear from the initiator side. Note you can not disable sendtargets discovery if any of the known targets are currently in use. I tend to use a dedicated initiator and target system for my iSCSI experiments, so I can make sure that all targets are not in use. Occasionally, I must reboot the initiator system to convince it that some particular target should not be in use.
You can verify that all the initiator-connections are now gone.
iscsiadm list target
Set up a series of parameters for an experiment, such as setting CHAP parameters on both initiator and target systems, and then re-enable sendtargets discovery:
iscsiadm modify discovery -B enable
How can I tell my storage is connected?
Signs that storage is now connected and usable by other software on the initiator system:
- On the target system, iscsitadm list target -v shows a connection for each initiator that has connected to the target. Your initiator will show up in this list.
-bash-3.2# iscsitadm list target -v
Target: tgt-no-acl
iSCSI Name: iqn.1986-03.com.sun:02:361bf4f4-eb16-428c-9bd0-b00b4aecb2b1.tgt-no-acl
Connections: 1
Initiator:
iSCSI Name: iqn.1986-03.com.sun:01:00000000782b.4846f53d
Alias: perelandra
ACL list:
TPGT list:
LUN information:
LUN: 0
GUID: 010000101803255600002a004859729e
VID: SUN
PID: SOLARIS
Type: disk
Size: 200M
Status: unknown
On the initiator system, the output of iscsiadm list target -S includes an OS device name for each accessible target. If your connection worked, your target will show up in this list, and will have an OS Device name (e.g. /dev/rdsk/ c0t2d0s0).
-bash-3.2# iscsiadm list target -S
<snip>
Posted on: Jul 18, 2008
Category: iSCSI-iSER
Posted by c0t0d0s0.org on July 19, 2008 at 07:31 AM EDT #