Skip to content

Commit 905fb90

Browse files
committed
Regenerate certs when --certificate-cname is present
1 parent 09cb1e9 commit 905fb90

3 files changed

Lines changed: 73 additions & 0 deletions

File tree

‎docs/certificates.md‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,17 @@ foremanctl deploy \
6565

6666
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.
6767

68+
If certificates already exist from a previous deployment, passing `--certificate-cname` will automatically regenerate the server certificate and CSR to include the new CNAMEs. Existing private keys are reused.
69+
70+
To remove all CNAMEs from an existing certificate, use `--reset-certificate-cname`:
71+
72+
```bash
73+
# Remove all CNAMEs, re-issue cert with only the primary hostname
74+
foremanctl deploy --reset-certificate-cname
75+
```
76+
77+
On each run the role compares the Subject Alternative Names in the existing server certificate against the desired list (hostname + any `--certificate-cname` values). If they differ, the CSR and certificate are regenerated automatically. This means both adding and removing CNAMEs are handled transparently without manual cleanup.
78+
6879
### Current Limitations
6980

7081
- Cannot provide custom certificate files during deployment

‎src/roles/certificates/tasks/issue.yml‎

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,66 @@
3232
args:
3333
creates: "{{ certificates_ca_directory_certs }}/{{ certificates_hostname }}.crt"
3434

35+
- name: 'Read current SANs from server certificate'
36+
ansible.builtin.command: >
37+
openssl x509
38+
-noout
39+
-ext subjectAltName
40+
-in "{{ certificates_ca_directory_certs }}/{{ certificates_hostname }}.crt"
41+
register: certificates_current_sans
42+
changed_when: false
43+
failed_when: false
44+
45+
- name: 'Determine desired SANs'
46+
ansible.builtin.set_fact:
47+
certificates_desired_sans: >-
48+
DNS:{{ certificates_hostname }}{% for cname in certificates_cnames %}, DNS:{{ cname }}{% endfor %}
49+
certificates_current_sans_normalized: >-
50+
{{ certificates_current_sans.stdout | default('')
51+
| regex_search('DNS:.*')
52+
| default('') | trim }}
53+
54+
- name: 'Determine if server certificate SANs need updating'
55+
ansible.builtin.set_fact:
56+
certificates_update_sans: >-
57+
{{ certificates_current_sans.rc == 0 and
58+
certificates_desired_sans != certificates_current_sans_normalized }}
59+
60+
- name: 'Remove outdated server signing request'
61+
ansible.builtin.file:
62+
path: "{{ certificates_ca_directory_requests }}/{{ certificates_hostname }}.csr"
63+
state: absent
64+
when: certificates_update_sans | bool
65+
66+
- name: 'Recreate server signing request with updated SANs'
67+
ansible.builtin.command: >
68+
openssl req
69+
-new
70+
-config "{{ certificates_ca_directory }}/openssl.cnf"
71+
-key "{{ certificates_ca_directory_keys }}/{{ certificates_hostname }}.key"
72+
-subj "/CN={{ certificates_hostname }}"
73+
-addext "subjectAltName = {{ certificates_desired_sans }}"
74+
-out "{{ certificates_ca_directory_requests }}/{{ certificates_hostname }}.csr"
75+
when: certificates_update_sans | bool
76+
77+
- name: 'Remove outdated server certificate'
78+
ansible.builtin.file:
79+
path: "{{ certificates_ca_directory_certs }}/{{ certificates_hostname }}.crt"
80+
state: absent
81+
when: certificates_update_sans | bool
82+
83+
- name: 'Re-sign server certificate with updated SANs'
84+
ansible.builtin.command: >
85+
openssl ca
86+
-create_serial
87+
-batch
88+
-extensions ssl_server
89+
-config "{{ certificates_ca_directory }}/openssl.cnf"
90+
-passin "file:{{ certificates_ca_directory_keys }}/ca.pwd"
91+
-in "{{ certificates_ca_directory_requests }}/{{ certificates_hostname }}.csr"
92+
-out "{{ certificates_ca_directory_certs }}/{{ certificates_hostname }}.crt"
93+
when: certificates_update_sans | bool
94+
3595
- name: 'Create client key'
3696
ansible.builtin.command: >
3797
openssl genrsa

‎src/roles/httpd/tasks/main.yml‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@
5050
dest: "certs/katello-apache.crt"
5151
- src: "{{ httpd_server_key }}"
5252
dest: "private/katello-apache.key"
53+
notify:
54+
- Restart httpd
5355

5456
- name: Copy CA certificate to pub directory for client trust
5557
ansible.builtin.copy:

0 commit comments

Comments
 (0)