Compare commits

...

9 commits
v1.0.0 ... main

18 changed files with 192 additions and 386 deletions

2
.gitignore vendored
View file

@ -1,2 +1,2 @@
.kitchen/*
*.pyc

View file

@ -1,26 +0,0 @@
---
driver:
name: vagrant
provider: virtualbox
box: bento/debian-9.5
provisioner:
name: ansible_playbook
hosts: localhost
require_ansible_repo: false
require_ansible_omnibus: true
require_chef_for_busser: true
ansible_verbose: false
ansible_inventory: ./test/integration/inventory
platforms:
- name: debian-9
driver_config:
image: "nishiki/debian9:ansible-<%= ENV['ANSIBLE_VERSION'] ? ENV['ANSIBLE_VERSION'] : '2.7' %>"
command: /bin/systemd
volume:
- /sys/fs/cgroup:/sys/fs/cgroup:ro
security_opt: seccomp=unconfined
suites:
- name: default

View file

@ -1,38 +0,0 @@
---
AllCops:
Exclude:
- db/**/*
- config/**/*
- Vagrantfile
TargetRubyVersion: 2.4
Naming/AccessorMethodName:
Enabled: false
Lint/RescueWithoutErrorClass:
Enabled: false
Metrics/LineLength:
Max: 120
Metrics/CyclomaticComplexity:
Enabled: false
Metrics/PerceivedComplexity:
Enabled: false
Metrics/MethodLength:
Enabled: false
Metrics/BlockLength:
Enabled: false
Metrics/ClassLength:
Enabled: false
Metrics/AbcSize:
Enabled: false
Style/NumericLiteralPrefix:
Enabled: false
Style/FrozenStringLiteralComment:
Enabled: false
Style/CommandLiteral:
Enabled: true
EnforcedStyle: percent_x
Style/Documentation:
Enabled: false

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,5 +5,31 @@ Which is based on [Keep A Changelog](http://keepachangelog.com/)
## [Unreleased]
## [1.0.0] - 2019-03-16
## v2.0.0 - 2024-07-05
### Breaking
- feat: use community.crypto.luks_device lib
### Added
- test: support debian 12
### Changed
test: replace kitchen to molecule
chore: use FQCN module name
### Fixed
- no show log with luks password
### Removed
- test: support debian 9
- test: support debian 10
- test: support debian 11
## v1.0.0 - 2019-03-16
- first version

View file

@ -1,8 +0,0 @@
source 'https://rubygems.org'
group :development do
gem 'kitchen-ansible'
gem 'kitchen-vagrant'
gem 'rubocop', '0.50.0'
gem 'test-kitchen'
end

View file

@ -1,92 +0,0 @@
GEM
remote: https://rubygems.org/
specs:
ast (2.4.0)
builder (3.2.3)
erubis (2.7.0)
ffi (1.10.0)
gssapi (1.2.0)
ffi (>= 1.0.1)
gyoku (1.3.1)
builder (>= 2.1.2)
httpclient (2.8.3)
kitchen-ansible (0.49.1)
net-ssh (>= 3)
test-kitchen (~> 1.4)
kitchen-vagrant (1.5.0)
test-kitchen (~> 1.4)
little-plugger (1.1.4)
logging (2.2.2)
little-plugger (~> 1.1)
multi_json (~> 1.10)
mixlib-install (3.11.11)
mixlib-shellout
mixlib-versioning
thor
mixlib-shellout (2.4.4)
mixlib-versioning (1.2.7)
multi_json (1.13.1)
net-scp (1.2.1)
net-ssh (>= 2.6.5)
net-ssh (4.2.0)
net-ssh-gateway (1.3.0)
net-ssh (>= 2.6.5)
nori (2.6.0)
parallel (1.14.0)
parser (2.6.0.0)
ast (~> 2.4.0)
powerpack (0.1.2)
rainbow (2.2.2)
rake
rake (12.3.2)
rubocop (0.50.0)
parallel (~> 1.10)
parser (>= 2.3.3.1, < 3.0)
powerpack (~> 0.1)
rainbow (>= 2.2.2, < 3.0)
ruby-progressbar (~> 1.7)
unicode-display_width (~> 1.0, >= 1.0.1)
ruby-progressbar (1.10.0)
rubyntlm (0.6.2)
rubyzip (1.2.2)
test-kitchen (1.24.0)
mixlib-install (~> 3.6)
mixlib-shellout (>= 1.2, < 3.0)
net-scp (~> 1.1)
net-ssh (>= 2.9, < 5.0)
net-ssh-gateway (~> 1.2)
thor (~> 0.19)
winrm (~> 2.0)
winrm-elevated (~> 1.0)
winrm-fs (~> 1.1)
thor (0.20.3)
unicode-display_width (1.5.0)
winrm (2.3.1)
builder (>= 2.1.2)
erubis (~> 2.7)
gssapi (~> 1.2)
gyoku (~> 1.0)
httpclient (~> 2.2, >= 2.2.0.2)
logging (>= 1.6.1, < 3.0)
nori (~> 2.0)
rubyntlm (~> 0.6.0, >= 0.6.1)
winrm-elevated (1.1.1)
winrm (~> 2.0)
winrm-fs (~> 1.0)
winrm-fs (1.3.2)
erubis (~> 2.7)
logging (>= 1.6.1, < 3.0)
rubyzip (~> 1.1)
winrm (~> 2.0)
PLATFORMS
ruby
DEPENDENCIES
kitchen-ansible
kitchen-vagrant
rubocop (= 0.50.0)
test-kitchen
BUNDLED WITH
1.16.0

View file

@ -1,56 +1,55 @@
# Ansible role: Luks
[![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
[![Version](https://img.shields.io/badge/latest_version-2.0.0-green.svg)](https://code.waks.be/nishiki/ansible-role-luks/releases)
[![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](https://code.waks.be/nishiki/ansible-role-luks/src/branch/main/LICENSE)
Encrypt device with luks and mount this encrypted device
## Requirements
* Ansible >= 2.5
* Debian Stretch
- Ansible >= 2.9
- Debian
- Bookworm
## Role variables
* `luks_devices` - array with the devices to encrypt
- `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
### Test syntax with yamllint
* install `python` and `python-pip`
* install yamllint `pip install yamllint`
* run `yamllint .`
### Test with molecule and docker
### Test syntax with ansible-lint
* install `python` and `python-pip`
* install yamllint `pip install ansible-lint`
* run `ansible-lint .`
### Tests with docker
* install [docker](https://docs.docker.com/engine/installation/)
* install ruby
* install bundler `gem install bundler`
* install dependencies `bundle install`
* run the tests `kitchen test`
- install libvirt on debian `apt install libvirt-dev qemu-system libvirt-clients libvirt-daemon-system`
- install [vagrant](https://www.vagrantup.com/docs/installation)
- install vagrant libvirt plusin `vagrant plugin install vagrant-libvirt`
- install `python3` and `python3-pip`
- install molecule and dependencies `pip3 install molecule python-vagrant molecule-vagrant ansible-lint pytest-testinfra yamllint`
- run `molecule test`
## License

View file

@ -1,53 +0,0 @@
#!/usr/bin/python
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)
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 }
}
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/python
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)
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 }
}
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()

22
meta/main.yml Normal file
View file

@ -0,0 +1,22 @@
---
galaxy_info:
role_name: luks
namespace: nishiki
author: Adrien Waksberg
company: Adrien Waksberg
description: Encrypt device with luks
license: Apache2
min_ansible_version: "2.9"
platforms:
- name: Debian
versions:
- bookworm
galaxy_tags:
- encrypt
- harddisk
- security
dependencies: []

View file

@ -0,0 +1,31 @@
---
- name: Converge
hosts: all
become: true
roles:
- ansible-role-luks
vars:
luks_devices:
- name: data_encrypted
device: /dev/loop0
fstype: ext4
mount_point: /mnt/data_decrypted
passphrase: secret
pre_tasks:
- name: Update apt cache
ansible.builtin.apt:
update_cache: true
- name: Check if test.img exists
ansible.builtin.stat:
path: /tmp/test.img
register: st
- 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

@ -0,0 +1,19 @@
---
driver:
name: vagrant
provider:
name: libvirt
platforms:
- name: debian12
box: debian/bookworm64
memory: 512
cpus: 1
instance_raw_config_args:
- vagrant.plugins = ["vagrant-libvirt"]
lint: |
set -e
yamllint .
ansible-lint .
verifier:
name: testinfra

View file

@ -0,0 +1,16 @@
import testinfra.utils.ansible_runner
def test_packages(host):
for package_name in ['cryptsetup', 'util-linux']:
package = host.package(package_name)
assert package.is_installed
def test_mount_device_encrypted(host):
mount = host.mount_point('/mnt/data_decrypted')
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,49 +1,50 @@
---
- name: install packages
package:
name: '{{ packages }}'
vars:
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 }}'
no_log: true
- 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 }}"
tags: luks
- name: decrypt luks device
luks_decrypt:
device: '{{ item.device }}'
name: '{{ item.name }}'
key: '{{ item.key }}'
loop: '{{ luks_devices }}'
no_log: true
- 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 }}"
tags: luks
- name: format partition
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 }}"
tags: luks
- name: mount partition
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 }}"
tags: luks

View file

@ -1,21 +0,0 @@
---
- hosts: localhost
connection: local
vars:
luks_devices:
- name: data_encrypted
device: /tmp/test.img
fstype: ext4
mount_point: /mnt/data_decrypted
key: secret
pre_tasks:
- stat:
path: /tmp/test.img
register: st
- command: dd if=/dev/zero of=/tmp/test.img bs=1M count=100
when: not st.stat.exists
roles:
- ansible-role-luks

View file

@ -1,25 +0,0 @@
require 'serverspec'
set :backend, :exec
puts
puts '================================'
puts %x(ansible --version)
puts '================================'
%w[
cryptsetup
util-linux
].each do |package|
describe package(package) do
it { should be_installed }
end
end
describe file('/dev/mapper/data_encrypted') do
it { should be_block_device }
end
describe file('/mnt/data_decrypted') do
it { should be_mounted }
end

View file

@ -1 +0,0 @@
localhost