From 640e718d8fd365a6f611fde7edca9cf2cb1ab5ec Mon Sep 17 00:00:00 2001 From: "Eric D. Helms" Date: Thu, 13 Nov 2025 10:42:52 -0500 Subject: [PATCH] Add cname support for certificates Signed-off-by: Eric D. Helms --- docs/certificates.md | 25 +++++++++++++++--------- docs/parameters.md | 2 +- src/playbooks/deploy/metadata.obsah.yaml | 4 ++++ src/roles/certificates/defaults/main.yml | 1 + src/roles/certificates/tasks/issue.yml | 2 +- 5 files changed, 23 insertions(+), 11 deletions(-) diff --git a/docs/certificates.md b/docs/certificates.md index 6f189f9b..7d122b42 100644 --- a/docs/certificates.md +++ b/docs/certificates.md @@ -51,14 +51,19 @@ After deployment, certificates are available at: - Server Certificate: `/root/ssl-build//-apache.crt` - Client Certificate: `/root/ssl-build//-foreman-client.crt` -### Current Limitations +### CNAME Support -- Only supports single hostname (no multiple DNS names) -- Cannot provide custom certificate files during deployment -- Fixed 20-year certificate validity period -- Limited certificate customization options +foremanctl supports Subject Alternative Names (SANs) for multi-domain certificates: ---- +```bash +# Generate certificates with multiple DNS names +foremanctl deploy \ + --certificate-cname api.example.com \ + --certificate-cname foreman.example.com \ + --certificate-cname satellite.example.com +``` + +When CNAMEs are specified, certificates will include all names in the Subject Alternative Name field, allowing the same certificate to be valid for multiple hostnames. ## Internal Design @@ -89,7 +94,8 @@ src/roles/certificates/ 2. **Host Certificate Issuance** (for each hostname in `certificates_hostnames`): - Generate 4096-bit RSA private key - - Create certificate signing request (CSR) + - Create certificate signing request (CSR) with Subject Alternative Names + - Include primary hostname and any additional CNAMEs from `certificate_cname` - Sign certificate with CA (includes serverAuth/clientAuth extensions) - Generate both server and client certificates per hostname @@ -146,5 +152,6 @@ The `certificate_checks` role uses `foreman-certificate-check` binary to validat **OpenSSL Configuration:** - Custom configuration template supports SAN extensions -- Single DNS entry per certificate: `subjectAltName = DNS:{{ certificates_hostname }}` -- Uses OpenSSL's `req` and `ca` commands for generation and signing \ No newline at end of file +- Multiple DNS entries supported: `subjectAltName = DNS:{{ certificates_hostname }}{% for cname in certificate_cname %},DNS:{{ cname }}{% endfor %}` +- Uses OpenSSL's `req` and `ca` commands for generation and signing +- CNAMEs configured via `certificate_cname` variable (list of additional DNS names) diff --git a/docs/parameters.md b/docs/parameters.md index b8746b7f..07611747 100644 --- a/docs/parameters.md +++ b/docs/parameters.md @@ -58,6 +58,7 @@ There are multiple use cases from the users perspective that dictate what parame | Parameter | Description | foreman-installer Parameter | | ----------| ----------- | --------------------------- | +| `--certificate-cname` | Allows defining CNAME for default certificates | --certs-cname | ##### Unmapped @@ -76,7 +77,6 @@ There are multiple use cases from the users perspective that dictate what parame | `--foreman-plugin-tasks-cron-line` | | foreman::plugin::tasks | cron_line | | `--foreman-plugin-tasks-automatic-cleanup` | | foreman::plugin::tasks | automatic_cleanup | | `--tuning` | Sets the tuning profile | foreman-installer | | -| `--certs-cname` | | certs | cname | | `--certs-tar` | | certs | tar | | `--certs-tar-file` | | certs | tar | | `--certs-server-cert` | | certs | server_cert | diff --git a/src/playbooks/deploy/metadata.obsah.yaml b/src/playbooks/deploy/metadata.obsah.yaml index 997aaec9..b208f118 100644 --- a/src/playbooks/deploy/metadata.obsah.yaml +++ b/src/playbooks/deploy/metadata.obsah.yaml @@ -11,6 +11,10 @@ variables: help: Number of workers for Puma. pulp_worker_count: help: Number of Pulp workers. Defaults to 8 or the number of CPU cores, whichever is smaller. + certificates_cnames: + help: Additional DNS name to include in Subject Alternative Names for certificates. Can be specified multiple times. + action: append + parameter: --certificate-cname include: - _certificate_source diff --git a/src/roles/certificates/defaults/main.yml b/src/roles/certificates/defaults/main.yml index c217f72f..2c7c67b2 100644 --- a/src/roles/certificates/defaults/main.yml +++ b/src/roles/certificates/defaults/main.yml @@ -4,3 +4,4 @@ certificates_ca_directory: /root/certificates # Change this to /var/lib? certificates_ca_directory_keys: "{{ certificates_ca_directory }}/private" certificates_ca_directory_certs: "{{ certificates_ca_directory }}/certs" certificates_ca_directory_requests: "{{ certificates_ca_directory }}/requests" +certificates_cnames: [] diff --git a/src/roles/certificates/tasks/issue.yml b/src/roles/certificates/tasks/issue.yml index f532c7d9..2d4796a7 100644 --- a/src/roles/certificates/tasks/issue.yml +++ b/src/roles/certificates/tasks/issue.yml @@ -14,7 +14,7 @@ -config "{{ certificates_ca_directory }}/openssl.cnf" -key "{{ certificates_ca_directory_keys }}/{{ certificates_hostname }}.key" -subj "/CN={{ certificates_hostname }}" - -addext "subjectAltName = DNS:{{ certificates_hostname }}" + -addext "subjectAltName = DNS:{{ certificates_hostname }}{% for cname in certificates_cnames %},DNS:{{ cname }}{% endfor %}" -out "{{ certificates_ca_directory_requests }}/{{ certificates_hostname }}.csr" args: creates: "{{ certificates_ca_directory_requests }}/{{ certificates_hostname }}.csr"