Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use the certificate role to create the cert and the key #78

Merged
merged 2 commits into from
Nov 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 34 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 creating a self-signed certificate is not supported on RHEL/CentOS-7.

## Example Playbooks
The most simple example.
Expand Down
3 changes: 3 additions & 0 deletions defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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: []
25 changes: 25 additions & 0 deletions tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,31 @@
when: cockpit_config is defined
notify: restart cockpit

- name: Create certificates
when:
- cockpit_certificates | length > 0
- ansible_facts['os_family'] == 'RedHat'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The node in the readme says NOTE: This does *not* work on RHEL/CentOS 7. - do we need to add a condition for that e.g.

    - ansible_facts['distribution_version'] is version('>=', '8')

?

Copy link
Contributor Author

@nhosoi nhosoi Oct 27, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh, sorry. The note is not needed. The issue was if we try to generate the new cert directly in the target location /etc/cockpit/ws-certs.d like this:

    cockpit_certificates:
      - name: /etc/cockpit/ws-certs.d/cockpit_cert
        <<snip>>

it fails due to this bug on RHEL/CentOS-7 with an invalid mode.

In this PR, it generates the private key and cert in the standard location and copies them to the directories Cockpit expects. So, it is free from the issue. And there's no problem running on RHEL/CentOS-7. (CI successfully passed on the platforms.) I'm removing the note. Thanks for finding it out, @richm!

Oops, the note is needed. It is for this example (located above in README), in which the full path /etc/cockpit/ws-certs.d/monger-cockpit is specified. THAT does not work on RHEL/CentOS 7.

    - name: Generate Cockpit web server certificate
      include_role:
        name: linux-system-roles.certificate
      vars:
        certificate_requests:
          - name: /etc/cockpit/ws-certs.d/monger-cockpit
            dns: ['localhost', 'www.example.com']
            ca: ipa
            group: cockpit-ws

Do we want to describe in a little more detailed manner something like this?

NOTE: This specifying the certificate location by full path does *not* work on RHEL/CentOS 7.

Copy link
Contributor

@richm richm Oct 28, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to describe in a little more detailed manner something like this?

Yes - and - do we have a bz or some other issue tracker for this issue? Or maybe it is a "feature" of cockpit/certmonger?

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:
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 }}"
Expand Down
File renamed without changes.
74 changes: 74 additions & 0 deletions tests/tests_certificate_internal.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
---
- name: Test the cockpit role calling the certificate role internally
hosts: all
tasks:
- name: tests
vars:
cert_name: cockpit_cert
block:
- 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: 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
# 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