Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save vishalbelsare/423aa882b85a33cacc7c6cc656a44399 to your computer and use it in GitHub Desktop.
Save vishalbelsare/423aa882b85a33cacc7c6cc656a44399 to your computer and use it in GitHub Desktop.

Revisions

  1. @MawKKe MawKKe revised this gist Mar 19, 2018. 1 changed file with 18 additions and 18 deletions.
    36 changes: 18 additions & 18 deletions cryptsetup-with-luks2-and-integrity-demo.sh
    Original file line number Diff line number Diff line change
    @@ -6,13 +6,13 @@
    #
    # What?
    #
    # Linux dm-crypt + dm-integrity + dm-raid (RAID1)
    # Linux dm-crypt + dm-integrity + dm-raid (RAID1)
    #
    # = Secure, redundant array with data integrity protection
    # = Secure, redundant array with data integrity protection
    #
    # Why?
    #
    # You see, RAID1 is dead simple tool for disk redundancy,
    # You see, RAID1 is dead simple tool for disk redundancy,
    # but it does NOT protect you from bit rot. There is no way
    # for RAID1 to distinguish which drive has the correct data if rot occurs.
    # This is a silent killer.
    @@ -32,9 +32,9 @@
    #
    # How cool is that?
    #
    # Also: If you use RAID1 arrays as LVM physical volumes, the overall
    # architecture is quite similar to ZFS! All with native Linux tools,
    # and no hacky solaris compatibility layers or licencing issues!
    # Also: If you use RAID1 arrays as LVM physical volumes, the overall
    # architecture is quite similar to ZFS! All with native Linux tools,
    # and no hacky solaris compatibility layers or licencing issues!
    #
    # (I guess you can use whatever RAID level you want, but RAID1 is the
    # simplest and fastest to set up)
    @@ -78,13 +78,13 @@ cryptsetup luksOpen disk2.img disk2luks --key-file key.bin
    # Create raid1:

    mdadm \
    --create \
    --verbose --level 1 \
    --metadata=1.2 \
    --raid-devices=2 \
    /dev/md/mdtest \
    /dev/mapper/disk1luks \
    /dev/mapper/disk2luks
    --create \
    --verbose --level 1 \
    --metadata=1.2 \
    --raid-devices=2 \
    /dev/md/mdtest \
    /dev/mapper/disk1luks \
    /dev/mapper/disk2luks


    # Create a filesystem, add to LVM volume group, etc...
    @@ -98,7 +98,7 @@ mkfs.ext4 /dev/md/mdtest
    #
    # To scrub the array:
    #
    # $ echo check > /sys/block/md127/md/sync_action
    # $ echo check > /sys/block/md127/md/sync_action
    #
    # ... wait a while
    #
    @@ -129,11 +129,11 @@ mkfs.ext4 /dev/md/mdtest
    # ...
    # [959146.618086] md: data-check of RAID array md127
    # [959146.962543] device-mapper: crypt: INTEGRITY AEAD ERROR, sector 39784
    # [959146.963086] device-mapper: crypt: INTEGRITY AEAD ERROR, sector 39840
    # [959146.963086] device-mapper: crypt: INTEGRITY AEAD ERROR, sector 39840
    # [959154.932650] md: md127: data-check done.
    #
    # But now if you run scrub yet again:
    # ...
    # ...
    # [959212.329473] md: data-check of RAID array md127
    # [959220.566150] md: md127: data-check done.
    #
    @@ -154,11 +154,11 @@ mkfs.ext4 /dev/md/mdtest
    # $ mdadm --create ...
    #
    # ...and so on. Though now you can detect and repair disk errors but have no protection
    # against malicious cold-storage attacks. Data is also readable by anybody.
    # against malicious cold-storage attacks. Data is also readable by anybody.
    #
    # 2018-03 NOTE:
    #
    # if you override the default --integrity value (whatever it is) during formatting,
    # if you override the default --integrity value (whatever it is) during formatting,
    # then you must specify it again when opening, like in the example above. For some
    # reason the algorithm is not autodetected. I guess there is no header written onto
    # disk like is with LUKS ?
  2. @MawKKe MawKKe revised this gist Mar 19, 2018. 1 changed file with 7 additions and 7 deletions.
    14 changes: 7 additions & 7 deletions cryptsetup-with-luks2-and-integrity-demo.sh
    Original file line number Diff line number Diff line change
    @@ -77,13 +77,13 @@ cryptsetup luksOpen disk2.img disk2luks --key-file key.bin

    # Create raid1:

    mdadm \
    --create \
    --verbose --level 1 \
    --metadata=1.2 \
    --raid-devices=2 \
    /dev/md/mdtest \
    /dev/mapper/disk1luks \
    mdadm \
    --create \
    --verbose --level 1 \
    --metadata=1.2 \
    --raid-devices=2 \
    /dev/md/mdtest \
    /dev/mapper/disk1luks \
    /dev/mapper/disk2luks


  3. @MawKKe MawKKe revised this gist Mar 19, 2018. No changes.
  4. @MawKKe MawKKe created this gist Mar 19, 2018.
    172 changes: 172 additions & 0 deletions cryptsetup-with-luks2-and-integrity-demo.sh
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,172 @@
    #!/usr/bin/env bash
    #
    # Author: Markus (MawKKe) [email protected]
    # Date: 2018-03-19
    #
    #
    # What?
    #
    # Linux dm-crypt + dm-integrity + dm-raid (RAID1)
    #
    # = Secure, redundant array with data integrity protection
    #
    # Why?
    #
    # You see, RAID1 is dead simple tool for disk redundancy,
    # but it does NOT protect you from bit rot. There is no way
    # for RAID1 to distinguish which drive has the correct data if rot occurs.
    # This is a silent killer.
    #
    # But with dm-integrity, you can now have error detection
    # at the block level. But it alone does not provide error correction
    # and is pretty useless with just one disk (disks fail, shit happens).
    #
    # But if you use dm-integrity *below* RAID1, now you have disk redundancy,
    # AND error checking AND error correction. Invalid data received from
    # a drive will cause a checksum error which the RAID array notices and
    # replaces with correct data.
    #
    # If you throw encryption into the mix, you'll have secure,
    # redundant array. Oh, and the data integrity can be protected with
    # authenticated encryption, so no-one can tamper your data maliciously.
    #
    # How cool is that?
    #
    # Also: If you use RAID1 arrays as LVM physical volumes, the overall
    # architecture is quite similar to ZFS! All with native Linux tools,
    # and no hacky solaris compatibility layers or licencing issues!
    #
    # (I guess you can use whatever RAID level you want, but RAID1 is the
    # simplest and fastest to set up)
    #
    #
    # Let's try it out!
    #
    # ---
    # NOTE: The dm-integrity target is available since Linux kernel version 4.12.
    # NOTE: This example requires LUKS2 which is only recently released (2018-03)
    # NOTE: The authenticated encryption is still experimental (2018-03)
    # ---

    set -eux

    # 1) Make dummy disks

    cd /tmp

    truncate -s 500M disk1.img
    truncate -s 500M disk2.img

    # Format the disk with luksFormat:

    dd if=/dev/urandom of=key.bin bs=512 count=1

    cryptsetup luksFormat -q --type luks2 --integrity hmac-sha256 disk1.img key.bin
    cryptsetup luksFormat -q --type luks2 --integrity hmac-sha256 disk2.img key.bin

    # The luksFormat's might take a while since the --integrity causes the disks to be wiped.
    # dm-integrity is usually configured with 'integritysetup' (see below), but as
    # it happens, cryptsetup can do all the integrity configuration automatically if
    # the --integrity flag is specified.

    # Open/attach the encrypted disks

    cryptsetup luksOpen disk1.img disk1luks --key-file key.bin
    cryptsetup luksOpen disk2.img disk2luks --key-file key.bin


    # Create raid1:

    mdadm \
    --create \
    --verbose --level 1 \
    --metadata=1.2 \
    --raid-devices=2 \
    /dev/md/mdtest \
    /dev/mapper/disk1luks \
    /dev/mapper/disk2luks


    # Create a filesystem, add to LVM volume group, etc...

    mkfs.ext4 /dev/md/mdtest

    # Cool! Now you can 'scrub' the raid setup, which verifies
    # the contents of each drive. Ordinarily detecting an error would
    # be problematic, but since we are now using dm-integrity, the raid1
    # *knows* which one has the correct data, and is able to fix it automatically.
    #
    # To scrub the array:
    #
    # $ echo check > /sys/block/md127/md/sync_action
    #
    # ... wait a while
    #
    # $ dmesg | tail -n 30
    #
    # You should see
    #
    # [957578.661711] md: data-check of RAID array md127
    # [957586.932826] md: md127: data-check done.
    #
    #
    # Let's simulate disk corruption:
    #
    # $ dd if=/dev/urandom of=disk2.img seek=30000 count=30 bs=1k conv=notrunc
    #
    # (this writes 30kB of random data into disk2.img)
    #
    #
    # Run scrub again:
    #
    # $ echo check > /sys/block/md127/md/sync_action
    #
    # ... wait a while
    #
    # $ dmesg | tail -n 30
    #
    # Now you should see
    # ...
    # [959146.618086] md: data-check of RAID array md127
    # [959146.962543] device-mapper: crypt: INTEGRITY AEAD ERROR, sector 39784
    # [959146.963086] device-mapper: crypt: INTEGRITY AEAD ERROR, sector 39840
    # [959154.932650] md: md127: data-check done.
    #
    # But now if you run scrub yet again:
    # ...
    # [959212.329473] md: data-check of RAID array md127
    # [959220.566150] md: md127: data-check done.
    #
    # And since we didn't get any errors a second time, we can deduce that the invalid
    # data was repaired automatically.
    #
    # Great! We are done.
    #
    # --------
    #
    # If you don't need encryption, then you can use 'integritysetup' instead of cryptsetup.
    # It works in similar fashion:
    #
    # $ integritysetup format --integrity sha256 disk1.img
    # $ integritysetup format --integrity sha256 disk2.img
    # $ integritysetup open --integrity sha256 disk1.img disk1int
    # $ integritysetup open --integrity sha256 disk2.img disk2int
    # $ mdadm --create ...
    #
    # ...and so on. Though now you can detect and repair disk errors but have no protection
    # against malicious cold-storage attacks. Data is also readable by anybody.
    #
    # 2018-03 NOTE:
    #
    # if you override the default --integrity value (whatever it is) during formatting,
    # then you must specify it again when opening, like in the example above. For some
    # reason the algorithm is not autodetected. I guess there is no header written onto
    # disk like is with LUKS ?
    #
    # ----------
    #
    # Read more:
    # https://fosdem.org/2018/schedule/event/cryptsetup/
    # https://gitlab.com/cryptsetup/cryptsetup/wikis/DMCrypt
    # https://gitlab.com/cryptsetup/cryptsetup/wikis/DMIntegrity
    # https://mirrors.edge.kernel.org/pub/linux/utils/cryptsetup/v2.0/v2.0.0-rc0-ReleaseNotes