From 0a3837db64975c86b1454cd71da82a1e239f3bdd Mon Sep 17 00:00:00 2001 From: mwiegand Date: Wed, 13 Oct 2021 00:10:10 +0200 Subject: [PATCH] dmcrypt --- bundles/dm-crypt/README.md | 24 ++++++++++++++++++++++++ bundles/dm-crypt/items.py | 29 +++++++++++++++++++++++++++++ bundles/dm-crypt/metadata.py | 22 ++++++++++++++++++++++ nodes/wb.offsite-backups.py | 27 ++++++++++++++------------- 4 files changed, 89 insertions(+), 13 deletions(-) create mode 100644 bundles/dm-crypt/README.md create mode 100644 bundles/dm-crypt/items.py create mode 100644 bundles/dm-crypt/metadata.py diff --git a/bundles/dm-crypt/README.md b/bundles/dm-crypt/README.md new file mode 100644 index 0000000..f3a6b35 --- /dev/null +++ b/bundles/dm-crypt/README.md @@ -0,0 +1,24 @@ +dm-crypt +======== + +Create encrypted block devices using `dm-crypt` on GNU/Linux. Unlocking +these devices will be done on runs of `bw apply`. + +Metadata +-------- + + 'dm-crypt': { + 'encrypted-devices': { + 'foobar': { + 'device': '/dev/sdb', + # either + 'salt': 'muWWU7dr+5Wtk+56OLdqUNZccnzXPUTJprMSMxkstR8=', + # or + 'password': vault.decrypt('passphrase'), + }, + }, + }, + +This will encrypt `/dev/sdb` using the specified passphrase. When the +device is going to be unlocked, it will be available as +`/dev/mapper/foobar`. diff --git a/bundles/dm-crypt/items.py b/bundles/dm-crypt/items.py new file mode 100644 index 0000000..5fb5eae --- /dev/null +++ b/bundles/dm-crypt/items.py @@ -0,0 +1,29 @@ +for name, conf in node.metadata.get('dm-crypt').items(): + actions[f'dm-crypt_format_{name}'] = { + 'cascade_skip': False, + 'command': f"cryptsetup --batch-mode luksFormat --cipher aes-xts-plain64 --key-size 512 '{conf['device']}'", + 'data_stdin': conf['password'], + 'unless': f"blkid -t TYPE=crypto_LUKS '{conf['device']}'", + 'comment': f"WARNING: This DESTROYS the contents of the device: '{conf['device']}'", + 'needs': { + 'pkg_apt:cryptsetup', + }, + } + + actions[f'dm-crypt_open_{name}'] = { + 'cascade_skip': False, + 'command': f"cryptsetup --batch-mode luksOpen '{conf['device']}' '{name}'", + 'data_stdin': conf['password'], + 'unless': f"test -e /dev/mapper/{name}", + 'comment': f"Unlocks the device '{conf['device']}' and makes it available in: '/dev/mapper/{name}'", + 'needs': { + f"action:dm-crypt_format_{name}", + 'pkg_apt:cryptsetup', + }, + 'needed_by': set(), + } + + if node.has_bundle('zfs'): + for pool, pool_conf in node.metadata.get('zfs/pools').items(): + if f'/dev/mapper/{name}' in pool_conf['devices']: + actions[f'dm-crypt_open_{name}']['needed_by'].add(f'zfs_pool:{pool}') diff --git a/bundles/dm-crypt/metadata.py b/bundles/dm-crypt/metadata.py new file mode 100644 index 0000000..36da82e --- /dev/null +++ b/bundles/dm-crypt/metadata.py @@ -0,0 +1,22 @@ +defaults = { + 'apt': { + 'packages': { + 'cryptsetup': {}, + }, + }, + 'dm-crypt': {}, +} + + +@metadata_reactor.provides( + 'dm-crypt', +) +def password_from_salt(metadata): + return { + 'dm-crypt': { + name: { + 'password': repo.vault.password_for(f"dm-crypt/{metadata.get('id')}/{name}"), + } + for name, conf in metadata.get('dm-crypt').items() + } + } diff --git a/nodes/wb.offsite-backups.py b/nodes/wb.offsite-backups.py index 0d6a3a4..36096fd 100644 --- a/nodes/wb.offsite-backups.py +++ b/nodes/wb.offsite-backups.py @@ -4,15 +4,11 @@ 'debian-11', ], 'bundles': [ + 'dm-crypt', 'wireguard', 'zfs', ], 'metadata': { - # TEMP - 'nameservers': { - '8.8.8.8', - }, - 'id': '23b898bd-203b-42d5-8150-cdb459915d77', 'network': { 'internal': { @@ -21,6 +17,18 @@ 'gateway4': '192.168.178.1', }, }, + 'dm-crypt': { + 'tank': { + 'device': '/dev/disk/by-id/ata-TOSHIBA_MG06ACA10TE_61C0A1B1FKQE', + }, + }, + 'users': { + 'root': { + 'authorized_users': { + 'root@home.backups', + }, + }, + }, 'wireguard': { 'my_ip': '172.30.0.4/32', 's2s': { @@ -35,18 +43,11 @@ }, }, }, - 'users': { - 'root': { - 'authorized_users': { - 'root@home.backups', - }, - }, - }, 'zfs': { 'pools': { 'tank': { 'devices': [ - '/dev/disk/by-id/ata-TOSHIBA_MG06ACA10TE_61C0A1B1FKQE', + '/dev/mapper/tank', ], }, },