Skip to content

Commit

Permalink
ansible-scylla-node: Add support for system resources encryption
Browse files Browse the repository at this point in the history
System encryption is applied to semi-transient on-disk data, such as commit logs, batch
logs, and hinted handoff data.
This patch adds support for it by adding the variables system_info_encryption_local
and system_info_encryption_kmip. The former should be used for a LocalKeyProvider
and the latter for a KMIPKeyProvider.
If the user is using a KMIPKeyProvider the variable kmip_hosts, also added in this
patch, must be set.
The details of how these variables must be used are described in
ansible-scylla-node/defaults/main.yml along with the other variables from the node
role.
  • Loading branch information
igorribeiroduarte committed Sep 6, 2023
1 parent f7efce8 commit c279144
Show file tree
Hide file tree
Showing 4 changed files with 135 additions and 1 deletion.
43 changes: 43 additions & 0 deletions ansible-scylla-node/defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,49 @@ scylla_ssl:
client:
enabled: true

# Encrypt system resources:
# System encryption is applied to semi-transient on-disk data, such as commit logs, batch logs, and hinted handoff data.
# If you'd like to use a LocalKeyProvider, please use the system_info_encrypt_local config
# If you'd like to use a KMIPKeyProvider, please use the system_info_encryption_kmip config

# LocalKeyProvider:
# To use your own key, copy it to {{ localhost_key_dir }} with the name {{ key_name }} and then this key will be copied to all the nodes.
# If you don't provide your own key, the role will automatically generate a new one for you based on the variables under system_info_encryption_local and at
# the end of the process the role will create {{ localhost_key_dir }} (if it's not already created) and copy the key to it, so you can save it
# somewhere else as a backup.
system_info_encryption_local:
enabled: false # mandatory
localhost_key_dir: "{{ inventory_dir }}/encryption_keys" # mandatory
key_dir: /etc/scylla/encryption_keys # mandatory
key_name: system_key # mandatory
cipher_algorithm: AES # mandatory
secret_key_strength: 128 # mandatory
secret_key_block_mode: CBC # mandatory if you're not providing your own key
secret_key_padding: PKCS5 # mandatory if you're not providing your own key

# KMIPKeyProvider:
# All the variables under system_info_encryption_kmip are mandatory
# Make sure you set kmip_hosts accordingly
system_info_encryption_kmip:
enabled: false
cipher_algorithm: AES
secret_key_strength: 128
kmip_host: yourkmipServerIP.com

# KMIP Hosts Template - Mandatory if you're using KMIPKeyProvider
# kmip_hosts:
# <name>:
# hosts: <address1[:port]> [, <address2[:port]>...]
# certificate: <identifying certificate> (optional)
# keyfile: <identifying key> (optional; it is required if "certificate" is set)
# truststore: <truststore for SSL connection> (optional)
# certficate_revocation_list: <CRL file> (optional)
# priority_string: <kmip tls priority string>
# username: <login> (optional)
# password: <password> (optional)
# max_command_retries: <int> (optional; default 3)
# <name>:

# If Scylla Manager will be used, set the following variables
scylla_manager_enabled: true
# deprecated in favour of below, it will be dropped soon, below should be used
Expand Down
4 changes: 4 additions & 0 deletions ansible-scylla-node/tasks/common.yml
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,10 @@
- (scylla_ssl.internode.enabled|bool) or
(scylla_ssl.client.enabled|bool)

- name: Set up LocalKeyProvider for system encryption
include_tasks: enable_ear.yml
when: system_info_encryption_local.enabled|bool

# scylla_listen_address is a composite indirect value that depends on another per-host value - scylla_nic.
# Therefore in order to be able to get the corresponding value via hostvars[item] later in the play we need to
# have an actual value resolved.
Expand Down
68 changes: 68 additions & 0 deletions ansible-scylla-node/tasks/enable_ear.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
---
- set_fact:
_remote_key_path: "{{ system_info_encryption_local.key_dir }}/{{ system_info_encryption_local.key_name }}"

- set_fact:
_localhost_key_path: "{{ system_info_encryption_local.localhost_key_dir }}/{{ system_info_encryption_local.key_name }}"

- name: Check if the keys already exist in the nodes
stat:
path: "{{ _remote_key_path }}"
become: true
register: remote_key_file

- name: Check if the user provided a key
stat:
path: "{{ _localhost_key_path }}"
delegate_to: localhost
register: localhost_key_file

- fail:
msg: "This node already has a key in '{{ _remote_key_path }}'"
when: remote_key_file.stat.exists|bool and localhost_key_file.stat.exists|bool == false

- fail:
msg: "This node already has a key in '{{ _remote_key_path }}' and it's different from the one provided by the user in '{{ _localhost_key_path }}'"
when:
- remote_key_file.stat.exists|bool and localhost_key_file.stat.exists|bool
- remote_key_file.stat.checksum != localhost_key_file.stat.checksum

- name: Create keys dir
file:
path: "{{ system_info_encryption_local.key_dir }}"
state: directory
owner: scylla
group: scylla
mode: '700'
become: true

- name: Generate key and copy it to localhost
block:
- name: Generate key
shell: "/bin/local_file_key_generator -a {{ system_info_encryption_local.cipher_algorithm }} -m {{ system_info_encryption_local.secret_key_block_mode }} -p {{ system_info_encryption_local.secret_key_padding }} -l {{ system_info_encryption_local.secret_key_strength }} {{ _remote_key_path }}"
become: true

- name: Create localhost keys dir
file:
path: "{{ system_info_encryption_local.localhost_key_dir }}"
state: directory
mode: '700'
delegate_to: localhost

- name: Copy key from remote to localhost
fetch:
src: "{{ _remote_key_path }}"
dest: "{{ _localhost_key_path }}"
flat: true
become: true
run_once: true
when: localhost_key_file.stat.exists|bool == false

- name: Copy key from localhost to all nodes
copy:
src: "{{ _localhost_key_path }}"
dest: "{{ _remote_key_path }}"
owner: scylla
group: scylla
mode: '600'
become: true
21 changes: 20 additions & 1 deletion ansible-scylla-node/templates/scylla.yaml.j2
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,30 @@ client_encryption_options:
keyfile: {{ scylla_ssl.cert_path }}/{{ inventory_hostname }}.pem
truststore: {{ scylla_ssl.cert_path }}/{{ scylla_cluster_name }}-ca.crt
{% endif %}

{% if scylla_ssl is defined and scylla_ssl.internode.enabled %}
server_encryption_options:
internode_encryption: {{ scylla_ssl.internode.internode_encryption }}
certificate: {{ scylla_ssl.cert_path }}/{{ inventory_hostname }}.crt
keyfile: {{ scylla_ssl.cert_path }}/{{ inventory_hostname }}.pem
truststore: {{ scylla_ssl.cert_path }}/{{ scylla_cluster_name }}-ca.crt
{% endif %}
{% if system_info_encryption_local.enabled|bool %}
system_info_encryption:
enabled: True
cipher_algorithm: {{ system_info_encryption_local.cipher_algorithm }}
secret_key_strength: {{ system_info_encryption_local.secret_key_strength }}
key_provider: LocalFileSystemKeyProviderFactory
secret_key_file: {{ system_info_encryption_local.key_dir }}/{{ system_info_encryption_local.key_name }}
{% elif system_info_encryption_kmip.enabled|bool %}
system_info_encryption:
enabled: True
cipher_algorithm: {{ system_info_encryption_kmip.cipher_algorithm }}
secret_key_strength: {{ system_info_encryption_kmip.secret_key_strength }}
key_provider: KmipKeyProviderFactory
kmip_host: {{ system_info_encryption_kmip.kmip_host }}

{% if kmip_hosts is defined %}
kmip_hosts:
{{ kmip_hosts | to_nice_yaml(indent=8) }}
{% endif %}
{% endif %}

0 comments on commit c279144

Please sign in to comment.