From e91c8be4492aee2327911ddea5b7decede388af9 Mon Sep 17 00:00:00 2001 From: Sebastian Gumprich Date: Wed, 31 Mar 2021 12:32:37 +0200 Subject: [PATCH] add support for encryption Closes-Bug: #1921861 Change-Id: I73e548ac208a96ddaa687a1b5fbb22cac20037d0 --- defaults/main.yml | 5 + handlers/main.yml | 7 ++ ...d-encryption-support-79e8218926995864.yaml | 15 +++ tasks/galera_server_encryption.yml | 94 +++++++++++++++++++ tasks/galera_server_install.yml | 6 ++ templates/encryption.cnf.j2 | 24 +++++ 6 files changed, 151 insertions(+) create mode 100644 releasenotes/notes/add-encryption-support-79e8218926995864.yaml create mode 100644 tasks/galera_server_encryption.yml create mode 100644 templates/encryption.cnf.j2 diff --git a/defaults/main.yml b/defaults/main.yml index e5bac9b1..8c33b745 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -144,6 +144,7 @@ galera_unindexed_query_logging: 0 galera_my_cnf_overrides: {} galera_cluster_cnf_overrides: {} galera_debian_cnf_overrides: {} +galera_encryption_overrides: {} # Set the max connections value for galera. Set this value to override the # computed value which is (100 x vCPUs) with a cap of 1600. If computed, the @@ -228,3 +229,7 @@ galera_mariadb_backups_user: galera_mariadb_backup galera_mariadb_backups_suffix: "{{ inventory_hostname }}" galera_mariadb_backups_cnf_file: "/etc/mysql/mariabackup.cnf" galera_mariadb_backups_nodes: ["{{ galera_cluster_members[0] }}"] + +galera_mariadb_encryption_enabled: false +galera_mariadb_encryption_plugin: "file_key_management" +galera_db_encryption_tmp_dir: "" diff --git a/handlers/main.yml b/handlers/main.yml index 0ee2005b..c6884dac 100644 --- a/handlers/main.yml +++ b/handlers/main.yml @@ -88,6 +88,8 @@ with_items: - "{{ ansible_play_hosts }}" run_once: true + notify: + - Delete encryption keyfile after starting Galera - meta: noop listen: Manage LB @@ -98,3 +100,8 @@ name: xinetd state: "{{ (galera_monitoring_check_enabled | bool) | ternary('restarted', 'stopped') }}" enabled: "{{ galera_monitoring_check_enabled | bool }}" + +- name: Delete encryption keyfile after starting Galera + file: + path: "/tmp/.keyfile.key" + state: absent diff --git a/releasenotes/notes/add-encryption-support-79e8218926995864.yaml b/releasenotes/notes/add-encryption-support-79e8218926995864.yaml new file mode 100644 index 00000000..c49a8be4 --- /dev/null +++ b/releasenotes/notes/add-encryption-support-79e8218926995864.yaml @@ -0,0 +1,15 @@ +--- +features: + - | + Add support for encryption of databases. This is disabled by default and + can be enabled by setting ``galera_mariadb_encryption_enabled`` to ``true``. + For now only the ``file_key_management`` encryption plugin is supported. + You can override enryption options with ``galera_encryption_overrides``. + The role creates ``galera_db_encryption_keys`` for you, if they're not specified. + To specify your on encryption keys, provide them like this. + + .. code-block:: yaml + + galera_db_encryption_keys: | + 1;5bbc03648be8db3d2087815717eabdec9fbc310f2b7fd53705b36fbdc80333e3 + 2;5bbc03648be8db3d2087815717eabdec9fbc310f2b7fd53705b36ebdc80333e3 diff --git a/tasks/galera_server_encryption.yml b/tasks/galera_server_encryption.yml new file mode 100644 index 00000000..20973b7d --- /dev/null +++ b/tasks/galera_server_encryption.yml @@ -0,0 +1,94 @@ +--- +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +- name: Create encryption config + config_template: + src: "{{ item.src }}" + dest: "{{ item.dest }}" + owner: "root" + group: "root" + mode: "{{ item.mode | default('0644') }}" + config_overrides: "{{ item.config_overrides }}" + config_type: "{{ item.config_type }}" + ignore_none_type: False + when: item.condition | default(True) + with_items: + - src: encryption.cnf.j2 + dest: "{{ galera_etc_include_dir }}/encryption.cnf" + config_overrides: "{{ galera_encryption_overrides }}" + config_type: "ini" + notify: Restart all mysql + +- name: use encryption with the file key management plugin + block: + - name: Create encryption directory + file: + path: "/etc/mysql/encryption" + state: "directory" + owner: "mysql" + group: "mysql" + mode: "0755" + + - name: Create a fact for the name of the temporary directory + set_fact: + galera_db_encryption_tmp_dir: "{{ lookup('env', 'OSA_CONFIG_DIR') | default(osa_config_dir, True) }}/mysql" + delegate_to: "localhost" + run_once: true + when: galera_db_encryption_tmp_dir | length == 0 + + - name: Create a temporary directory to store the keyfile + file: + path: "{{ galera_db_encryption_tmp_dir }}" + state: directory + delegate_to: "localhost" + run_once: true + + - name: Create encryption keys if the user does not specify them and put them on the deploy host + shell: "for i in {1..2}; do echo \"$i;$(openssl rand -hex 32)\"; done | tee {{ galera_db_encryption_tmp_dir }}/mysql_encryption_keys > /dev/null" + delegate_to: "localhost" + run_once: true + when: + - galera_db_encryption_keys is not defined + + - name: Create the encryption key file from the user provided galera_db_encryption_keys + shell: "echo '{{ galera_db_encryption_keys }}' > {{ galera_db_encryption_tmp_dir }}/mysql_encryption_keys" + delegate_to: "localhost" + run_once: true + when: + - galera_db_encryption_keys is defined + + - name: Create an encrypted keyfile using encryption key + command: "openssl enc -aes-256-cbc -md sha1 -k {{ galera_db_encryption_password }} -in {{ galera_db_encryption_tmp_dir }}/mysql_encryption_keys -out {{ galera_db_encryption_tmp_dir }}/mysql_encryption_keyfile.enc" + delegate_to: "localhost" + run_once: true + + - name: Copy encypted keyfile to servers + copy: + src: "{{ galera_db_encryption_tmp_dir }}/mysql_encryption_keyfile.enc" + dest: "/etc/mysql/encryption/keyfile.enc" + owner: mysql + group: mysql + mode: 0600 + force: false # only copy the file if it does not exist + notify: Restart all mysql + + - name: Copy password to file to servers + copy: + content: "{{ galera_db_encryption_password }}" + dest: "/etc/mysql/encryption/.keyfile.key" + owner: mysql + group: mysql + mode: 0600 + when: + - galera_mariadb_encryption_plugin == "file_key_management" + diff --git a/tasks/galera_server_install.yml b/tasks/galera_server_install.yml index 5226fa78..8abd199b 100644 --- a/tasks/galera_server_install.yml +++ b/tasks/galera_server_install.yml @@ -19,6 +19,12 @@ - include_tasks: "galera_install_{{ ansible_facts['pkg_mgr'] }}.yml" +- include_tasks: galera_server_encryption.yml + when: + - galera_mariadb_encryption_enabled | bool + tags: + - galera_server-encryption + - name: Record galera has been deployed ini_file: dest: "/etc/ansible/facts.d/openstack_ansible.fact" diff --git a/templates/encryption.cnf.j2 b/templates/encryption.cnf.j2 new file mode 100644 index 00000000..1cd14a43 --- /dev/null +++ b/templates/encryption.cnf.j2 @@ -0,0 +1,24 @@ +[mysqld] + +{% if galera_mariadb_encryption_plugin == "file_key_management" %} +# File Key Management +loose_plugin_load_add = file_key_management +file_key_management_filename = /etc/mysql/encryption/keyfile.enc +file_key_management_filekey = FILE:/etc/mysql/encryption/.keyfile.key +loose_file_key_management_filekey = FILE:/etc/mysql/encryption/.keyfile.key +file_key_management_encryption_algorithm = AES_CTR +{% endif %} + +{% if galera_mariadb_encryption_plugin == "aws_key_management" %} +# not implemented yet +# aws_key_management_master_key_id=alias/ +{% endif %} + +# InnoDB/XtraDB Encryption +innodb_encrypt_tables = FORCE +innodb_encrypt_temporary_tables = ON +innodb_encrypt_log = ON +innodb_encryption_threads = 4 +innodb_encryption_rotate_key_age = 1 + +encrypt_binlog=ON