From f25ee781289af6dbae598dc9da76ef2f0a2e8062 Mon Sep 17 00:00:00 2001 From: Noriko Hosoi Date: Sun, 9 Oct 2022 21:13:48 -0700 Subject: [PATCH 1/2] Use the certificate role to create the cert and the key - Introduce a variable cockpit_certificates to set the certificate_requests. - Add a test script tests_certificate_internal.yml. - Rename tests_certificate.yml to tests_certificate_external.yml. - Update README so that using the certificate role is recommended. --- README.md | 37 ++++++++++- defaults/main.yml | 3 + tasks/main.yml | 17 +++++ ...ate.yml => tests_certificate_external.yml} | 0 tests/tests_certificate_internal.yml | 62 +++++++++++++++++++ 5 files changed, 116 insertions(+), 3 deletions(-) rename tests/{tests_certificate.yml => tests_certificate_external.yml} (100%) create mode 100644 tests/tests_certificate_internal.yml diff --git a/README.md b/README.md index 614ce5c..3f94d2b 100644 --- a/README.md +++ b/README.md @@ -145,7 +145,34 @@ Note that this functionality requires at least Cockpit version 257, i.e. RHEL ### Generate a new certificate -For generating a new certificate for Cockpit it is recommended to use the [linux-system-roles.certificate role](https://github.com/linux-system-roles/certificate/). If your machines are joined to a FreeIPA domain, or you use certmonger in a different mode already, generate a certificate with: +For generating a new certificate for Cockpit it is recommended to set the +`cockpit_certificates` variable. The value of `cockpit_certificates` is passed +on to the `certificate_requests` variable of the `certificate` role called +internally in the `cockpit` role and it generates the private key and certificate. +For the supported parameters of `cockpit_certificates`, see the +[`certificate_requests` role documentation section](https://github.com/linux-system-roles/certificate/#certificate_requests). + +When you set `cockpit_certificates`, you must not set `cockpit_private_key` +and `cockpit_cert` variables because they are ignored. + +This example installs Cockpit with an IdM-issued web server certificate +assuming your machines are joined to a FreeIPA domain. + +```yaml + - name: Install cockpit with Cockpit web server certificate + include_role: + name: linux-system-roles.cockpit + vars: + cockpit_certificates: + - name: monger-cockpit + dns: ['localhost', 'www.example.com'] + ca: ipa + group: cockpit-ws +``` + +Note: Generating a new certificate using the [linux-system-roles.certificate role](https://github.com/linux-system-roles/certificate/) in the playbook remains supported. + +This example also installs Cockpit with an IdM-issued web server certificate. ```yaml # This step is only necessary for Cockpit version < 255; in particular on RHEL/CentOS 8 @@ -166,9 +193,13 @@ For generating a new certificate for Cockpit it is recommended to use the [linux group: cockpit-ws ``` -You can also use `ca: self-sign` or `ca: local` depending on your certmonger usage, see the [linux-system-roles.certificate documentation](https://github.com/linux-system-roles/certificate/#cas-and-providers) for details. +NOTE: The `certificate` role, unless using IPA and joining the systems to an IPA domain, +creates self-signed certificates, so you will need to explicitly configure trust, +which is not currently supported by the system roles. To use `ca: self-sign` or +`ca: local`, depending on your certmonger usage, see the +[linux-system-roles.certificate documentation](https://github.com/linux-system-roles/certificate/#cas-and-providers) for details. -Note that this does *not* work on RHEL/CentOS 7. +NOTE: This does *not* work on RHEL/CentOS 7. ## Example Playbooks The most simple example. diff --git a/defaults/main.yml b/defaults/main.yml index 5fccdb0..04f8651 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -23,3 +23,6 @@ cockpit_manage_firewall: no # If yes, manage the cockpit ports using the selinux role. cockpit_manage_selinux: no + +# pass to the certificate_requests variable of the certificate role. +cockpit_certificates: [] diff --git a/tasks/main.yml b/tasks/main.yml index aee7476..697b6bb 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -79,6 +79,23 @@ when: cockpit_config is defined notify: restart cockpit +- name: Create certificates + when: + - cockpit_certificates | length > 0 + - ansible_facts['os_family'] == 'RedHat' + block: + - name: Create certificates using the certificate role + include_role: + name: fedora.linux_system_roles.certificate + vars: + __cert_name: "{{ cockpit_certificates.0.name | basename }}" + certificate_requests: "{{ cockpit_certificates }}" + + - name: Set cockpit_cert and cockpit_private_key + set_fact: + cockpit_cert: "/etc/pki/tls/certs/{{ cockpit_certificates.0.name }}.crt" + cockpit_private_key: "/etc/pki/tls/private/{{ cockpit_certificates.0.name }}.key" + - name: Link to configured existing certificate file: src: "{{ cockpit_cert }}" diff --git a/tests/tests_certificate.yml b/tests/tests_certificate_external.yml similarity index 100% rename from tests/tests_certificate.yml rename to tests/tests_certificate_external.yml diff --git a/tests/tests_certificate_internal.yml b/tests/tests_certificate_internal.yml new file mode 100644 index 0000000..2cee09c --- /dev/null +++ b/tests/tests_certificate_internal.yml @@ -0,0 +1,62 @@ +--- +- name: Install cockpit + hosts: all + vars: + cockpit_packages: minimal + cockpit_certificates: + - name: cockpit_cert + dns: ['localhost', 'www.example.com'] + ca: self-sign + group: cockpit-ws + roles: + - linux-system-roles.cockpit + +- name: Verify self-signed certmonger certificate created by the certificate role + hosts: all + vars: + cert_name: cockpit_cert + tasks: + - name: tests + block: + - name: Collect installed package versions + package_facts: + + - name: Check if cockpit is new enough (at least 211) to support certmonger + when: ansible_facts.packages['cockpit-ws'][0].version | int >= 211 + block: + # + # Validate installation + # + - name: test - cockpit works with TLS and expected certificate + command: + cmd: curl --cacert "/etc/pki/tls/certs/{{ cert_name }}.crt" https://localhost:9090 + # ansible 2.11's uri module has ca_path, but that's still too new for us + warn: false + changed_when: false + + - name: test - get certmonger tracking status + command: getcert list --tracking-only -f "/etc/pki/tls/certs/{{ cert_name }}.crt" + register: result + changed_when: false + + - name: test - ensure certificate generation succeeded + assert: + that: "'status: MONITORING' in result.stdout" + + - name: test - clean up tracked certificate + command: getcert stop-tracking -f "/etc/pki/tls/certs/{{ cert_name }}.crt" + changed_when: false + + always: + - name: test - clean up generated certificate + file: + path: "/etc/pki/tls/certs/{{ cert_name }}.crt" + state: absent + + - name: test - clean up generated private key + file: + path: "/etc/pki/tls/private/{{ cert_name }}.key" + state: absent + + - name: test - generic cleanup + include_tasks: tasks/cleanup.yml From a118f4597201c010946ed4d6126ed30a5a627c05 Mon Sep 17 00:00:00 2001 From: Noriko Hosoi Date: Fri, 28 Oct 2022 13:23:22 -0700 Subject: [PATCH 2/2] Add a check and README note for not supporting creating a self-signed certificate on RHEL/CentOS-7. --- README.md | 2 +- tasks/main.yml | 10 +++++- tests/tests_certificate_internal.yml | 54 +++++++++++++++++----------- 3 files changed, 43 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 3f94d2b..e8f39ac 100644 --- a/README.md +++ b/README.md @@ -199,7 +199,7 @@ which is not currently supported by the system roles. To use `ca: self-sign` or `ca: local`, depending on your certmonger usage, see the [linux-system-roles.certificate documentation](https://github.com/linux-system-roles/certificate/#cas-and-providers) for details. -NOTE: This does *not* work on RHEL/CentOS 7. +NOTE: This creating a self-signed certificate is not supported on RHEL/CentOS-7. ## Example Playbooks The most simple example. diff --git a/tasks/main.yml b/tasks/main.yml index 697b6bb..faa3835 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -84,11 +84,19 @@ - cockpit_certificates | length > 0 - ansible_facts['os_family'] == 'RedHat' block: + - name: Check the OS version for self-sign + when: + - (ansible_facts['distribution_version'] | int == 7 and + cockpit_certificates.0.ca == 'self-sign') + fail: + msg: >- + Creating a self-signed certificate is not supported on + {{ ansible_facts['distribution'] }}-{{ ansible_facts['distribution_version'] }} + - name: Create certificates using the certificate role include_role: name: fedora.linux_system_roles.certificate vars: - __cert_name: "{{ cockpit_certificates.0.name | basename }}" certificate_requests: "{{ cockpit_certificates }}" - name: Set cockpit_cert and cockpit_private_key diff --git a/tests/tests_certificate_internal.yml b/tests/tests_certificate_internal.yml index 2cee09c..cef391c 100644 --- a/tests/tests_certificate_internal.yml +++ b/tests/tests_certificate_internal.yml @@ -1,32 +1,44 @@ --- -- name: Install cockpit +- name: Test the cockpit role calling the certificate role internally hosts: all - vars: - cockpit_packages: minimal - cockpit_certificates: - - name: cockpit_cert - dns: ['localhost', 'www.example.com'] - ca: self-sign - group: cockpit-ws - roles: - - linux-system-roles.cockpit - -- name: Verify self-signed certmonger certificate created by the certificate role - hosts: all - vars: - cert_name: cockpit_cert tasks: - name: tests + vars: + cert_name: cockpit_cert block: - - name: Collect installed package versions - package_facts: + - name: Install cockpit using the certificate role to create a certificate + block: + - name: Install cockpit with cockpit_certificates request + vars: + cockpit_packages: minimal + cockpit_certificates: + - name: "{{ cert_name }}" + dns: ['localhost', 'www.example.com'] + ca: self-sign + group: cockpit-ws + include_role: + name: linux-system-roles.cockpit + rescue: + - name: Check the error message + vars: + expected: >- + Creating a self-signed certificate is not supported on + {{ ansible_facts['distribution'] }}-{{ ansible_facts['distribution_version'] }} + assert: + that: ansible_failed_result.msg == expected + when: + - ansible_facts['os_family'] == 'RedHat' + - ansible_facts['distribution_version'] | int == 7 - - name: Check if cockpit is new enough (at least 211) to support certmonger - when: ansible_facts.packages['cockpit-ws'][0].version | int >= 211 + - name: Verify self-signed certmonger certificate created by the certificate role + when: + - ansible_facts['os_family'] == 'RedHat' + - ansible_facts['distribution_version'] | int > 7 block: - # + - name: Collect installed package versions + package_facts: + # Validate installation - # - name: test - cockpit works with TLS and expected certificate command: cmd: curl --cacert "/etc/pki/tls/certs/{{ cert_name }}.crt" https://localhost:9090