diff --git a/.yamllint b/.yamllint index 5465b58..676700a 100644 --- a/.yamllint +++ b/.yamllint @@ -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 diff --git a/CHANGELOG.md b/CHANGELOG.md index 7995413..33f6cc1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/README.md b/README.md index 964a70a..93add58 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/library/luks_decrypt.py b/library/luks_decrypt.py deleted file mode 100644 index 6942445..0000000 --- a/library/luks_decrypt.py +++ /dev/null @@ -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() diff --git a/library/luks_manage.py b/library/luks_manage.py deleted file mode 100644 index d44b661..0000000 --- a/library/luks_manage.py +++ /dev/null @@ -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() diff --git a/meta/main.yml b/meta/main.yml index 641eb02..0be0f2b 100644 --- a/meta/main.yml +++ b/meta/main.yml @@ -12,11 +12,11 @@ galaxy_info: platforms: - name: Debian versions: - - buster - - bullseye + - bookworm galaxy_tags: - - bacula - - backup + - encrypt + - harddisk + - security dependencies: [] diff --git a/molecule/default/converge.yml b/molecule/default/converge.yml index d507240..b81f4c3 100644 --- a/molecule/default/converge.yml +++ b/molecule/default/converge.yml @@ -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 diff --git a/molecule/default/molecule.yml b/molecule/default/molecule.yml index 620b6a5..9ac5f29 100644 --- a/molecule/default/molecule.yml +++ b/molecule/default/molecule.yml @@ -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: diff --git a/molecule/default/tests/test_default.py b/molecule/default/tests/test_default.py index 8468d10..8fceb29 100644 --- a/molecule/default/tests/test_default.py +++ b/molecule/default/tests/test_default.py @@ -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 diff --git a/tasks/main.yml b/tasks/main.yml index eb27f24..fc691e5 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -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