Remote encrypted backup with iSCSI and LUKS2
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
.:. Links
[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/