Le certificat SSL du Satellite et/ou Capsule est expiré, voici comment le regénérer avec IDM.
Dans mon cas l’IDM sert de PKI et de DNS.
Satellite#
Générer le csr#
$ ansible-playbook playbook/generate_csr.yaml -e "host=satellite.gnali.lab"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
| ---
# Generate certificate signin requests
- name: "Generate Satellite SSL certificates"
hosts: "{{ host }}"
tasks:
- name: "Localhost: Create temporary directory"
ansible.builtin.file:
path: "{{ ssldir }}/{{ ansible_fqdn }}"
state: "directory"
recurse: yes
delegate_to: localhost
run_once: yes
- name: "Localhost: Generate private key"
community.crypto.openssl_privatekey:
size: 4096
type: "RSA"
path: "{{ ssldir }}/{{ ansible_fqdn }}/{{ ansible_fqdn }}_key.pem"
delegate_to: localhost
run_once: yes
- name: "Localhost: Generate Certificate Signin request"
community.crypto.openssl_csr:
path: "{{ ssldir }}/{{ ansible_fqdn }}/{{ ansible_fqdn }}_csr.pem"
privatekey_path: "{{ ssldir }}/{{ ansible_fqdn }}/{{ ansible_fqdn }}_key.pem"
country_name: "{{ main_dn_fields.C }}"
state_or_province_name: "{{ main_dn_fields.ST }}"
locality_name: "{{ main_dn_fields.L }}"
organization_name: "{{ main_dn_fields.O }}"
organizational_unit_name: "{{ main_dn_fields.OU }}"
common_name: "{{ main_dn_fields.CN }}"
key_usage:
- digitalSignature
- nonRepudiation
- keyEncipherment
- dataEncipherment
extended_key_usage:
- serverAuth
- clientAuth
- codeSigning
- emailProtection
subject_alt_name:
- "DNS:{{ main_dn_fields.CN }}"
- "DNS:{{ ansible_fqdn }}"
- "IP:{{ ansible_all_ipv4_addresses[0] }}"
- "IP:{{ ansible_all_ipv4_addresses[1] }}"
basicConstraints:
- CA:FALSE
delegate_to: localhost
run_once: yes
|
⚠️ S’assurer que les nom DNS et les ips utilisés dans le CSR sont bien connus du clusteur IDM.
Faire signer le CSR par l’IDM#
$ ipa cert-request --principal=HTTP/satellite.gnali.lab --add files/satellite.gnali.lab/satellite.gnali.lab_csr.pem --certificate-out files/satellite.gnali.lab/satellite.gnali.lab.pem
Vérifier que le nouveau certificat a bien été généré avec les nouvelles dates
$ openssl x509 -noout -dates -in files/satellite.gnali.lab/satellite.gnali.lab.pem
notBefore=Mar 2 14:56:05 2026 GMT
notAfter=Mar 2 14:56:05 2028 GMT
Mettre à jour le certificat sur le Satellite#
$ ansible-playbook playbook/update_satellite_ssl_certs.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
| - name: Update Satellite with Corporate signed certificate
hosts: satellite
become: true
tasks:
- name: Create certificate directory
ansible.builtin.file:
path: "/root/satellite_cert/"
state: directory
- name: Copy Satellite Certificate
ansible.builtin.copy:
src: "{{ ssldir }}/{{ ansible_fqdn }}/{{ item }}"
dest: "/root/satellite_cert/{{ item }}"
with_items:
- "{{ ansible_fqdn }}_key.pem"
- "{{ main_dn_fields.CN }}.pem"
- name: Create CA chain bundle
ansible.builtin.assemble:
remote_src: no
src: "{{ ssldir }}/root_ca"
dest: /root/satellite_cert/ca_cert_bundle.pem
- name: "Update Certificates"
include_role:
name: redhat.satellite_operations.installer
vars:
satellite_installer_scenario: satellite
satellite_installer_options:
- '--certs-server-cert "/root/satellite_cert/{{ main_dn_fields.CN }}.pem"'
- '--certs-server-key "/root/satellite_cert/{{ ansible_fqdn }}_key.pem"'
- '--certs-server-ca-cert "/root/satellite_cert/ca_cert_bundle.pem"'
- '--certs-update-server --certs-update-server-ca'
|
Renouveller le certificat des capsules.#
Il est aussi fort probable qu’au même moment ou un peu plus tard nous ayons besoin de renouveller le certificat des capsules.
Générer le csr#
$ ansible-playbook playbook/generate_csr.yaml -e "host=capsule.gnali.lab"
⚠️ S’assurer que les nom DNS et les ips utilisés dans le CSR sont bien connus du clusteur IDM.
Créer les services et hosts s’ils ne sont pas présent dans l’IDM#
$ ipa service-add HTTP/capsule.gnali.lab
$ ipa host-add lb.gnali.lab --force
$ ipa service-add HTTP/lb.gnali.lab --force
$ ipa service-add-host HTTP/lb.gnali.lab --host capsule.gnali.lab #1
#1 Ajouter autant de --host que de capsule servit par le load-balancer
Faire signer le CSR par l’IDM#
$ ipa cert-request --principal=HTTP/lb.gnali.lab --add files/capsule.gnali.lab/capsule.gnali.lab_csr.pem --certificate-out files/capsule.gnali.lab/capsule.gnali.lab.pem
Vérifier que le nouveau certificat a bien été généré avec les nouvelles dates
$ openssl x509 -noout -dates -in files/capsule.gnali.lab/capsule.gnali.lab.pem
notBefore=Mar 3 08:15:37 2026 GMT
notAfter=Mar 3 08:15:37 2028 GMT
Mettre à jour le certificat sur la capsule#
$ ansible-playbook playbook/update_capsule_ssl_certs.yaml -e "host=capsule.gnali.lab"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
| ---
- name: Update Capsule with Corporate signed certificate
hosts: "{{ host }}"
become: true
pre_tasks:
- name: Create certificate directory
ansible.builtin.file:
path: "/root/{{ host }}_cert/"
state: directory
delegate_to: satellite
- name: Copy Capsule Certificate
ansible.builtin.copy:
src: "{{ ssldir }}/{{ ansible_fqdn }}/{{ item }}"
dest: "/root/{{ host }}_cert/{{ item }}"
with_items:
- "{{ ansible_fqdn }}_key.pem"
- "{{ ansible_fqdn }}.pem"
delegate_to: satellite
- name: Create CA chain bundle
ansible.builtin.assemble:
remote_src: no
src: "{{ ssldir }}/root_ca"
dest: /root/{{ host }}_cert/ca_cert_bundle.pem
delegate_to: satellite
roles:
- role: redhat.satellite_operations.capsule_certs_generate
vars:
satellite_capsule_certs_generate_fqdn: "{{ host }}"
satellite_capsule_certs_generate_options:
- '--foreman-proxy-cname {{ main_dn_fields.CN }}'
- '--server-ca-cert /root/{{ host }}_cert/ca_cert_bundle.pem'
- '--server-cert /root/{{ host }}_cert/{{ ansible_fqdn }}.pem'
- '--server-key /root/{{ host }}_cert/{{ ansible_fqdn }}_key.pem'
delegate_to: satellite
post_tasks:
- name: Get Satellite answers file
ansible.builtin.slurp:
src: /etc/foreman-installer/scenarios.d/satellite-answers.yaml
register: answers_output
delegate_to: satellite
- name: Parse Satellite answers file
ansible.builtin.set_fact:
satellite_answers: "{{ answers_output['content'] | b64decode | from_yaml }}"
- name: Fetch Capsule Certs tarball from Satellite
ansible.builtin.fetch:
src: "/root/{{ host }}.tar.gz"
dest: "{{ ssldir }}/{{ ansible_fqdn }}/{{ host }}.tar.gz"
flat: yes
run_once: yes
delegate_to: satellite
- name: Copy Capsule Certs tarball to Capsule
ansible.builtin.copy:
src: "{{ ssldir }}/{{ ansible_fqdn }}/{{ host }}.tar.gz"
dest: "/root/{{ host }}.tar.gz"
- name: "Update Certificates"
include_role:
name: redhat.satellite_operations.installer
vars:
satellite_installer_scenario: capsule
satellite_installer_options:
- '--certs-cname {{ main_dn_fields.CN }}'
- '--certs-tar-file /root/{{ host }}.tar.gz'
- '--enable-foreman-proxy-plugin-remote-execution-script'
- '--foreman-proxy-foreman-base-url https://{{ hostvars[groups["satellite"][0]].main_dn_fields.CN }}'
- '--foreman-proxy-oauth-consumer-key {{ satellite_answers.foreman.oauth_consumer_key }}'
- '--foreman-proxy-oauth-consumer-secret {{ satellite_answers.foreman.oauth_consumer_secret }}'
- '--foreman-proxy-trusted-hosts {{ hostvars[groups["satellite"][0]].main_dn_fields.CN }}'
- '--foreman-proxy-trusted-hosts {{ host }}'
|
Inventory#
A toute fin utile l’inventory ansible ressemble à ca:
inventory/host_vars/satellite.gnali.lab.yaml
inventory/host_vars/capsule.gnali.lab.yaml
inventory/hosts.yaml
inventory/hosts.yaml
1
2
3
4
5
6
7
8
9
10
11
| ---
all:
children:
satellite:
hosts:
satellite.gnali.lab:
ansible_host: xxx.xxx.xxx.xxx
capsule:
hosts:
capsule.gnali.lab:
ansible_host: xxx.xxx.xxx.xxx
|
inventory/host_vars/satellite.gnali.lab.yaml
1
2
3
4
5
6
7
8
9
| main_dn_fields:
CN: "satellite.gnali.lab"
OU: "Customer Success"
O: "Red Hat"
ST: "IDF"
L: "Puteaux"
C: "FR"
ssldir: "{{ playbook_dir }}/../files"
|
inventory/host_vars/capsule.gnali.lab.yaml
1
2
3
4
5
6
7
8
9
| main_dn_fields:
CN: "lb.gnali.lab"
OU: "Customer Success"
O: "Red Hat"
ST: "IDF"
L: "Cloud"
C: "FR"
ssldir: "{{ playbook_dir }}/../files"
|