Commit 2ce2fe09 authored by Krzysztof Karas's avatar Krzysztof Karas Committed by Konrad Sztyber
Browse files

doc/nvmf: Add section about TLS in NVMe-oF



Add section describing TLS setup in SPDK NVMe-oF.

Change-Id: I1915a8a034fb7ba76c9f01ed0d517e9258fce9a0
Signed-off-by: default avatarKrzysztof Karas <krzysztof.karas@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/17357


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarTomasz Zawadzki <tomasz.zawadzki@intel.com>
Reviewed-by: default avatarKonrad Sztyber <konrad.sztyber@intel.com>
parent 03b6183a
Loading
Loading
Loading
Loading
+70 −0
Original line number Diff line number Diff line
@@ -273,3 +273,73 @@ SPDK has a tracing framework for capturing low-level event information at runtim

The SPDK NVMe-oF target and initiator support multiple independent paths to the same NVMe-oF subsystem.
For step-by-step instructions for configuring and switching between paths, see @ref nvmf_multipath_howto .

## Enabling NVMe-oF TLS

The SPDK NVMe-oF target and initiator support establishing a secure TCP connection using Transport
Layer Security (TLS) protocol in compliance with NVMe TCP transport specification. Only version 1.3
of the TLS protocol is supported.

Currently, it is only possible to establish a fabric secure channel using TLS and NVMe-oF in-band
authentication is not supported. The channel is protected by a symmetric pre-shared key (PSK) using
either `TLS_AES_256_GCM_SHA384` (recommended) or `TLS_AES_128_GCM_SHA256` cipher suite. The cipher
suite is selected based on the hash function associated with a key. During configuration, the keys
are expected to be in the PSK interchange format (see NVMe TCP transport specification 1.0c,
section 3.6.1.5).

The target supports assigning different keys for each host connecting to a given subsystem. It is
also possible for a single host to use different keys for different subsystems. The keys are
expected to be placed in separate files (with permissions configured only to allow read/write
access to the owner) and can be configured using the `--psk` option in the `nvmf_subsystem_add_host`
RPC. Additionally, to allow establishing TLS connections on a given listener, it must be created
with `--secure-channel` option enabled. It's also worth noting that this option is mutually
exclusive with `--allow-any-host` subsystem option and trying to add a listener to such a subsystem
will result in an error.

On the initiator side, the key can be specified using `--psk` option in the
`bdev_nvme_attach_controller` RPC.

Recommendations on the pre-shared keys:

* It is strongly recommended to change the keys at least once a year.
* Use a strong cryptographic random number generator that provides sufficient entropy
  to generate the keys (e.g. HSM).
* Use a single key to secure transmission between two systems only.
* Delete files containing PSKs as soon as they are not needed.

Additionally, it is recommended to follow:
[RFC 9257 'Guidance for External Pre-Shared Key (PSK) Usage in TLS'](https://www.rfc-editor.org/rfc/rfc9257.html)

### Target setup

~~~{.sh}
cat key.txt
NVMeTLSkey-1:01:MDAxMTIyMzM0NDU1NjY3Nzg4OTlhYWJiY2NkZGVlZmZwJEiQ:

build/bin/nvmf_tgt &
scripts/rpc.py nvmf_create_transport -t TCP
scripts/rpc.py nvmf_create_subsystem nqn.2016-06.io.spdk:cnode1 -s SPDK00000000000001 -m 10
scripts/rpc.py nvmf_subsystem_add_listener nqn.2016-06.io.spdk:cnode1 -t tcp -a 127.0.0.1 -s 4420 \
               --secure-channel
scripts/rpc.py nvmf_subsystem_add_host nqn.2016-06.io.spdk:cnode1 nqn.2016-06.io.spdk:host1 \
               --psk key.txt
~~~

### Initiator setup

For SPDK initiator example, bdevperf application may be used, because it depends on SPDK's
NVMe TCP driver.

~~~{.sh}
cat key.txt
NVMeTLSkey-1:01:MDAxMTIyMzM0NDU1NjY3Nzg4OTlhYWJiY2NkZGVlZmZwJEiQ:

build/examples/bdevperf -m 0x2 -z -r /var/tmp/bdevperf.sock -q 128 -o 4096 -w verify -t 10 &
scripts/rpc.py -s /var/tmp/bdevperf.sock bdev_nvme_attach_controller -b TLSTEST -t tcp -a 127.0.0.1 \
               -s 4420 -f ipv4 -n nqn.2016-06.io.spdk:cnode1 -q nqn.2016-06.io.spdk:host1 \
               --psk key.txt
~~~

First of the two commands will launch bdevperf, the second one will attempt to construct NVMe bdev
and establish TLS connection. Of course, the same PSK must be used on both the target and the
initiator side.