The idea here is to have a LUKS2 encrypted volume stored on a remote server that allows authenticated clients to load and decrypt the data without letting the server know what is being written, read and stored.
Keep in mind that this solution is not 100% bulletproof, you still kind of have to trust the backup server because a malicious entity might take multiple snapshots of the encrypted iSCSI LUN and try to crack the encryption.

.:. Server A.K.A. Target

Install the required packages:


$ su -c "yum install targetcli && systemctl start target && systemctl enable target"

Target configuration is done via the command line utility “targetcli”.
Select a device or a file as backstore:


$ sudo targetcli

/> /backstores/fileio create file1 /tmp/disk1.img 2000GB write_back=false

Create an iSCSI target:


/> iscsi/
/iscsi> create

Configure a LUN:


/iscsi/iqn.20...mple:444/tpg1> luns/ create /backstores/fileio/file1

Add some ACLs, to get the server FQDN use:


$ sudo iscsiadm -m discovery -t st -p 127.0.0.1

/iscsi/iqn.20...mple:444/tpg1> acls/
/iscsi/iqn.20...444/tpg1/acls> create <FQDN>

Disable authentication and set a user/password for CHAP auth:


/iscsi/iqn.20...mple:444/tpg1 set attribute authentication=0
/iscsi/iqn.20...mple:444/tpg1/acls/iqn.20...mple:444/ set auth userid=<USER> password=>PASSWORD>
exit

Restart the service:


$ sudo systemctl restart target

.:. Client A.K.A. Initiator

Install the required packages:


$ sudo dnf install -y iscsi-initiator-utils

Edit iSCSI configuration file to instruct the initiator to use CHAP authentication, uncomment or add the following lines:


$ vi language=/etc/iscsi/initiatorname.iscsi
---
node.session.auth.authmethod = CHAP
# As USER and PASSWORD use the ones you created on the Target machine when defining the iSCSI LUN
node.session.auth.username = <USER>
node.session.auth.password = <PASSWORD>

Discover and load the iSCSI target:


$ sudo iscsiadm -m discovery -t sendtargets -p <TARGET-IP-ADDRESS>;
$ sudo iscsiadm -m discovery -P1
$ sudo systemctl restart iscsid
$ sudo iscsiadm -m node -T <FQDN displayed using the discovery command> -l

Now that the iSCSI target is loaded we can mount it, but first we need to identify its device name (in this case it is /dev/sdf):


$ lsblk --scsi
NAME HCTL       TYPE VENDOR   MODEL             REV TRAN
sda  1:0:0:0    disk ATA      AAA              BBB  sata
sdb  4:0:0:0    disk ATA      AAA              BBB  sata
sdc  5:0:0:0    disk ATA      AAA              BBB  sata
sdd  6:0:0:0    disk ATA      AAA              BBB  sata
sde  7:0:0:0    disk ATA      AAA              BBB  sata
sdf  10:0:0:0   disk LIO-ORG  backup           4.0  iscsi

The iSCSI target behaves like a physical hard drive, we can partion it, format it, mount it, etc as usual.
In this particular case we want to create a LUKS2 encrypted volume, to do so run:


$ sudo cryptsetup luksFormat -M luks2 --pbkdf argon2id -i 5000 /dev/sdf
$ sudo cryptsetup luksOpen /dev/sdf <luks_volume_name>;
$ sudo mkfs.xfs /dev/mapper/<luks_volume_name>;
$ sudo mount /dev/mapper/<luks_volume_name> /mountpoint

To unmount the encrypted LUKS2 iSCSI target run:


$ sudo sync
$ sudo umount /mnt/backup
$ sudo cryptsetup luksClose /dev/mapper/backup
$ sudo iscsiadm -m node -T <FQDN displayed using the discovery command> -u

###.:. Target iptables configuration

Instruct iptables to allow TCP traffic on port 3260.


$ systemctl stop iptables

Add the following rule and restart iptables.


$ vi language=/etc/sysconfig/iptables
---
-A INPUT -p tcp -m state --state NEW -m tcp --dport 3260 -j ACCEPT

systemctl start iptables

[0] https://uwot.eu/luks2-the-right-way-argon2/
[1] https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/storage_administration_guide/online-storage-management#osm-target-setup
[2] https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/storage_administration_guide/osm-create-iscsi-initiator
[3] https://www.lisenet.com/2016/iscsi-target-and-initiator-configuration-on-rhel-7/