feat: use community.crypto.luks_device lib

This commit is contained in:
Adrien Waksberg 2024-07-05 10:02:39 +02:00
parent 02a216ed56
commit bd8ee1ae8b
10 changed files with 84 additions and 164 deletions

View file

@ -10,3 +10,11 @@ rules:
max: 120
level: warning
truthy: false
comments-indentation: false
comments:
min-spaces-from-content: 1
braces:
max-spaces-inside: 1
octal-values:
forbid-implicit-octal: true
forbid-explicit-octal: true

View file

@ -5,9 +5,13 @@ Which is based on [Keep A Changelog](http://keepachangelog.com/)
## [Unreleased]
### Breaking
- feat: use community.crypto.luks_device lib
### Added
- support debian 11
- test: support debian 12
### Changed
@ -20,8 +24,9 @@ chore: use FQCN module name
### Removed
- support debian 9
- support debian 10
- test: support debian 9
- test: support debian 10
- test: support debian 11
## v1.0.0 - 2019-03-16

View file

@ -3,34 +3,41 @@
[![Version](https://img.shields.io/badge/latest_version-1.0.0-green.svg)](https://git.yaegashi.fr/nishiki/ansible-role-luks/releases)
[![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](https://git.yaegashi.fr/nishiki/ansible-role-luks/src/branch/master/LICENSE)
Encrypt device with luks
Encrypt device with luks and mount this encrypted device
## Requirements
- Ansible >= 2.9
- Debian
- Bullseye
- Bookworm
## Role variables
- `luks_devices` - array with the devices to encrypt
```
- name: data_encrypted
device: /dev/sdx2
mount_point: /mnt/data_decrypted
fstype: ext4
cipher: aes-xts-plain
size: 256
key: secret
```yaml
- name: data_encrypted
device: /dev/sdx2
mount_point: /mnt/data_decrypted
fstype: ext4
cipher: aes
hash: sha256
passphrase: secret
```
## How to use
```
```yaml
- hosts: data
roles:
- luks
vars:
luks_devices:
- name: data_encrypted
device: /dev/loop0
fstype: ext4
mount_point: /mnt/data_decrypted
passphrase: secret
```
## Development

View file

@ -1,53 +0,0 @@
#!/usr/bin/python3
from ansible.module_utils.basic import *
import subprocess
import os
class LuksDecrypt:
def __init__(self, name, device):
self.name = name
self.device = device
def is_luks(self):
if subprocess.call(['cryptsetup', 'isLuks', self.device]) == 0:
return True
else:
return False
def is_decrypted(self):
return os.path.exists('/dev/mapper/{}'.format(self.name))
def decrypt(self, key):
p = subprocess.Popen(
[
'cryptsetup', '-q', 'open', '-d', '-', self.device, self.name
], stdin=subprocess.PIPE
)
p.stdin.write(key.encode())
p.communicate()[0]
p.stdin.close()
if p.returncode != 0:
raise ValueError('Error during the decrypt of device {}'.format(self.device))
def main():
fields = {
'name': { 'type': 'str', 'required': True },
'device': { 'type': 'str', 'required': True },
'key': { 'type': 'str', 'required': True, 'no_log': True }
}
module = AnsibleModule(argument_spec=fields)
changed = False
luks = LuksDecrypt(module.params['name'], module.params['device'])
if not luks.is_luks():
raise ValueError('Error the device {} is not a LUKS device'.format(module.params['device']))
elif not luks.is_decrypted():
luks.decrypt(module.params['key'])
changed = True
module.exit_json(changed=changed)
if __name__ == '__main__':
main()

View file

@ -1,52 +0,0 @@
#!/usr/bin/python3
from ansible.module_utils.basic import *
import subprocess
class LuksManage:
def __init__(self, device):
self.device = device
def is_luks(self):
if subprocess.call(['cryptsetup', 'isLuks', self.device]) == 0:
return True
else:
return False
def create(self, cipher, size, key):
p = subprocess.Popen(
[
'cryptsetup', '-q', 'luksFormat', '-c', cipher,
'-s', str(size), self.device, '-d', '-'
], stdin=subprocess.PIPE
)
p.stdin.write(key.encode())
p.communicate()[0]
p.stdin.close()
if p.returncode != 0:
raise ValueError('Error to create the luks device {}'.format(self.device))
def main():
fields = {
'device': { 'type': 'str', 'required': True },
'cipher': { 'type': 'str', 'default': 'aes-xts-plain' },
'size': { 'type': 'int', 'default': 256 },
'key': { 'type': 'str', 'required': True, 'no_log': True }
}
module = AnsibleModule(argument_spec=fields)
changed = False
luks = LuksManage(module.params['device'])
if not luks.is_luks():
luks.create(
module.params['cipher'],
module.params['size'],
module.params['key']
)
changed = True
module.exit_json(changed=changed)
if __name__ == '__main__':
main()

View file

@ -12,11 +12,11 @@ galaxy_info:
platforms:
- name: Debian
versions:
- buster
- bullseye
- bookworm
galaxy_tags:
- bacula
- backup
- encrypt
- harddisk
- security
dependencies: []

View file

@ -7,21 +7,25 @@
vars:
luks_devices:
- name: data_encrypted
device: /tmp/test.img
device: /dev/loop0
fstype: ext4
mount_point: /mnt/data_decrypted
key: secret
passphrase: secret
pre_tasks:
- name: update apt cache
- name: Update apt cache
ansible.builtin.apt:
update_cache: true
- name: check if test.img exists
- name: Check if test.img exists
ansible.builtin.stat:
path: /tmp/test.img
register: st
- name: create test.img
- name: Create test.img
ansible.builtin.command: dd if=/dev/zero of=/tmp/test.img bs=1M count=100
when: not st.stat.exists
- name: Create loop device
ansible.builtin.command: losetup -fP /tmp/test.img
when: not st.stat.exists

View file

@ -5,8 +5,8 @@ driver:
name: libvirt
platforms:
- name: debian11
box: debian/bullseye64
- name: debian12
box: debian/bookworm64
memory: 512
cpus: 1
instance_raw_config_args:

View file

@ -10,3 +10,7 @@ def test_mount_device_encrypted(host):
assert mount.exists
assert mount.device == '/dev/mapper/data_encrypted'
assert mount.filesystem == 'ext4'
def test_write_file(host):
cmd = host.run('sudo touch /mnt/data_decrypted/test.txt')
assert cmd.succeeded

View file

@ -1,53 +1,50 @@
---
- name: install packages
- name: Install packages
ansible.builtin.package:
name:
- cryptsetup
- util-linux
register: result
retries: 3
delay: 1
until: result is success
tags: luks
- name: create luks device
luks_manage:
device: '{{ item.device }}'
cipher: '{{ item.cipher|default("aes-xts-plain") }}'
size: '{{ item.size|default(256) }}'
key: '{{ item.key }}'
loop: '{{ luks_devices }}'
- name: Create luks device
community.crypto.luks_device:
device: "{{ item.device }}"
cipher: "{{ item.cipher | default(omit) }}"
hash: "{{ item.hash | default(omit) }}"
passphrase: "{{ item.passphrase }}"
loop: "{{ luks_devices }}"
loop_control:
label: '{{ item.name }} - {{ item.device }}'
label: "{{ item.name }} - {{ item.device }}"
tags: luks
- name: decrypt luks device
luks_decrypt:
device: '{{ item.device }}'
name: '{{ item.name }}'
key: '{{ item.key }}'
loop: '{{ luks_devices }}'
- name: Opened luks device
community.crypto.luks_device:
device: "{{ item.device }}"
name: "{{ item.name }}"
passphrase: "{{ item.passphrase }}"
state: opened
loop: "{{ luks_devices }}"
loop_control:
label: '{{ item.name }} - {{ item.device }}'
label: "{{ item.name }} - {{ item.device }}"
tags: luks
- name: format partition
ansible.builtin.filesystem:
fstype: '{{ item.fstype }}'
dev: '/dev/mapper/{{ item.name }}'
loop: '{{ luks_devices }}'
- name: Format partition
community.general.filesystem:
fstype: "{{ item.fstype }}"
dev: "/dev/mapper/{{ item.name }}"
loop: "{{ luks_devices }}"
loop_control:
label: '{{ item.name }} - {{ item.device }}'
label: "{{ item.name }} - {{ item.device }}"
tags: luks
- name: mount partition
ansible.builtin.mount:
src: '/dev/mapper/{{ item.name }}'
path: '{{ item.mount_point }}'
fstype: '{{ item.fstype }}'
opts: noauto
- name: Mount partition
ansible.posix.mount:
src: "/dev/mapper/{{ item.name }}"
path: "{{ item.mount_point }}"
fstype: "{{ item.fstype }}"
opts: defaults,noauto
state: mounted
loop: '{{ luks_devices }}'
loop: "{{ luks_devices }}"
loop_control:
label: '{{ item.name }} - {{ item.device }}'
label: "{{ item.name }} - {{ item.device }}"
tags: luks