# 32.13.iSCSI target 和 initiator 的配置

iSCSI 是一种通过网络共享存储的方式。与在文件系统级别工作的 NFS 不同，iSCSI 在块设备级别工作。

在 iSCSI 术语中，共享存储的系统被称为 *target*（目标）。存储可以是一个物理磁盘，或者是表示多个磁盘或物理磁盘一部分的区域。例如，如果磁盘使用 ZFS 格式化，可以创建一个 zvol 来作为 iSCSI 存储。

访问 iSCSI 存储的客户端称为 *initiators*（发起者）。对发起者来说，通过 iSCSI 提供的存储表现为一个原始的、未格式化的磁盘，称为 LUN。磁盘的设备节点出现在 **/dev/** 中，设备必须单独格式化并挂载。

FreeBSD 提供了一个原生的、基于内核的 iSCSI 目标和发起者。本节将描述如何将 FreeBSD 系统配置为目标或发起者。

## 32.13.1. 配置 iSCSI 目标

要配置 iSCSI 目标，首先创建 **/etc/ctl.conf** 配置文件，向 **/etc/rc.conf** 中添加一行，确保 [ctld(8)](https://man.freebsd.org/cgi/man.cgi?query=ctld\&sektion=8\&format=html) 守护进程在启动时自动启动，然后启动该守护进程。

以下是一个简单的 **/etc/ctl.conf** 配置文件的示例。有关此文件可用选项的完整描述，请参见 [ctl.conf(5)](https://man.freebsd.org/cgi/man.cgi?query=ctl.conf\&sektion=5\&format=html)。

```ini
portal-group pg0 {
	discovery-auth-group no-authentication
	listen 0.0.0.0
	listen [::]
}

target iqn.2012-06.com.example:target0 {
	auth-group no-authentication
	portal-group pg0

	lun 0 {
		path /data/target0-0
		size 4G
	}
}
```

第一个条目定义了 `pg0` 门户组。门户组定义了 [ctld(8)](https://man.freebsd.org/cgi/man.cgi?query=ctld\&sektion=8\&format=html) 守护进程将监听的网络地址。`discovery-auth-group no-authentication` 条目表示任何发起者都可以在没有身份验证的情况下执行 iSCSI 目标发现。第三行和第四行配置 [ctld(8)](https://man.freebsd.org/cgi/man.cgi?query=ctld\&sektion=8\&format=html) 监听所有 IPv4（`listen 0.0.0.0`）和 IPv6（`listen [::]`）地址，默认端口为 3260。

定义门户组不是必需的，因为有一个内置的门户组叫做 `default`。在这种情况下，`default` 与 `pg0` 的区别在于，使用 `default` 时，目标发现始终被拒绝，而使用 `pg0` 时，目标发现始终被允许。

第二个条目定义了一个单一的目标。目标有两种可能的含义：一个提供 iSCSI 服务的机器，或者一个命名的 LUN 群组。此示例使用后者的含义，其中 `iqn.2012-06.com.example:target0` 是目标名称。此目标名称适用于测试目的。实际使用时，将 `com.example` 更改为实际的反向域名，`2012-06` 表示获得该域名控制权的年月，`target0` 可以是任何值。可以在此配置文件中定义任意数量的目标。

`auth-group no-authentication` 行允许所有发起者连接到指定的目标，`portal-group pg0` 使该目标可以通过 `pg0` 门户组访问。

接下来的部分定义了 LUN。对于发起者来说，每个 LUN 将作为一个独立的磁盘设备显示。每个目标可以定义多个 LUN。每个 LUN 由一个数字标识，其中 LUN 0 是强制性的。`path /data/target0-0` 行定义了一个文件或 zvol，作为 LUN 的后端存储路径。该路径必须在启动 [ctld(8)](https://man.freebsd.org/cgi/man.cgi?query=ctld\&sektion=8\&format=html) 之前存在。第二行是可选的，用于指定 LUN 的大小。

接下来，为确保 [ctld(8)](https://man.freebsd.org/cgi/man.cgi?query=ctld\&sektion=8\&format=html) 守护进程在启动时启动，请将以下行添加到 **/etc/rc.conf**：

```sh
ctld_enable="YES"
```

要立即启动 [ctld(8)](https://man.freebsd.org/cgi/man.cgi?query=ctld\&sektion=8\&format=html) 守护进程，可以运行以下命令：

```sh
# service ctld start
```

当 [ctld(8)](https://man.freebsd.org/cgi/man.cgi?query=ctld\&sektion=8\&format=html) 守护进程启动时，它会读取 **/etc/ctl.conf**。如果在守护进程启动后编辑了此文件，请使用以下命令使更改立即生效：

```sh
# service ctld reload
```

### 32.13.1.1. 认证

前面的示例本质上是不安全的，因为它没有使用任何认证，允许任何人完全访问所有目标。要要求用户名和密码才能访问目标，请按以下方式修改配置：

```ini
auth-group ag0 {
	chap username1 secretsecret
	chap username2 anothersecret
}

portal-group pg0 {
	discovery-auth-group no-authentication
	listen 0.0.0.0
	listen [::]
}

target iqn.2012-06.com.example:target0 {
	auth-group ag0
	portal-group pg0
	lun 0 {
		path /data/target0-0
		size 4G
	}
}
```

`auth-group` 部分定义了用户名和密码对。一个发起者在尝试连接到 `iqn.2012-06.com.example:target0` 时，必须首先指定一个已定义的用户名和密码。然而，目标发现仍然允许没有认证的连接。要要求进行目标发现认证，请将 `discovery-auth-group` 设置为已定义的 `auth-group` 名称，而不是 `no-authentication`。

通常，为每个发起者定义一个单独的导出目标。作为上述语法的简写，用户名和密码可以直接在目标条目中指定：

```ini
target iqn.2012-06.com.example:target0 {
	portal-group pg0
	chap username1 secretsecret

	lun 0 {
		path /data/target0-0
		size 4G
	}
}
```

## 32.13.2. 配置 iSCSI 发起者

> **注意**
>
> 本节所述的 iSCSI 发起者从 FreeBSD 10.0-RELEASE 开始得到支持。要使用较早版本中可用的 iSCSI 发起者，请参阅 [iscontrol(8)](https://man.freebsd.org/cgi/man.cgi?query=iscontrol\&sektion=8\&format=html)。

iSCSI 发起者需要运行 [iscsid(8)](https://man.freebsd.org/cgi/man.cgi?query=iscsid\&sektion=8\&format=html) 守护进程。该守护进程不使用配置文件。要使其在启动时自动启动，请将以下行添加到 **/etc/rc.conf**：

```sh
iscsid_enable="YES"
```

要立即启动 [iscsid(8)](https://man.freebsd.org/cgi/man.cgi?query=iscsid\&sektion=8\&format=html) 守护进程，可以运行以下命令：

```sh
# service iscsid start
```

可以通过有或没有 **/etc/iscsi.conf** 配置文件来连接目标。本节将演示这两种连接方式。

### 32.13.2.1. 无配置文件连接目标

要将发起者连接到单个目标，指定门户的 IP 地址和目标名称：

```sh
# iscsictl -A -p 10.10.10.10 -t iqn.2012-06.com.example:target0
```

要验证连接是否成功，可以运行 `iscsictl` 不带任何参数。输出应类似于以下内容：

```sh
Target name                                     Target portal   State
iqn.2012-06.com.example:target0                 10.10.10.10     Connected: da0
```

在此示例中，iSCSI 会话已成功建立，**/dev/da0** 代表附加的 LUN。如果 `iqn.2012-06.com.example:target0` 目标导出多个 LUN，则该部分输出将显示多个设备节点：

```sh
Connected: da0 da1 da2.
```

任何错误都会在输出中报告，同时也会出现在系统日志中。例如，以下消息通常意味着 [iscsid(8)](https://man.freebsd.org/cgi/man.cgi?query=iscsid\&sektion=8\&format=html) 守护进程没有运行：

```sh
Target name                                     Target portal   State
iqn.2012-06.com.example:target0                 10.10.10.10     Waiting for iscsid(8)
```

以下消息表示存在网络问题，例如 IP 地址或端口错误：

```sh
Target name                                     Target portal   State
iqn.2012-06.com.example:target0                 10.10.10.11     Connection refused
```

此消息意味着指定的目标名称错误：

```sh
Target name                                     Target portal   State
iqn.2012-06.com.example:target0                 10.10.10.10     Not found
```

此消息表示目标需要认证：

```sh
Target name                                     Target portal   State
iqn.2012-06.com.example:target0                 10.10.10.10     Authentication failed
```

要指定 CHAP 用户名和密码，请使用以下语法：

```sh
# iscsictl -A -p 10.10.10.10 -t iqn.2012-06.com.example:target0 -u user -s secretsecret
```

### 32.13.2.2. 使用配置文件连接目标

要使用配置文件连接，请创建 **/etc/iscsi.conf**，内容如下：

```ini
t0 {
	TargetAddress   = 10.10.10.10
	TargetName      = iqn.2012-06.com.example:target0
	AuthMethod      = CHAP
	chapIName       = user
	chapSecret      = secretsecret
}
```

`t0` 指定配置文件部分的昵称。发起者将使用该昵称来指定要使用的配置。其他行指定连接时使用的参数。`TargetAddress` 和 `TargetName` 是必需的，而其他选项是可选的。在此示例中，显示了 CHAP 用户名和密码。

要连接到定义的目标，请指定昵称：

```sh
# iscsictl -An t0
```

或者，要连接到配置文件中定义的所有目标，可以使用：

```sh
# iscsictl -Aa
```

要使发起者自动连接到 **/etc/iscsi.conf** 中的所有目标，请将以下内容添加到 **/etc/rc.conf**：

```sh
iscsictl_enable="YES"
iscsictl_flags="-Aa"
```
