From 11af98275e64f65ba49a1782deee163c639948c8 Mon Sep 17 00:00:00 2001 From: Jim Enright Date: Thu, 22 Aug 2024 14:33:45 +0100 Subject: [PATCH 1/7] Add roles and example playbook for PVC cert renewal Signed-off-by: Jim Enright --- playbooks/pvc_renew_certs.yml | 131 +++++++++ roles/tls_fetch_ca_certs/README.md | 17 ++ roles/tls_fetch_ca_certs/defaults/main.yml | 22 ++ roles/tls_fetch_ca_certs/tasks/main.yml | 26 ++ roles/tls_generate_csr/README.md | 17 ++ roles/tls_generate_csr/defaults/main.yml | 278 ++++++++++++++++++ roles/tls_generate_csr/tasks/main.yml | 59 ++++ .../templates/certificate_dn.j2 | 20 ++ roles/tls_generate_csr/templates/csr.cnf.j2 | 23 ++ roles/tls_install_certs/README.md | 17 ++ roles/tls_install_certs/defaults/main.yml | 43 +++ roles/tls_install_certs/tasks/main.yml | 83 ++++++ roles/tls_signing/README.md | 17 ++ roles/tls_signing/defaults/main.yml | 26 ++ roles/tls_signing/tasks/main.yml | 93 ++++++ 15 files changed, 872 insertions(+) create mode 100644 playbooks/pvc_renew_certs.yml create mode 100644 roles/tls_fetch_ca_certs/README.md create mode 100644 roles/tls_fetch_ca_certs/defaults/main.yml create mode 100644 roles/tls_fetch_ca_certs/tasks/main.yml create mode 100644 roles/tls_generate_csr/README.md create mode 100644 roles/tls_generate_csr/defaults/main.yml create mode 100644 roles/tls_generate_csr/tasks/main.yml create mode 100644 roles/tls_generate_csr/templates/certificate_dn.j2 create mode 100644 roles/tls_generate_csr/templates/csr.cnf.j2 create mode 100644 roles/tls_install_certs/README.md create mode 100644 roles/tls_install_certs/defaults/main.yml create mode 100644 roles/tls_install_certs/tasks/main.yml create mode 100644 roles/tls_signing/README.md create mode 100644 roles/tls_signing/defaults/main.yml create mode 100644 roles/tls_signing/tasks/main.yml diff --git a/playbooks/pvc_renew_certs.yml b/playbooks/pvc_renew_certs.yml new file mode 100644 index 00000000..c9b3d2ac --- /dev/null +++ b/playbooks/pvc_renew_certs.yml @@ -0,0 +1,131 @@ +--- + +# Copyright 2024 Cloudera, Inc. All Rights Reserved. +# +# 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: Pre - Initialization of local working directories + hosts: localhost + connection: local + tasks: + - name: Create temporary build directory + ansible.builtin.tempfile: + state: directory + prefix: pvc_tls_ + register: __pvc_tls_tempdir + + - debug: + var: __pvc_tls_tempdir + + - name: Create a directory for csrs and signed certs + ansible.builtin.file: + path: "{{ [__pvc_tls_tempdir.path, item] | path_join }}" + state: directory + mode: '0755' + loop: + - csrs + - certs + - ca_certs + +- name: Play 1 - Generate CSR on each host + hosts: "{{ target | default('cluster') }}" + become: yes + gather_facts: yes + tasks: + + - name: Call tls_generate_csr role + ansible.builtin.import_role: + name: cloudera.exe.tls_generate_csr + vars: + local_csrs_dir: "{{ (hostvars['localhost']['__pvc_tls_tempdir']['path'], 'csrs') | path_join }}" + +- name: Get the list of CSRs to sign + hosts: localhost + connection: local + tasks: + - name: "Set fact for all CSRs in {{ local_csrs_dir }}" + ansible.builtin.find: + paths: "{{ local_csrs_dir }}" + file_type: file + register: __csrs_to_sign + vars: + local_csrs_dir: "{{ (hostvars['localhost']['__pvc_tls_tempdir']['path'], 'csrs') | path_join }}" + + - name: Set fact for csrs to sign + ansible.builtin.set_fact: + local_csrs_to_sign: "{{ __csrs_to_sign.files | json_query('[*].path') | flatten }}" + +- name: Play 2 - Sign the CSR + hosts: ca_server + become: yes + gather_facts: yes + tasks: + + - name: Call tls_signing role + ansible.builtin.import_role: + name: cloudera.exe.tls_signing + vars: + csrs_to_sign: "{{ hostvars['localhost']['local_csrs_to_sign'] }}" + copy_from_controller: true + local_certs_dir: "{{ (hostvars['localhost']['__pvc_tls_tempdir']['path'], 'certs') | path_join }}" + +- name: Play 3 - Install the sign certs on each host + hosts: "{{ target | default('cluster') }}" + become: yes + gather_facts: yes + tasks: + + - name: Call tls_install_certs role + ansible.builtin.import_role: + name: cloudera.exetls_install_certs + vars: + local_tls_signed_certs_dir: "{{ (hostvars['localhost']['__pvc_tls_tempdir']['path'], 'certs') | path_join }}" + +- name: Post 1 - Restart CM Server service + hosts: cloudera_manager + become: yes + gather_facts: yes + tasks: + + - name: Restart CM Server service + when: + - restart_services | default(False) + ansible.builtin.service: + name: cloudera-scm-server + state: restarted + +- name: Post 2 - Restart DB Server service + hosts: db_server + become: yes + gather_facts: yes + tasks: + + - name: Restart DB Server service + when: + - restart_services | default(False) + ansible.builtin.service: + name: "{{ db_service_name }}" + state: reloaded + +- name: Post 3 - Restart CM Agent service + hosts: cluster + become: yes + gather_facts: yes + tasks: + + - name: Restart CM Agent service + when: + - restart_services | default(False) + ansible.builtin.service: + name: cloudera-scm-agent + state: restarted \ No newline at end of file diff --git a/roles/tls_fetch_ca_certs/README.md b/roles/tls_fetch_ca_certs/README.md new file mode 100644 index 00000000..103e7c06 --- /dev/null +++ b/roles/tls_fetch_ca_certs/README.md @@ -0,0 +1,17 @@ + + +# cloudera.exe.tls_fetch_ca_certs diff --git a/roles/tls_fetch_ca_certs/defaults/main.yml b/roles/tls_fetch_ca_certs/defaults/main.yml new file mode 100644 index 00000000..057969c2 --- /dev/null +++ b/roles/tls_fetch_ca_certs/defaults/main.yml @@ -0,0 +1,22 @@ +# Copyright 2024 Cloudera, Inc. +# +# 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. + +--- + +ca_server_intermediate_path: /ca/intermediate/certs +ca_server_intermediate_cert_name: intermediate.cert.pem +ca_server_root_path: /ca/certs +ca_server_root_cert_name: ca.cert.pem + +# local_ca_certs_dir \ No newline at end of file diff --git a/roles/tls_fetch_ca_certs/tasks/main.yml b/roles/tls_fetch_ca_certs/tasks/main.yml new file mode 100644 index 00000000..e3c14a29 --- /dev/null +++ b/roles/tls_fetch_ca_certs/tasks/main.yml @@ -0,0 +1,26 @@ +# Copyright 2024 Cloudera, Inc. +# +# 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: Bring ca root and intermediate cert back to controller + ansible.builtin.fetch: + src: "{{ item.cert_path }}/{{ item.cert_filename }}" + dest: "{{ local_ca_certs_dir }}/{{ item.cert_filename }}" + flat: yes + loop: + - cert_path: "{{ ca_server_intermediate_path }}" + cert_filename: "{{ ca_server_intermediate_cert_name }}" + - cert_path: "{{ ca_server_root_path }}" + cert_filename: "{{ ca_server_root_cert_name }}" diff --git a/roles/tls_generate_csr/README.md b/roles/tls_generate_csr/README.md new file mode 100644 index 00000000..634be215 --- /dev/null +++ b/roles/tls_generate_csr/README.md @@ -0,0 +1,17 @@ + + +# cloudera.exe.tls_generate_csr diff --git a/roles/tls_generate_csr/defaults/main.yml b/roles/tls_generate_csr/defaults/main.yml new file mode 100644 index 00000000..95ffea7c --- /dev/null +++ b/roles/tls_generate_csr/defaults/main.yml @@ -0,0 +1,278 @@ +# Copyright 2023 Cloudera, Inc. All Rights Reserved. +# +# 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. + +--- +keytool_path: /usr/bin/keytool +openssl_path: /usr/bin/openssl + +base_dir_security: /opt/cloudera/security +base_dir_security_pki: "{{ base_dir_security }}/pki" +tls_csr_config_path: "{{ base_dir_security_pki }}/csr.cnf" +tls_csr_path: "{{ base_dir_security_pki }}/{{ inventory_hostname }}.csr" + +# local_csrs_dir: "/tmp/csrs" +# subject_alternative_names # optional variable which can be defined for each host + +ca_server_attrs_general: + OU: PS + O: Cloudera, Inc. + ST: CA + C: US + + +tls_keystore_password: changeme +tls_key_password: changeme + +tls_keystore_path: "{{ base_dir_security_pki }}/{{ inventory_hostname }}.jks" +tls_keystore_path_generic: "{{ base_dir_security_pki }}/host.jks" + +tls_key_password_file: "{{ base_dir_security_pki }}/host.key.pw" + +tls_key_path: "{{ base_dir_security_pki }}/{{ inventory_hostname }}.key" +tls_key_path_generic: "{{ base_dir_security_pki }}/host.key" + +tls_key_path_plaintext: "{{ tls_key_path }}.unenc" +tls_key_path_plaintext_generic: "{{ tls_key_path_generic }}.unenc" + + +local_accounts: + + - user: accumulo + home: /var/lib/accumulo + comment: Accumulo + + - user: atlas + home: /var/lib/atlas + comment: Atlas + extra_groups: [hadoop] + + - user: cloudera-scm + home: /var/lib/cloudera-scm-server + comment: Cloudera Manager + mode: '770' + keystore_acl: True + key_acl: True + key_password_acl: True + + - user: cruisecontrol + home: /var/lib/cruise_control + comment: Cruise Control + keystore_acl: True + + - user: druid + home: /var/lib/druid + comment: Druid + extra_groups: [hadoop] + + - user: flink + home: /var/lib/flink + comment: Flink + keystore_acl: True + + - user: ssb + home: /var/lib/ssb + comment: SQL Stream Builder + keystore_acl: True + key_acl: True + key_password_acl: True + + - user: flume + home: /var/lib/flume-ng + comment: Flume + keystore_acl: True + + - user: hbase + home: /var/lib/hbase + comment: HBase + keystore_acl: True + + - user: hdfs + home: /var/lib/hadoop-hdfs + comment: Hadoop HDFS + extra_groups: [hadoop] + + - user: hive + home: /var/lib/hive + comment: Hive + keystore_acl: True + + - user: httpfs + home: /var/lib/hadoop-httpfs + comment: Hadoop HTTPFS + keystore_acl: True + + - user: hue + home: /usr/lib/hue + comment: Hue + key_acl: True + key_password_acl: True + + - user: impala + home: /var/lib/impala + comment: Impala + extra_groups: [hive] + key_acl: True + key_password_acl: True + + - user: kafka + home: /var/lib/kafka + comment: Kafka + keystore_acl: True + + - user: keytrustee + home: /var/lib/keytrustee + comment: KeyTrustee KMS + keystore_acl: True + key_acl: True + key_password_acl: True + + - user: kms + home: /var/lib/hadoop-kms + comment: Hadoop KMS + keystore_acl: True + + - user: knox + home: /var/lib/knox + comment: Knox + extra_groups: [hadoop] + keystore_acl: True + + - user: kudu + home: /var/lib/kudu + comment: Kudu + key_acl: True + key_password_acl: True + + - user: livy + home: /var/lib/livy + comment: Livy + keystore_acl: True + + - user: mapred + home: /var/lib/hadoop-mapreduce + comment: Hadoop MapReduce + extra_groups: [hadoop] + + - user: nifi + home: /var/lib/nifi + command: NiFi + keystore_acl: True + + - user: nifiregistry + home: /var/lib/nifiregistry + command: NiFi Registry + keystore_acl: True + + - user: nifi + home: /var/lib/nifi + command: NiFi + + - user: nifiregistry + home: /var/lib/nifiregistry + command: NiFi Registry + + - user: oozie + home: /var/lib/oozie + comment: Oozie User + keystore_acl: True + + - user: phoenix + home: /var/lib/phoenix + comment: Phoenix User + + - user: ranger + home: /var/lib/ranger + comment: Ranger + extra_groups: [hadoop] + + - user: rangerraz + home: /var/lib/rangerraz + comment: Ranger Raz User + extra_groups: [ranger, hadoop] + + - user: rangertagsync + home: /var/lib/rangertagsync + comment: Ranger Tagsync User + extra_groups: [ranger, hadoop] + + - user: schemaregistry + home: /var/lib/schemaregistry + comment: Schema Registry + keystore_acl: True + + - user: sentry + home: /var/lib/sentry + comment: Sentry + + - user: solr + home: /var/lib/solr + comment: Solr + keystore_acl: True + + - user: spark + home: /var/lib/spark + comment: Spark + keystore_acl: True + + - user: spark2 + home: /var/lib/spark2 + comment: Spark2 + + - user: sqoop + home: /var/lib/sqoop + comment: Sqoop + + - user: sqoop2 + home: /var/lib/sqoop2 + comment: Sqoop2 + extra_groups: [sqoop] + + - user: streamsmsgmgr + home: /var/lib/streams_messaging_manager + comment: Streams Messaging Manager + keystore_acl: True + key_acl: True + + - user: streamsrepmgr + home: /var/lib/streams_replication_manager + comment: Streams Replication Manager + keystore_acl: True + + - user: superset + home: /var/lib/superset + comment: Superset + + - user: yarn + home: /var/lib/hadoop-yarn + comment: Hadoop Yarn + extra_groups: [hadoop, spark] + + - user: zeppelin + home: /var/lib/zeppelin + comment: Zeppelin + keystore_acl: True + + - user: zookeeper + home: /var/lib/zookeeper + comment: ZooKeeper + keystore_acl: True + +ecs_accounts: + - user: cloudera-scm + home: /var/lib/cloudera-scm-server + comment: Cloudera Manager + mode: '770' + keystore_acl: True + key_acl: True + key_password_acl: True \ No newline at end of file diff --git a/roles/tls_generate_csr/tasks/main.yml b/roles/tls_generate_csr/tasks/main.yml new file mode 100644 index 00000000..254c0cdc --- /dev/null +++ b/roles/tls_generate_csr/tasks/main.yml @@ -0,0 +1,59 @@ +# Copyright 2024 Cloudera, Inc. +# +# 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: Prepare directories for TLS + ansible.builtin.file: + state: directory + path: "{{ dir }}" + mode: 0755 + owner: root + loop: + - "{{ base_dir_security }}" + - "{{ base_dir_security_pki }}" + loop_control: + loop_var: dir + +- ansible.builtin.set_fact: + subject_attr: "{{ lookup('template', 'certificate_dn.j2') | from_yaml }}" + +- ansible.builtin.set_fact: + openssl_subject: "/{{ subject_attr | map('regex_replace', '/', '\\/') | join('/') }}" + keytool_subject: "{{ subject_attr | map('regex_replace', ',', '\\,') | join(',') }}" + +- name: Create openssl.cnf for CSR generation + ansible.builtin.template: + src: csr.cnf.j2 + dest: "{{ tls_csr_config_path }}" + owner: root + mode: 0644 + +- name: Generate CSR + ansible.builtin.shell: + cmd: > + {{ openssl_path }} req + -key {{ tls_key_path }} + -passin pass:{{ tls_key_password }} + -subj "{{ openssl_subject }}" + -config {{ tls_csr_config_path }} + -new + -out {{ tls_csr_path }} + creates: "{{ tls_csr_path }}" + +- name: Bring CSRs back to controller + ansible.builtin.fetch: + src: "{{ tls_csr_path }}" + dest: "{{ local_csrs_dir }}/" + flat: yes diff --git a/roles/tls_generate_csr/templates/certificate_dn.j2 b/roles/tls_generate_csr/templates/certificate_dn.j2 new file mode 100644 index 00000000..c7d1f595 --- /dev/null +++ b/roles/tls_generate_csr/templates/certificate_dn.j2 @@ -0,0 +1,20 @@ +{% set attr = ca_server_attrs_general | default({}) | combine(ca_server_attrs_host | default({})) %} +- CN={{ cn_override | default(attr.CN | default(inventory_hostname)) }} +{% if attr.OU is defined %} +{% if attr.OU is iterable and attr.OU is not string %} +{% for ou in attr.OU %} +- OU={{ ou }} +{% endfor %} +{% else %} +- OU={{ attr.OU }} +{% endif %} +{% endif %} +{% if attr.O is defined %} +- O={{ attr.O }} +{% endif %} +{% if attr.ST is defined %} +- ST={{ attr.ST }} +{% endif %} +{% if attr.C is defined %} +- C={{ attr.C }} +{% endif %} diff --git a/roles/tls_generate_csr/templates/csr.cnf.j2 b/roles/tls_generate_csr/templates/csr.cnf.j2 new file mode 100644 index 00000000..d5c600f1 --- /dev/null +++ b/roles/tls_generate_csr/templates/csr.cnf.j2 @@ -0,0 +1,23 @@ +[ CA_default ] +# Directory and file locations. +default_md = sha256 + +[ req ] +# Options for the `req` tool (`man req`). +default_bits = 2048 +req_extensions = cloudera_req +distinguished_name = req_distinguished_name + +[req_distinguished_name] + +[ cloudera_req ] +basicConstraints = CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment +extendedKeyUsage = serverAuth, clientAuth +subjectAltName = @alt_names + +[alt_names] +DNS.1 = {{ inventory_hostname }} +{% for san in subject_alternative_names | default([]) %} +DNS.{{ loop.index + 1 }} = {{ san }} +{% endfor %} diff --git a/roles/tls_install_certs/README.md b/roles/tls_install_certs/README.md new file mode 100644 index 00000000..a0b032bb --- /dev/null +++ b/roles/tls_install_certs/README.md @@ -0,0 +1,17 @@ + + +# clouera.exe.tls_install_certs diff --git a/roles/tls_install_certs/defaults/main.yml b/roles/tls_install_certs/defaults/main.yml new file mode 100644 index 00000000..804ab9e9 --- /dev/null +++ b/roles/tls_install_certs/defaults/main.yml @@ -0,0 +1,43 @@ +# Copyright 2024 Cloudera, Inc. All Rights Reserved. +# +# 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. + +--- + +keytool_path: /usr/bin/keytool +openssl_path: /usr/bin/openssl +update_ca_trust_path: /usr/bin/update-ca-trust + +base_dir_security: /opt/cloudera/security +base_dir_security_pki: "{{ base_dir_security }}/pki" + +tls_cert_path: "{{ base_dir_security_pki }}/{{ inventory_hostname }}.pem" +tls_cert_path_generic: "{{ base_dir_security_pki }}/host.pem" + +tls_key_path_generic: "{{ base_dir_security_pki }}/host.key" +tls_key_path_plaintext_generic: "{{ tls_key_path_generic }}.unenc" + + +tls_ca_chain_path: "{{ base_dir_security_pki }}/chain.pem" + +tls_keystore_path: "{{ base_dir_security_pki }}/{{ inventory_hostname }}.jks" +tls_keystore_password: changeme + +tls_truststore_path: "{{ base_dir_security_pki }}/truststore.jks" +tls_uber_truststore_path: "{{ base_dir_security_pki }}/full_truststore.jks" +tls_truststore_password: changeme + +jdk_java_cacerts_password: changeit + +__temp_keychain: "{{ base_dir_security_pki }}/tmp_keychain.pem" +__temp_keystore: "{{ base_dir_security_pki }}/tmp_keystore.p12" \ No newline at end of file diff --git a/roles/tls_install_certs/tasks/main.yml b/roles/tls_install_certs/tasks/main.yml new file mode 100644 index 00000000..dcbcdb83 --- /dev/null +++ b/roles/tls_install_certs/tasks/main.yml @@ -0,0 +1,83 @@ +# Copyright 2024 Cloudera, Inc. All Rights Reserved. +# +# 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: Check if signed cert is available + become: no + delegate_to: localhost + stat: + path: "{{ local_tls_signed_certs_dir }}/{{ inventory_hostname }}.pem" + register: signed_cert + +- ansible.builtin.fail: + msg: > + "Signed cert for {{ inventory_hostname }} could not be found. If manual signing is + required, do this now and re-run the playbook with 'tls_signed_certs_dir' variable set. + when: + - not signed_cert.stat.exists + +- name: Copy signed certs to hosts + ansible.builtin.copy: + src: "{{ local_tls_signed_certs_dir }}/{{ inventory_hostname }}.pem" + dest: "{{ tls_cert_path }}" + mode: 0644 + +- name: Create host agnostic link for signed certificate + ansible.builtin.file: + src: "{{ tls_cert_path }}" + dest: "{{ tls_cert_path_generic }}" + state: hard + force: true + mode: 0644 + owner: root + group: root + +- name: Validate certificate + ansible.builtin.shell: + cmd: openssl verify -verbose -CAfile {{ tls_ca_chain_path }} {{ tls_cert_path }} + +# Update the keystore with the renewed cert +# Reference: https://support.smartbear.com/collaborator/faq/how-to-update-an-expired-certificate-in-the-existi/ +# ....Step 1: Create chain including signed host cert +# ....Step 2: Create PKCS12 keystore with chain and key. Alias name is {{ inventory_hostname }} +# NOTE: Step 1 & 2 are handled by the task below +- name: Generate a temporary PKCS12 keystore with renewed cert + community.crypto.openssl_pkcs12: + action: export + path: "{{ __temp_keystore }}" + passphrase: "{{ tls_keystore_password }}" + friendly_name: "{{ keystore_alias | default(inventory_hostname) }}" + privatekey_path: "{{ tls_key_path_plaintext_generic }}" + certificate_path: "{{ tls_cert_path_generic }}" + other_certificates: + - "{{ base_dir_security_pki }}/cluster_intca.pem" + - "{{ base_dir_security_pki }}/cluster_rootca.pem" + +# ....Step 3: Update the {{ tls_keystore_path }} with the above keystore +- name: Import the temporary keystore to {{ tls_keystore_path }} + community.general.java_cert: + pkcs12_path: "{{ __temp_keystore }}" + pkcs12_alias: "{{ keystore_alias | default(inventory_hostname) }}" + pkcs12_password: "{{ tls_keystore_password }}" + cert_alias: "{{ keystore_alias | default(inventory_hostname) }}" + keystore_path: "{{ tls_keystore_path }}" + keystore_pass: "{{ tls_keystore_password }}" + keystore_create: false + state: present + +- name: Remove the temporary keystore + ansible.builtin.file: + path: "{{ __temp_keystore }}" + state: absent diff --git a/roles/tls_signing/README.md b/roles/tls_signing/README.md new file mode 100644 index 00000000..d0ee8105 --- /dev/null +++ b/roles/tls_signing/README.md @@ -0,0 +1,17 @@ + + +# cloudera.exe.tls_signing diff --git a/roles/tls_signing/defaults/main.yml b/roles/tls_signing/defaults/main.yml new file mode 100644 index 00000000..c2859c28 --- /dev/null +++ b/roles/tls_signing/defaults/main.yml @@ -0,0 +1,26 @@ +# Copyright 2024 Cloudera, Inc. All Rights Reserved. +# +# 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. + +--- +keytool_path: /usr/bin/keytool +openssl_path: /usr/bin/openssl + +ca_server_intermediate_path: /ca/intermediate +ca_server_intermediate_path_certs: "{{ ca_server_intermediate_path }}/certs" +ca_server_intermediate_path_crl: "{{ ca_server_intermediate_path }}/crl" +ca_server_intermediate_path_csr: "{{ ca_server_intermediate_path }}/csr" +ca_server_intermediate_key_password: password + +override_old_certs: True +cert_backup_directory: "{{ ca_server_intermediate_path }}/cert_backup_{{ ansible_date_time.iso8601 | default('')}}" \ No newline at end of file diff --git a/roles/tls_signing/tasks/main.yml b/roles/tls_signing/tasks/main.yml new file mode 100644 index 00000000..c66f29ab --- /dev/null +++ b/roles/tls_signing/tasks/main.yml @@ -0,0 +1,93 @@ +# Copyright 2024 Cloudera, Inc. All Rights Reserved. +# +# 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. + +--- + +# TODO: Check index.txt.attr and see if unique_subject = no for intermediate ca + +- name: Set fact for all CSRs to sign + ansible.builtin.set_fact: + __csrs_to_sign: "{{ (__csrs_to_sign | default([])) + ([csr_item]) }}" + vars: + csr_item: + local_file: "{{ item }}" + csr_filename: "{{ item | basename }}" + file_suffix: "{{ item | basename | splitext | first }}" + loop: "{{ csrs_to_sign }}" + +- name: Copy all CSRs from controller to CA server + when: copy_from_controller + ansible.builtin.copy: + src: "{{ item.local_file }}" + dest: "{{ ca_server_intermediate_path_csr }}/{{ item.csr_filename }}" + mode: 0644 + loop: "{{ __csrs_to_sign }}" + +- name: Backup and remove old certs if required + when: override_old_certs + block: + - name: Create backup directory for old certs + ansible.builtin.file: + path: "{{ cert_backup_directory }}" + state: directory + mode: '0755' + + - name: Backup old certs + block: + - name: Check if cert exists + ansible.builtin.stat: + path: "{{ ca_server_intermediate_path_certs }}/{{ item.file_suffix }}.pem" + loop: "{{ __csrs_to_sign }}" + register: __old_certs + + - name: Copy existing certs to backup directory + when: item.stat.exists + ansible.builtin.copy: + src: "{{ item.stat.path }}" + dest: "{{ cert_backup_directory }}" + remote_src: True + loop: "{{ __old_certs.results }}" + + - name: Remove old certs + when: item.stat.exists + ansible.builtin.file: + path: "{{ item.stat.path }}" + state: absent + loop: "{{ __old_certs.results }}" + +- name: Sign CSRs + ansible.builtin.shell: + executable: /bin/bash + cmd: > + exec 100>/tmp/ca_server.lock; + flock 100 && + {{ openssl_path }} ca + -batch + -config {{ ca_server_intermediate_path }}/openssl.cnf + -extensions cloudera_req + -days 730 + -notext + -md sha256 + -in {{ ca_server_intermediate_path_csr }}/{{ item.csr_filename }} + -out {{ ca_server_intermediate_path_certs }}/{{ item.file_suffix }}.pem + -passin pass:{{ ca_server_intermediate_key_password }} + creates: "{{ ca_server_intermediate_path_certs }}/{{ item.file_suffix }}.pem" + loop: "{{ __csrs_to_sign }}" + +- name: Bring signed certs back to controller + ansible.builtin.fetch: + src: "{{ ca_server_intermediate_path_certs }}/{{ item.file_suffix }}.pem" + dest: "{{ local_certs_dir }}/{{ item.file_suffix }}.pem" + flat: yes + loop: "{{ __csrs_to_sign }}" From 1a0205cbbe414dd43bd6d1f7fa314b08bbfee51d Mon Sep 17 00:00:00 2001 From: Jim Enright Date: Thu, 22 Aug 2024 14:33:46 +0100 Subject: [PATCH 2/7] Add documentation for TLS roles Signed-off-by: Jim Enright --- .../meta/argument_specs.yml | 44 ++++ roles/tls_generate_csr/defaults/main.yml | 244 ------------------ .../tls_generate_csr/meta/argument_specs.yml | 67 +++++ roles/tls_install_certs/defaults/main.yml | 9 - .../tls_install_certs/meta/argument_specs.yml | 65 +++++ roles/tls_install_certs/tasks/main.yml | 2 +- roles/tls_signing/defaults/main.yml | 5 +- roles/tls_signing/meta/argument_specs.yml | 63 +++++ 8 files changed, 244 insertions(+), 255 deletions(-) create mode 100644 roles/tls_fetch_ca_certs/meta/argument_specs.yml create mode 100644 roles/tls_generate_csr/meta/argument_specs.yml create mode 100644 roles/tls_install_certs/meta/argument_specs.yml create mode 100644 roles/tls_signing/meta/argument_specs.yml diff --git a/roles/tls_fetch_ca_certs/meta/argument_specs.yml b/roles/tls_fetch_ca_certs/meta/argument_specs.yml new file mode 100644 index 00000000..6dea9f03 --- /dev/null +++ b/roles/tls_fetch_ca_certs/meta/argument_specs.yml @@ -0,0 +1,44 @@ +# Copyright 2024 Cloudera, Inc. +# +# 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. + +--- + +argument_specs: + main: + short_description: "Bring CA root and intermediate cert back to controller" + description: + - Fetch the named root and intermediate CA TLS Certificates from the CA Server. + author: + - "Jim Enright " + options: + ca_server_intermediate_path: + description: "Path to intermediate CA cert on the CA server" + default: "/ca/intermediate/certs" + type: "str" + ca_server_intermediate_cert_name: + description: "Name of the intermediate CA cert file" + type: "str" + default: "intermediate.cert.pem" + ca_server_root_path: + description: "Path to root CA cert on the CA server" + default: "/ca/certs" + type: "str" + ca_server_root_cert_name: + description: "Name of the root CA cert file" + type: "str" + default: "ca.cert.pem" + local_ca_certs_dir: + description: "Directory on Ansible controller to store the root and intermediate CA cert files" + type: "str" + required: true \ No newline at end of file diff --git a/roles/tls_generate_csr/defaults/main.yml b/roles/tls_generate_csr/defaults/main.yml index 95ffea7c..ae506631 100644 --- a/roles/tls_generate_csr/defaults/main.yml +++ b/roles/tls_generate_csr/defaults/main.yml @@ -13,7 +13,6 @@ # limitations under the License. --- -keytool_path: /usr/bin/keytool openssl_path: /usr/bin/openssl base_dir_security: /opt/cloudera/security @@ -22,7 +21,6 @@ tls_csr_config_path: "{{ base_dir_security_pki }}/csr.cnf" tls_csr_path: "{{ base_dir_security_pki }}/{{ inventory_hostname }}.csr" # local_csrs_dir: "/tmp/csrs" -# subject_alternative_names # optional variable which can be defined for each host ca_server_attrs_general: OU: PS @@ -31,248 +29,6 @@ ca_server_attrs_general: C: US -tls_keystore_password: changeme tls_key_password: changeme -tls_keystore_path: "{{ base_dir_security_pki }}/{{ inventory_hostname }}.jks" -tls_keystore_path_generic: "{{ base_dir_security_pki }}/host.jks" - -tls_key_password_file: "{{ base_dir_security_pki }}/host.key.pw" - tls_key_path: "{{ base_dir_security_pki }}/{{ inventory_hostname }}.key" -tls_key_path_generic: "{{ base_dir_security_pki }}/host.key" - -tls_key_path_plaintext: "{{ tls_key_path }}.unenc" -tls_key_path_plaintext_generic: "{{ tls_key_path_generic }}.unenc" - - -local_accounts: - - - user: accumulo - home: /var/lib/accumulo - comment: Accumulo - - - user: atlas - home: /var/lib/atlas - comment: Atlas - extra_groups: [hadoop] - - - user: cloudera-scm - home: /var/lib/cloudera-scm-server - comment: Cloudera Manager - mode: '770' - keystore_acl: True - key_acl: True - key_password_acl: True - - - user: cruisecontrol - home: /var/lib/cruise_control - comment: Cruise Control - keystore_acl: True - - - user: druid - home: /var/lib/druid - comment: Druid - extra_groups: [hadoop] - - - user: flink - home: /var/lib/flink - comment: Flink - keystore_acl: True - - - user: ssb - home: /var/lib/ssb - comment: SQL Stream Builder - keystore_acl: True - key_acl: True - key_password_acl: True - - - user: flume - home: /var/lib/flume-ng - comment: Flume - keystore_acl: True - - - user: hbase - home: /var/lib/hbase - comment: HBase - keystore_acl: True - - - user: hdfs - home: /var/lib/hadoop-hdfs - comment: Hadoop HDFS - extra_groups: [hadoop] - - - user: hive - home: /var/lib/hive - comment: Hive - keystore_acl: True - - - user: httpfs - home: /var/lib/hadoop-httpfs - comment: Hadoop HTTPFS - keystore_acl: True - - - user: hue - home: /usr/lib/hue - comment: Hue - key_acl: True - key_password_acl: True - - - user: impala - home: /var/lib/impala - comment: Impala - extra_groups: [hive] - key_acl: True - key_password_acl: True - - - user: kafka - home: /var/lib/kafka - comment: Kafka - keystore_acl: True - - - user: keytrustee - home: /var/lib/keytrustee - comment: KeyTrustee KMS - keystore_acl: True - key_acl: True - key_password_acl: True - - - user: kms - home: /var/lib/hadoop-kms - comment: Hadoop KMS - keystore_acl: True - - - user: knox - home: /var/lib/knox - comment: Knox - extra_groups: [hadoop] - keystore_acl: True - - - user: kudu - home: /var/lib/kudu - comment: Kudu - key_acl: True - key_password_acl: True - - - user: livy - home: /var/lib/livy - comment: Livy - keystore_acl: True - - - user: mapred - home: /var/lib/hadoop-mapreduce - comment: Hadoop MapReduce - extra_groups: [hadoop] - - - user: nifi - home: /var/lib/nifi - command: NiFi - keystore_acl: True - - - user: nifiregistry - home: /var/lib/nifiregistry - command: NiFi Registry - keystore_acl: True - - - user: nifi - home: /var/lib/nifi - command: NiFi - - - user: nifiregistry - home: /var/lib/nifiregistry - command: NiFi Registry - - - user: oozie - home: /var/lib/oozie - comment: Oozie User - keystore_acl: True - - - user: phoenix - home: /var/lib/phoenix - comment: Phoenix User - - - user: ranger - home: /var/lib/ranger - comment: Ranger - extra_groups: [hadoop] - - - user: rangerraz - home: /var/lib/rangerraz - comment: Ranger Raz User - extra_groups: [ranger, hadoop] - - - user: rangertagsync - home: /var/lib/rangertagsync - comment: Ranger Tagsync User - extra_groups: [ranger, hadoop] - - - user: schemaregistry - home: /var/lib/schemaregistry - comment: Schema Registry - keystore_acl: True - - - user: sentry - home: /var/lib/sentry - comment: Sentry - - - user: solr - home: /var/lib/solr - comment: Solr - keystore_acl: True - - - user: spark - home: /var/lib/spark - comment: Spark - keystore_acl: True - - - user: spark2 - home: /var/lib/spark2 - comment: Spark2 - - - user: sqoop - home: /var/lib/sqoop - comment: Sqoop - - - user: sqoop2 - home: /var/lib/sqoop2 - comment: Sqoop2 - extra_groups: [sqoop] - - - user: streamsmsgmgr - home: /var/lib/streams_messaging_manager - comment: Streams Messaging Manager - keystore_acl: True - key_acl: True - - - user: streamsrepmgr - home: /var/lib/streams_replication_manager - comment: Streams Replication Manager - keystore_acl: True - - - user: superset - home: /var/lib/superset - comment: Superset - - - user: yarn - home: /var/lib/hadoop-yarn - comment: Hadoop Yarn - extra_groups: [hadoop, spark] - - - user: zeppelin - home: /var/lib/zeppelin - comment: Zeppelin - keystore_acl: True - - - user: zookeeper - home: /var/lib/zookeeper - comment: ZooKeeper - keystore_acl: True - -ecs_accounts: - - user: cloudera-scm - home: /var/lib/cloudera-scm-server - comment: Cloudera Manager - mode: '770' - keystore_acl: True - key_acl: True - key_password_acl: True \ No newline at end of file diff --git a/roles/tls_generate_csr/meta/argument_specs.yml b/roles/tls_generate_csr/meta/argument_specs.yml new file mode 100644 index 00000000..72270afe --- /dev/null +++ b/roles/tls_generate_csr/meta/argument_specs.yml @@ -0,0 +1,67 @@ +# Copyright 2024 Cloudera, Inc. +# +# 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. + +--- + +argument_specs: + main: + short_description: "Generates a CSR on each host and copies it back to the Ansible controller" + description: + - Generates a TLS Certificate Signing Request (CSR). + - Once created the CSR file is copied back to the Ansibles controller. + author: + - "Jim Enright " + options: + openssl_path: + description: "Absolute path to the C(openssl) executable" + default: "/usr/bin/openssl" + type: "str" + base_dir_security: + description: "Base directory for Cloudera CDP security related files" + type: "str" + default: "/opt/cloudera/security" + base_dir_security_pki: + description: "Base directory for Cloudera CDP PKI security related files" + type: "str" + default: "{{ base_dir_security }}/pki" + tls_csr_config_path: + description: + - Location of the OpenSSL configuration file that will be created by the role. + - This file will be generated by the C(csr.cnf.j2) template file. + type: "str" + default: "{{ base_dir_security_pki }}/csr.cnf" + tls_csr_path: + description: "Location of the OpenSSL Certificate Signing Request file that will be created by the role" + type: "str" + default: "{{ base_dir_security_pki }}/{{ inventory_hostname }}.csr" + ca_server_attrs_general: + description: "Attributes to use in the certificate signing request" + type: "dict" + default: + OU: PS + O: "Cloudera, Inc." + ST: "CA" + C: "US" + tls_key_password: + description: "Password for the TLS Key." + type: "str" + default: "changeme" + tls_key_path: + description: "Location of the TLS key." + type: "str" + default: "{{ base_dir_security_pki }}/{{ inventory_hostname }}.key" + local_csrs_dir: + description: "Location on the Ansible Controller where the CSR will be copied." + type: "str" + default: "{{ base_dir_security_pki }}/{{ inventory_hostname }}.key" \ No newline at end of file diff --git a/roles/tls_install_certs/defaults/main.yml b/roles/tls_install_certs/defaults/main.yml index 804ab9e9..b1ae4049 100644 --- a/roles/tls_install_certs/defaults/main.yml +++ b/roles/tls_install_certs/defaults/main.yml @@ -14,9 +14,7 @@ --- -keytool_path: /usr/bin/keytool openssl_path: /usr/bin/openssl -update_ca_trust_path: /usr/bin/update-ca-trust base_dir_security: /opt/cloudera/security base_dir_security_pki: "{{ base_dir_security }}/pki" @@ -33,11 +31,4 @@ tls_ca_chain_path: "{{ base_dir_security_pki }}/chain.pem" tls_keystore_path: "{{ base_dir_security_pki }}/{{ inventory_hostname }}.jks" tls_keystore_password: changeme -tls_truststore_path: "{{ base_dir_security_pki }}/truststore.jks" -tls_uber_truststore_path: "{{ base_dir_security_pki }}/full_truststore.jks" -tls_truststore_password: changeme - -jdk_java_cacerts_password: changeit - -__temp_keychain: "{{ base_dir_security_pki }}/tmp_keychain.pem" __temp_keystore: "{{ base_dir_security_pki }}/tmp_keystore.p12" \ No newline at end of file diff --git a/roles/tls_install_certs/meta/argument_specs.yml b/roles/tls_install_certs/meta/argument_specs.yml new file mode 100644 index 00000000..e1e9fa2b --- /dev/null +++ b/roles/tls_install_certs/meta/argument_specs.yml @@ -0,0 +1,65 @@ +# Copyright 2024 Cloudera, Inc. +# +# 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. + +--- + +argument_specs: + main: + short_description: "Copy and install the signed TLS certificates to each cluster" + description: + - Copies the signed TLS cert to each cluster host. + - Updates the Java keystore with the renewed certificate + author: + - "Jim Enright " + options: + openssl_path: + description: "Absolute path to the C(openssl) executable" + default: "/usr/bin/openssl" + type: "str" + base_dir_security: + description: "Base directory for Cloudera CDP security related files" + type: "str" + default: "/opt/cloudera/security" + base_dir_security_pki: + description: "Base directory for Cloudera CDP PKI security related files" + type: "str" + default: "{{ base_dir_security }}/pki" + tls_cert_path: + description: "Location where the signed TLS certificate should be copied." + type: "str" + default: "{{ base_dir_security_pki }}/{{ inventory_hostname }}.pem" + tls_cert_path_generic: + description: "Host agnostic file name for the signed TLS certificate" + type: "str" + default: "{{ base_dir_security_pki }}/host.pem" + tls_key_path_generic: + description: "Host agnostic file name for the encrypted TLS key" + type: "str" + default: "{{ base_dir_security_pki }}/host.key" + tls_key_path_plaintext_generic: + description: "Host agnostic file name for the unencrypted TLS key" + type: "str" + default: "{{ tls_key_path_generic }}.unenc" + tls_ca_chain_path: + description: "Full path to the TLS CA chain file" + type: "str" + default: "{{ base_dir_security_pki }}/chain.pem" + tls_keystore_path: + description: "Full path to Java Keystore file" + type: "str" + default: "{{ base_dir_security_pki }}/{{ inventory_hostname }}.jks" + tls_keystore_password: + description: "Password for the Java Keystore" + type: "str" + default: "changeme" diff --git a/roles/tls_install_certs/tasks/main.yml b/roles/tls_install_certs/tasks/main.yml index dcbcdb83..e7f8c54b 100644 --- a/roles/tls_install_certs/tasks/main.yml +++ b/roles/tls_install_certs/tasks/main.yml @@ -46,7 +46,7 @@ - name: Validate certificate ansible.builtin.shell: - cmd: openssl verify -verbose -CAfile {{ tls_ca_chain_path }} {{ tls_cert_path }} + cmd: {{ openssl_path }} verify -verbose -CAfile {{ tls_ca_chain_path }} {{ tls_cert_path }} # Update the keystore with the renewed cert # Reference: https://support.smartbear.com/collaborator/faq/how-to-update-an-expired-certificate-in-the-existi/ diff --git a/roles/tls_signing/defaults/main.yml b/roles/tls_signing/defaults/main.yml index c2859c28..9c1c1c4e 100644 --- a/roles/tls_signing/defaults/main.yml +++ b/roles/tls_signing/defaults/main.yml @@ -13,12 +13,15 @@ # limitations under the License. --- + +# csrs_to_sign: +copy_from_controller: True + keytool_path: /usr/bin/keytool openssl_path: /usr/bin/openssl ca_server_intermediate_path: /ca/intermediate ca_server_intermediate_path_certs: "{{ ca_server_intermediate_path }}/certs" -ca_server_intermediate_path_crl: "{{ ca_server_intermediate_path }}/crl" ca_server_intermediate_path_csr: "{{ ca_server_intermediate_path }}/csr" ca_server_intermediate_key_password: password diff --git a/roles/tls_signing/meta/argument_specs.yml b/roles/tls_signing/meta/argument_specs.yml new file mode 100644 index 00000000..51fe7476 --- /dev/null +++ b/roles/tls_signing/meta/argument_specs.yml @@ -0,0 +1,63 @@ +# Copyright 2024 Cloudera, Inc. +# +# 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. + +--- + +argument_specs: + main: + short_description: "Sign of CSRs by a CA Server" + description: + - Generates a signed TLS certificate from a specified list of Certificate Signing Requests (CSRs). + - The role will optionally override and backup existing certs of the same name if required. + - Upon completion the signed certs are copied back to the Ansible controller. + author: + - "Jim Enright " + options: + csrs_to_sign: + description: "List of full path locations of the CSRs to sign." + type: "list" + elements: "str" + required: true + copy_from_controller: + description: "Flag to specify if the CSRs should be copied from the Ansible controller." + type: "bool" + default: true + override_old_certs: + description: + - Flag to specify if existing signed certs of the same name should be overridden. + - If C(true) then a backup of the existing certs are taken to the location specified by C(cert_backup_directory). + type: "bool" + default: true + cert_backup_directory: + description: + - Directory where existing signed certs should be backed up. + - Used if the C(override_old_certs) is set to C(true). + type: "str" + default: "{{ ca_server_intermediate_path }}/cert_backup_{{ ansible_date_time.iso8601 | default('')}}" + ca_server_intermediate_path: + description: Common base directory for all intermediate CA resources + type: "str" + default: "/ca/intermediate" + ca_server_intermediate_path_certs: + description: Path to intermediate CA certificates directory + type: "str" + default: "{{ ca_server_intermediate_path }}/certs" + ca_server_intermediate_path_csr: + description: Path to intermediate CA CSR directory + type: "str" + default: "{{ ca_server_intermediate_path }}/csr" + ca_server_intermediate_key_password: + description: Password for the intermediate CA TLS key + type: "str" + default: "password" From ece66524891f535e86e512ec075ea7a98be5616f Mon Sep 17 00:00:00 2001 From: Jim Enright Date: Thu, 22 Aug 2024 14:49:49 +0100 Subject: [PATCH 3/7] Fix lint issues Signed-off-by: Jim Enright --- playbooks/pvc_renew_certs.yml | 14 +++++++------- roles/tls_fetch_ca_certs/defaults/main.yml | 2 +- roles/tls_fetch_ca_certs/meta/argument_specs.yml | 2 +- roles/tls_generate_csr/meta/argument_specs.yml | 6 +++--- roles/tls_install_certs/defaults/main.yml | 2 +- roles/tls_install_certs/tasks/main.yml | 4 ++-- roles/tls_signing/defaults/main.yml | 2 +- roles/tls_signing/meta/argument_specs.yml | 6 +++--- roles/tls_signing/tasks/main.yml | 8 ++++---- 9 files changed, 23 insertions(+), 23 deletions(-) diff --git a/playbooks/pvc_renew_certs.yml b/playbooks/pvc_renew_certs.yml index c9b3d2ac..19c741ac 100644 --- a/playbooks/pvc_renew_certs.yml +++ b/playbooks/pvc_renew_certs.yml @@ -42,7 +42,7 @@ become: yes gather_facts: yes tasks: - + - name: Call tls_generate_csr role ansible.builtin.import_role: name: cloudera.exe.tls_generate_csr @@ -84,7 +84,7 @@ become: yes gather_facts: yes tasks: - + - name: Call tls_install_certs role ansible.builtin.import_role: name: cloudera.exetls_install_certs @@ -98,8 +98,8 @@ tasks: - name: Restart CM Server service - when: - - restart_services | default(False) + when: + - restart_services | default(False) ansible.builtin.service: name: cloudera-scm-server state: restarted @@ -124,8 +124,8 @@ tasks: - name: Restart CM Agent service - when: - - restart_services | default(False) + when: + - restart_services | default(False) ansible.builtin.service: name: cloudera-scm-agent - state: restarted \ No newline at end of file + state: restarted diff --git a/roles/tls_fetch_ca_certs/defaults/main.yml b/roles/tls_fetch_ca_certs/defaults/main.yml index 057969c2..015fbb85 100644 --- a/roles/tls_fetch_ca_certs/defaults/main.yml +++ b/roles/tls_fetch_ca_certs/defaults/main.yml @@ -19,4 +19,4 @@ ca_server_intermediate_cert_name: intermediate.cert.pem ca_server_root_path: /ca/certs ca_server_root_cert_name: ca.cert.pem -# local_ca_certs_dir \ No newline at end of file +# local_ca_certs_dir diff --git a/roles/tls_fetch_ca_certs/meta/argument_specs.yml b/roles/tls_fetch_ca_certs/meta/argument_specs.yml index 6dea9f03..5bff0f30 100644 --- a/roles/tls_fetch_ca_certs/meta/argument_specs.yml +++ b/roles/tls_fetch_ca_certs/meta/argument_specs.yml @@ -41,4 +41,4 @@ argument_specs: local_ca_certs_dir: description: "Directory on Ansible controller to store the root and intermediate CA cert files" type: "str" - required: true \ No newline at end of file + required: true diff --git a/roles/tls_generate_csr/meta/argument_specs.yml b/roles/tls_generate_csr/meta/argument_specs.yml index 72270afe..a6a2b685 100644 --- a/roles/tls_generate_csr/meta/argument_specs.yml +++ b/roles/tls_generate_csr/meta/argument_specs.yml @@ -36,7 +36,7 @@ argument_specs: type: "str" default: "{{ base_dir_security }}/pki" tls_csr_config_path: - description: + description: - Location of the OpenSSL configuration file that will be created by the role. - This file will be generated by the C(csr.cnf.j2) template file. type: "str" @@ -56,7 +56,7 @@ argument_specs: tls_key_password: description: "Password for the TLS Key." type: "str" - default: "changeme" + default: "changeme" tls_key_path: description: "Location of the TLS key." type: "str" @@ -64,4 +64,4 @@ argument_specs: local_csrs_dir: description: "Location on the Ansible Controller where the CSR will be copied." type: "str" - default: "{{ base_dir_security_pki }}/{{ inventory_hostname }}.key" \ No newline at end of file + default: "{{ base_dir_security_pki }}/{{ inventory_hostname }}.key" diff --git a/roles/tls_install_certs/defaults/main.yml b/roles/tls_install_certs/defaults/main.yml index b1ae4049..f4ff8bcc 100644 --- a/roles/tls_install_certs/defaults/main.yml +++ b/roles/tls_install_certs/defaults/main.yml @@ -31,4 +31,4 @@ tls_ca_chain_path: "{{ base_dir_security_pki }}/chain.pem" tls_keystore_path: "{{ base_dir_security_pki }}/{{ inventory_hostname }}.jks" tls_keystore_password: changeme -__temp_keystore: "{{ base_dir_security_pki }}/tmp_keystore.p12" \ No newline at end of file +__temp_keystore: "{{ base_dir_security_pki }}/tmp_keystore.p12" diff --git a/roles/tls_install_certs/tasks/main.yml b/roles/tls_install_certs/tasks/main.yml index e7f8c54b..27b9e8b6 100644 --- a/roles/tls_install_certs/tasks/main.yml +++ b/roles/tls_install_certs/tasks/main.yml @@ -46,7 +46,7 @@ - name: Validate certificate ansible.builtin.shell: - cmd: {{ openssl_path }} verify -verbose -CAfile {{ tls_ca_chain_path }} {{ tls_cert_path }} + cmd: "{{ openssl_path }} verify -verbose -CAfile {{ tls_ca_chain_path }} {{ tls_cert_path }}" # Update the keystore with the renewed cert # Reference: https://support.smartbear.com/collaborator/faq/how-to-update-an-expired-certificate-in-the-existi/ @@ -58,7 +58,7 @@ action: export path: "{{ __temp_keystore }}" passphrase: "{{ tls_keystore_password }}" - friendly_name: "{{ keystore_alias | default(inventory_hostname) }}" + friendly_name: "{{ keystore_alias | default(inventory_hostname) }}" privatekey_path: "{{ tls_key_path_plaintext_generic }}" certificate_path: "{{ tls_cert_path_generic }}" other_certificates: diff --git a/roles/tls_signing/defaults/main.yml b/roles/tls_signing/defaults/main.yml index 9c1c1c4e..ddcc2dde 100644 --- a/roles/tls_signing/defaults/main.yml +++ b/roles/tls_signing/defaults/main.yml @@ -26,4 +26,4 @@ ca_server_intermediate_path_csr: "{{ ca_server_intermediate_path }}/csr" ca_server_intermediate_key_password: password override_old_certs: True -cert_backup_directory: "{{ ca_server_intermediate_path }}/cert_backup_{{ ansible_date_time.iso8601 | default('')}}" \ No newline at end of file +cert_backup_directory: "{{ ca_server_intermediate_path }}/cert_backup_{{ ansible_date_time.iso8601 | default('')}}" diff --git a/roles/tls_signing/meta/argument_specs.yml b/roles/tls_signing/meta/argument_specs.yml index 51fe7476..d66b3379 100644 --- a/roles/tls_signing/meta/argument_specs.yml +++ b/roles/tls_signing/meta/argument_specs.yml @@ -34,13 +34,13 @@ argument_specs: type: "bool" default: true override_old_certs: - description: + description: - Flag to specify if existing signed certs of the same name should be overridden. - If C(true) then a backup of the existing certs are taken to the location specified by C(cert_backup_directory). type: "bool" default: true cert_backup_directory: - description: + description: - Directory where existing signed certs should be backed up. - Used if the C(override_old_certs) is set to C(true). type: "str" @@ -52,7 +52,7 @@ argument_specs: ca_server_intermediate_path_certs: description: Path to intermediate CA certificates directory type: "str" - default: "{{ ca_server_intermediate_path }}/certs" + default: "{{ ca_server_intermediate_path }}/certs" ca_server_intermediate_path_csr: description: Path to intermediate CA CSR directory type: "str" diff --git a/roles/tls_signing/tasks/main.yml b/roles/tls_signing/tasks/main.yml index c66f29ab..730f359c 100644 --- a/roles/tls_signing/tasks/main.yml +++ b/roles/tls_signing/tasks/main.yml @@ -51,17 +51,17 @@ loop: "{{ __csrs_to_sign }}" register: __old_certs - - name: Copy existing certs to backup directory + - name: Copy existing certs to backup directory when: item.stat.exists ansible.builtin.copy: src: "{{ item.stat.path }}" dest: "{{ cert_backup_directory }}" - remote_src: True + remote_src: True loop: "{{ __old_certs.results }}" - name: Remove old certs when: item.stat.exists - ansible.builtin.file: + ansible.builtin.file: path: "{{ item.stat.path }}" state: absent loop: "{{ __old_certs.results }}" @@ -90,4 +90,4 @@ src: "{{ ca_server_intermediate_path_certs }}/{{ item.file_suffix }}.pem" dest: "{{ local_certs_dir }}/{{ item.file_suffix }}.pem" flat: yes - loop: "{{ __csrs_to_sign }}" + loop: "{{ __csrs_to_sign }}" From 14671e1b7fb300b1eef9e8c4bcc5a5cfdf490378 Mon Sep 17 00:00:00 2001 From: Jim Enright Date: Mon, 26 Aug 2024 19:29:55 +0100 Subject: [PATCH 4/7] Updates based on PR feedback Signed-off-by: Jim Enright --- playbooks/pvc_renew_certs.yml | 5 +-- .../tls_generate_csr/meta/argument_specs.yml | 4 --- roles/tls_generate_csr/tasks/main.yml | 36 +++++++++++-------- roles/tls_generate_csr/templates/csr.cnf.j2 | 23 ------------ roles/tls_install_certs/defaults/main.yml | 2 -- roles/tls_install_certs/tasks/main.yml | 19 ++++++---- roles/tls_signing/defaults/main.yml | 12 +++---- roles/tls_signing/meta/argument_specs.yml | 11 ++---- 8 files changed, 44 insertions(+), 68 deletions(-) delete mode 100644 roles/tls_generate_csr/templates/csr.cnf.j2 diff --git a/playbooks/pvc_renew_certs.yml b/playbooks/pvc_renew_certs.yml index 19c741ac..fe1476d6 100644 --- a/playbooks/pvc_renew_certs.yml +++ b/playbooks/pvc_renew_certs.yml @@ -24,9 +24,6 @@ prefix: pvc_tls_ register: __pvc_tls_tempdir - - debug: - var: __pvc_tls_tempdir - - name: Create a directory for csrs and signed certs ansible.builtin.file: path: "{{ [__pvc_tls_tempdir.path, item] | path_join }}" @@ -87,7 +84,7 @@ - name: Call tls_install_certs role ansible.builtin.import_role: - name: cloudera.exetls_install_certs + name: cloudera.exe.tls_install_certs vars: local_tls_signed_certs_dir: "{{ (hostvars['localhost']['__pvc_tls_tempdir']['path'], 'certs') | path_join }}" diff --git a/roles/tls_generate_csr/meta/argument_specs.yml b/roles/tls_generate_csr/meta/argument_specs.yml index a6a2b685..0cb37f10 100644 --- a/roles/tls_generate_csr/meta/argument_specs.yml +++ b/roles/tls_generate_csr/meta/argument_specs.yml @@ -23,10 +23,6 @@ argument_specs: author: - "Jim Enright " options: - openssl_path: - description: "Absolute path to the C(openssl) executable" - default: "/usr/bin/openssl" - type: "str" base_dir_security: description: "Base directory for Cloudera CDP security related files" type: "str" diff --git a/roles/tls_generate_csr/tasks/main.yml b/roles/tls_generate_csr/tasks/main.yml index 254c0cdc..6a823e87 100644 --- a/roles/tls_generate_csr/tasks/main.yml +++ b/roles/tls_generate_csr/tasks/main.yml @@ -26,12 +26,14 @@ loop_control: loop_var: dir -- ansible.builtin.set_fact: +- name: Read subject attribute from certificate DN template file + ansible.builtin.set_fact: subject_attr: "{{ lookup('template', 'certificate_dn.j2') | from_yaml }}" -- ansible.builtin.set_fact: - openssl_subject: "/{{ subject_attr | map('regex_replace', '/', '\\/') | join('/') }}" - keytool_subject: "{{ subject_attr | map('regex_replace', ',', '\\,') | join(',') }}" +- name: Derive openssl subjects from subject attribute + ansible.builtin.set_fact: + openssl_subject: "{{ openssl_subject | default({}) | combine( {item.split('=')[0] : item.split('=')[1]}) }}" + loop: "{{ subject_attr }}" - name: Create openssl.cnf for CSR generation ansible.builtin.template: @@ -41,16 +43,22 @@ mode: 0644 - name: Generate CSR - ansible.builtin.shell: - cmd: > - {{ openssl_path }} req - -key {{ tls_key_path }} - -passin pass:{{ tls_key_password }} - -subj "{{ openssl_subject }}" - -config {{ tls_csr_config_path }} - -new - -out {{ tls_csr_path }} - creates: "{{ tls_csr_path }}" + community.crypto.openssl_csr: + path: "{{ tls_csr_path }}" + privatekey_path: "{{ tls_key_path }}" + privatekey_passphrase: "{{ tls_key_password }}" + subject: "{{ openssl_subject }}" + backup: true + basic_constraints: + - "CA:FALSE" + keyUsage: + - "nonRepudiation" + - "digitalSignature" + - "keyEncipherment" + extendedKeyUsage: + - "serverAuth" + - "clientAuth" + subject_alt_name: "DNS:{{ inventory_hostname }}" - name: Bring CSRs back to controller ansible.builtin.fetch: diff --git a/roles/tls_generate_csr/templates/csr.cnf.j2 b/roles/tls_generate_csr/templates/csr.cnf.j2 deleted file mode 100644 index d5c600f1..00000000 --- a/roles/tls_generate_csr/templates/csr.cnf.j2 +++ /dev/null @@ -1,23 +0,0 @@ -[ CA_default ] -# Directory and file locations. -default_md = sha256 - -[ req ] -# Options for the `req` tool (`man req`). -default_bits = 2048 -req_extensions = cloudera_req -distinguished_name = req_distinguished_name - -[req_distinguished_name] - -[ cloudera_req ] -basicConstraints = CA:FALSE -keyUsage = nonRepudiation, digitalSignature, keyEncipherment -extendedKeyUsage = serverAuth, clientAuth -subjectAltName = @alt_names - -[alt_names] -DNS.1 = {{ inventory_hostname }} -{% for san in subject_alternative_names | default([]) %} -DNS.{{ loop.index + 1 }} = {{ san }} -{% endfor %} diff --git a/roles/tls_install_certs/defaults/main.yml b/roles/tls_install_certs/defaults/main.yml index f4ff8bcc..9b7028c1 100644 --- a/roles/tls_install_certs/defaults/main.yml +++ b/roles/tls_install_certs/defaults/main.yml @@ -25,10 +25,8 @@ tls_cert_path_generic: "{{ base_dir_security_pki }}/host.pem" tls_key_path_generic: "{{ base_dir_security_pki }}/host.key" tls_key_path_plaintext_generic: "{{ tls_key_path_generic }}.unenc" - tls_ca_chain_path: "{{ base_dir_security_pki }}/chain.pem" tls_keystore_path: "{{ base_dir_security_pki }}/{{ inventory_hostname }}.jks" tls_keystore_password: changeme -__temp_keystore: "{{ base_dir_security_pki }}/tmp_keystore.p12" diff --git a/roles/tls_install_certs/tasks/main.yml b/roles/tls_install_certs/tasks/main.yml index 27b9e8b6..d868819f 100644 --- a/roles/tls_install_certs/tasks/main.yml +++ b/roles/tls_install_certs/tasks/main.yml @@ -21,7 +21,8 @@ path: "{{ local_tls_signed_certs_dir }}/{{ inventory_hostname }}.pem" register: signed_cert -- ansible.builtin.fail: +- name: Fail is the signed certificate is not available for this host + ansible.builtin.fail: msg: > "Signed cert for {{ inventory_hostname }} could not be found. If manual signing is required, do this now and re-run the playbook with 'tls_signed_certs_dir' variable set. @@ -45,18 +46,24 @@ group: root - name: Validate certificate - ansible.builtin.shell: + ansible.builtin.command: cmd: "{{ openssl_path }} verify -verbose -CAfile {{ tls_ca_chain_path }} {{ tls_cert_path }}" # Update the keystore with the renewed cert # Reference: https://support.smartbear.com/collaborator/faq/how-to-update-an-expired-certificate-in-the-existi/ # ....Step 1: Create chain including signed host cert # ....Step 2: Create PKCS12 keystore with chain and key. Alias name is {{ inventory_hostname }} -# NOTE: Step 1 & 2 are handled by the task below +# NOTE: Step 1 & 2 are handled by the tasks below +- name: Create temporary keystore file name + ansible.builtin.tempfile: + state: file + suffix: tmp_keystore.p12 + register: __pvc_tls_temp_keystore + - name: Generate a temporary PKCS12 keystore with renewed cert community.crypto.openssl_pkcs12: action: export - path: "{{ __temp_keystore }}" + path: "{{ __pvc_tls_temp_keystore.path }}" passphrase: "{{ tls_keystore_password }}" friendly_name: "{{ keystore_alias | default(inventory_hostname) }}" privatekey_path: "{{ tls_key_path_plaintext_generic }}" @@ -68,7 +75,7 @@ # ....Step 3: Update the {{ tls_keystore_path }} with the above keystore - name: Import the temporary keystore to {{ tls_keystore_path }} community.general.java_cert: - pkcs12_path: "{{ __temp_keystore }}" + pkcs12_path: "{{ __pvc_tls_temp_keystore.path }}" pkcs12_alias: "{{ keystore_alias | default(inventory_hostname) }}" pkcs12_password: "{{ tls_keystore_password }}" cert_alias: "{{ keystore_alias | default(inventory_hostname) }}" @@ -79,5 +86,5 @@ - name: Remove the temporary keystore ansible.builtin.file: - path: "{{ __temp_keystore }}" + path: "{{ __pvc_tls_temp_keystore.path }}" state: absent diff --git a/roles/tls_signing/defaults/main.yml b/roles/tls_signing/defaults/main.yml index ddcc2dde..e3fe7b63 100644 --- a/roles/tls_signing/defaults/main.yml +++ b/roles/tls_signing/defaults/main.yml @@ -17,13 +17,13 @@ # csrs_to_sign: copy_from_controller: True -keytool_path: /usr/bin/keytool -openssl_path: /usr/bin/openssl - ca_server_intermediate_path: /ca/intermediate +ca_server_intermediate_private_key: "{{ ca_server_intermediate_path }}/private/intermediate.key.pem" +ca_server_intermediate_private_key_password: password + ca_server_intermediate_path_certs: "{{ ca_server_intermediate_path }}/certs" +ca_server_intermediate_cert: "{{ ca_server_intermediate_path_certs }}/intermediate.cert.pem" + ca_server_intermediate_path_csr: "{{ ca_server_intermediate_path }}/csr" -ca_server_intermediate_key_password: password -override_old_certs: True -cert_backup_directory: "{{ ca_server_intermediate_path }}/cert_backup_{{ ansible_date_time.iso8601 | default('')}}" +backup_old_certs: True \ No newline at end of file diff --git a/roles/tls_signing/meta/argument_specs.yml b/roles/tls_signing/meta/argument_specs.yml index d66b3379..9b151e3f 100644 --- a/roles/tls_signing/meta/argument_specs.yml +++ b/roles/tls_signing/meta/argument_specs.yml @@ -33,18 +33,11 @@ argument_specs: description: "Flag to specify if the CSRs should be copied from the Ansible controller." type: "bool" default: true - override_old_certs: + backup_old_certs: description: - - Flag to specify if existing signed certs of the same name should be overridden. - - If C(true) then a backup of the existing certs are taken to the location specified by C(cert_backup_directory). + - Flag to specify if existing signed certs of the same name should be backed up. type: "bool" default: true - cert_backup_directory: - description: - - Directory where existing signed certs should be backed up. - - Used if the C(override_old_certs) is set to C(true). - type: "str" - default: "{{ ca_server_intermediate_path }}/cert_backup_{{ ansible_date_time.iso8601 | default('')}}" ca_server_intermediate_path: description: Common base directory for all intermediate CA resources type: "str" From 191ffe520c6e1bb3fb3192cba8ef74e3d50de117 Mon Sep 17 00:00:00 2001 From: Jim Enright Date: Mon, 26 Aug 2024 19:42:23 +0100 Subject: [PATCH 5/7] Fix lint issues Signed-off-by: Jim Enright --- roles/tls_generate_csr/tasks/main.yml | 2 +- roles/tls_install_certs/defaults/main.yml | 1 - roles/tls_install_certs/tasks/main.yml | 2 +- roles/tls_signing/defaults/main.yml | 2 +- 4 files changed, 3 insertions(+), 4 deletions(-) diff --git a/roles/tls_generate_csr/tasks/main.yml b/roles/tls_generate_csr/tasks/main.yml index 6a823e87..b8d72988 100644 --- a/roles/tls_generate_csr/tasks/main.yml +++ b/roles/tls_generate_csr/tasks/main.yml @@ -33,7 +33,7 @@ - name: Derive openssl subjects from subject attribute ansible.builtin.set_fact: openssl_subject: "{{ openssl_subject | default({}) | combine( {item.split('=')[0] : item.split('=')[1]}) }}" - loop: "{{ subject_attr }}" + loop: "{{ subject_attr }}" - name: Create openssl.cnf for CSR generation ansible.builtin.template: diff --git a/roles/tls_install_certs/defaults/main.yml b/roles/tls_install_certs/defaults/main.yml index 9b7028c1..34bbd846 100644 --- a/roles/tls_install_certs/defaults/main.yml +++ b/roles/tls_install_certs/defaults/main.yml @@ -29,4 +29,3 @@ tls_ca_chain_path: "{{ base_dir_security_pki }}/chain.pem" tls_keystore_path: "{{ base_dir_security_pki }}/{{ inventory_hostname }}.jks" tls_keystore_password: changeme - diff --git a/roles/tls_install_certs/tasks/main.yml b/roles/tls_install_certs/tasks/main.yml index d868819f..91c61e99 100644 --- a/roles/tls_install_certs/tasks/main.yml +++ b/roles/tls_install_certs/tasks/main.yml @@ -54,7 +54,7 @@ # ....Step 1: Create chain including signed host cert # ....Step 2: Create PKCS12 keystore with chain and key. Alias name is {{ inventory_hostname }} # NOTE: Step 1 & 2 are handled by the tasks below -- name: Create temporary keystore file name +- name: Create temporary keystore file name ansible.builtin.tempfile: state: file suffix: tmp_keystore.p12 diff --git a/roles/tls_signing/defaults/main.yml b/roles/tls_signing/defaults/main.yml index e3fe7b63..56bda5a9 100644 --- a/roles/tls_signing/defaults/main.yml +++ b/roles/tls_signing/defaults/main.yml @@ -26,4 +26,4 @@ ca_server_intermediate_cert: "{{ ca_server_intermediate_path_certs }}/intermedia ca_server_intermediate_path_csr: "{{ ca_server_intermediate_path }}/csr" -backup_old_certs: True \ No newline at end of file +backup_old_certs: True From aac682548f16af1403e380f571f9d1eae8b6dd4b Mon Sep 17 00:00:00 2001 From: Jim Enright Date: Mon, 26 Aug 2024 19:43:05 +0100 Subject: [PATCH 6/7] Updates based on PR feedback Signed-off-by: Jim Enright --- roles/tls_signing/tasks/main.yml | 58 ++++++-------------------------- 1 file changed, 10 insertions(+), 48 deletions(-) diff --git a/roles/tls_signing/tasks/main.yml b/roles/tls_signing/tasks/main.yml index 730f359c..66887ec4 100644 --- a/roles/tls_signing/tasks/main.yml +++ b/roles/tls_signing/tasks/main.yml @@ -34,56 +34,18 @@ mode: 0644 loop: "{{ __csrs_to_sign }}" -- name: Backup and remove old certs if required - when: override_old_certs - block: - - name: Create backup directory for old certs - ansible.builtin.file: - path: "{{ cert_backup_directory }}" - state: directory - mode: '0755' - - - name: Backup old certs - block: - - name: Check if cert exists - ansible.builtin.stat: - path: "{{ ca_server_intermediate_path_certs }}/{{ item.file_suffix }}.pem" - loop: "{{ __csrs_to_sign }}" - register: __old_certs - - - name: Copy existing certs to backup directory - when: item.stat.exists - ansible.builtin.copy: - src: "{{ item.stat.path }}" - dest: "{{ cert_backup_directory }}" - remote_src: True - loop: "{{ __old_certs.results }}" - - - name: Remove old certs - when: item.stat.exists - ansible.builtin.file: - path: "{{ item.stat.path }}" - state: absent - loop: "{{ __old_certs.results }}" - - name: Sign CSRs - ansible.builtin.shell: - executable: /bin/bash - cmd: > - exec 100>/tmp/ca_server.lock; - flock 100 && - {{ openssl_path }} ca - -batch - -config {{ ca_server_intermediate_path }}/openssl.cnf - -extensions cloudera_req - -days 730 - -notext - -md sha256 - -in {{ ca_server_intermediate_path_csr }}/{{ item.csr_filename }} - -out {{ ca_server_intermediate_path_certs }}/{{ item.file_suffix }}.pem - -passin pass:{{ ca_server_intermediate_key_password }} - creates: "{{ ca_server_intermediate_path_certs }}/{{ item.file_suffix }}.pem" + community.crypto.x509_certificate: + path: "{{ ca_server_intermediate_path_certs }}/{{ item.file_suffix }}.pem" + csr_path: "{{ ca_server_intermediate_path_csr }}/{{ item.csr_filename }}" + backup: "{{ backup_old_certs }}" + provider: ownca + ownca_path: "{{ ca_server_intermediate_cert }}" + ownca_privatekey_path: "{{ ca_server_intermediate_private_key }}" + ownca_privatekey_passphrase: "{{ ca_server_intermediate_private_key_password }}" + selfsigned_not_after: "+730d" loop: "{{ __csrs_to_sign }}" + register: __signed_certs - name: Bring signed certs back to controller ansible.builtin.fetch: From a80e1e9827eee704f1a6aff453f7a9078e7df2a0 Mon Sep 17 00:00:00 2001 From: Jim Enright Date: Mon, 26 Aug 2024 20:56:41 +0100 Subject: [PATCH 7/7] Remove tasks and variables used to create openssl.cnf Signed-off-by: Jim Enright --- roles/tls_generate_csr/defaults/main.yml | 1 - roles/tls_generate_csr/meta/argument_specs.yml | 6 ------ roles/tls_generate_csr/tasks/main.yml | 7 ------- 3 files changed, 14 deletions(-) diff --git a/roles/tls_generate_csr/defaults/main.yml b/roles/tls_generate_csr/defaults/main.yml index ae506631..b7ebffb2 100644 --- a/roles/tls_generate_csr/defaults/main.yml +++ b/roles/tls_generate_csr/defaults/main.yml @@ -17,7 +17,6 @@ openssl_path: /usr/bin/openssl base_dir_security: /opt/cloudera/security base_dir_security_pki: "{{ base_dir_security }}/pki" -tls_csr_config_path: "{{ base_dir_security_pki }}/csr.cnf" tls_csr_path: "{{ base_dir_security_pki }}/{{ inventory_hostname }}.csr" # local_csrs_dir: "/tmp/csrs" diff --git a/roles/tls_generate_csr/meta/argument_specs.yml b/roles/tls_generate_csr/meta/argument_specs.yml index 0cb37f10..d821614b 100644 --- a/roles/tls_generate_csr/meta/argument_specs.yml +++ b/roles/tls_generate_csr/meta/argument_specs.yml @@ -31,12 +31,6 @@ argument_specs: description: "Base directory for Cloudera CDP PKI security related files" type: "str" default: "{{ base_dir_security }}/pki" - tls_csr_config_path: - description: - - Location of the OpenSSL configuration file that will be created by the role. - - This file will be generated by the C(csr.cnf.j2) template file. - type: "str" - default: "{{ base_dir_security_pki }}/csr.cnf" tls_csr_path: description: "Location of the OpenSSL Certificate Signing Request file that will be created by the role" type: "str" diff --git a/roles/tls_generate_csr/tasks/main.yml b/roles/tls_generate_csr/tasks/main.yml index b8d72988..1e45b15d 100644 --- a/roles/tls_generate_csr/tasks/main.yml +++ b/roles/tls_generate_csr/tasks/main.yml @@ -35,13 +35,6 @@ openssl_subject: "{{ openssl_subject | default({}) | combine( {item.split('=')[0] : item.split('=')[1]}) }}" loop: "{{ subject_attr }}" -- name: Create openssl.cnf for CSR generation - ansible.builtin.template: - src: csr.cnf.j2 - dest: "{{ tls_csr_config_path }}" - owner: root - mode: 0644 - - name: Generate CSR community.crypto.openssl_csr: path: "{{ tls_csr_path }}"