From 5413c4112193f20c92b6874583e8fdd6722817f0 Mon Sep 17 00:00:00 2001 From: Denys Mishchenko Date: Wed, 28 May 2025 11:13:50 +0200 Subject: [PATCH] Temp directory for pki certificates If directory is defined instead of certificate files, haproxy will attempt to treat all files within as a pem bundled certs. And will fail its configuration test. To avoid this we can put generated by pki certificates into a temporary directory and them put only valid bundle file into haproxy_ssl_cert_path. Such approach allows us to put additional certificates to the directory outside of the haproxy_server role and keep the directory clean. This also eliminates the need to list all additional custom certificates and calculated by role ones. Additionally added a cleanup/move of the certs if haproxy_ssl_temp_path set to be different from haproxy_ssl_cert_path which allows a transition from old setup. Change-Id: I3662195cb2248d8841e1525d5e6d86f84ca876d3 --- defaults/main.yml | 1 + handlers/main.yml | 5 ++-- .../pki-temp-certs-path-d63091df0234df2e.yaml | 18 +++++++++++++ tasks/haproxy_pre_install.yml | 26 +++++++++++++++++++ vars/main.yml | 6 ++--- 5 files changed, 51 insertions(+), 5 deletions(-) create mode 100644 releasenotes/notes/pki-temp-certs-path-d63091df0234df2e.yaml diff --git a/defaults/main.yml b/defaults/main.yml index 9db5358..12ea063 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -141,6 +141,7 @@ haproxy_ssl: true haproxy_ssl_all_vips: false haproxy_ssl_dh_param: 2048 haproxy_ssl_cert_path: /etc/haproxy/ssl +haproxy_ssl_temp_path: "{{ haproxy_ssl_cert_path }}" haproxy_ssl_bind_options: "ssl-min-ver TLSv1.2 prefer-client-ciphers" haproxy_ssl_server_options: "ssl-min-ver TLSv1.2" # TLS v1.2 and below diff --git a/handlers/main.yml b/handlers/main.yml index 07ada1c..c1848bc 100644 --- a/handlers/main.yml +++ b/handlers/main.yml @@ -16,11 +16,12 @@ - name: Regen pem # noqa: no-changed-when ansible.builtin.shell: >- cat {{ item_base_path ~ '.crt' }} $(test -f {{ item_base_path ~ '-ca.crt' }} && - echo {{ item_base_path ~ '-ca.crt' }}) {{ item_base_path ~ '.key' }} > {{ item_base_path ~ '.pem' }} + echo {{ item_base_path ~ '-ca.crt' }}) {{ item_base_path ~ '.key' }} > {{ target_base_path ~ '.pem' }} vars: item_interface: "{{ item['interface'] | default('') }}" item_name: "{{ ('interface' in item and item['interface'] is truthy) | ternary(item['address'] ~ '-' ~ item_interface, item['address']) }}" - item_base_path: "{{ haproxy_ssl_cert_path ~ '/haproxy_' ~ ansible_facts['hostname'] ~ '-' ~ item_name }}" + item_base_path: "{{ haproxy_ssl_temp_path ~ '/haproxy_' ~ ansible_facts['hostname'] ~ '-' ~ item_name }}" + target_base_path: "{{ haproxy_ssl_cert_path ~ '/haproxy_' ~ ansible_facts['hostname'] ~ '-' ~ item_name }}" with_items: "{{ haproxy_vip_binds }}" listen: - haproxy cert installed diff --git a/releasenotes/notes/pki-temp-certs-path-d63091df0234df2e.yaml b/releasenotes/notes/pki-temp-certs-path-d63091df0234df2e.yaml new file mode 100644 index 0000000..c4ceb83 --- /dev/null +++ b/releasenotes/notes/pki-temp-certs-path-d63091df0234df2e.yaml @@ -0,0 +1,18 @@ +--- +features: + - | + If directory is defined instead of certificate files, haproxy will attempt + to treat all files within as a pem bundled certs. And will fail its + configuration test. + To avoid this a new variable haproxy_ssl_temp_path were introduced. When it + is defined certificates from the pki being put into that directory and then + combined into pem in the correct directory. + + Such an approach allows us to put additional certificates to the directory + outside of the haproxy_server role and keep the directory clean. This also + eliminates the need to list all additional custom certificates and sum them + with the ones calculate by this role. + + Additionally added a cleanup/move of the certs if haproxy_ssl_temp_path set + to be different from haproxy_ssl_cert_path which allows a transition from + old setup. diff --git a/tasks/haproxy_pre_install.yml b/tasks/haproxy_pre_install.yml index d8bfa47..b184115 100644 --- a/tasks/haproxy_pre_install.yml +++ b/tasks/haproxy_pre_install.yml @@ -53,6 +53,32 @@ with_items: - /etc/haproxy/conf.d - "{{ haproxy_ssl_cert_path }}" + - "{{ haproxy_ssl_temp_path }}" + +- name: Cleanup haproxy_ssl_cert_path if temp_path is used + when: "haproxy_ssl_cert_path != haproxy_ssl_temp_path" + block: + - name: Find crt and key files in the cert_path + ansible.builtin.find: + paths: "{{ haproxy_ssl_cert_path }}" + patterns: '*.crt,*.key' + register: old_certs + + - name: Copy cert files to the temp_path + vars: + filename: "{{ item | basename }}" + ansible.builtin.copy: + remote_src: true + src: "{{ item }}" + dest: "{{ [haproxy_ssl_temp_path, filename] | path_join }}" + mode: "0644" + loop: "{{ old_certs['files'] | map(attribute='path') }}" + + - name: Remove file from the old place + ansible.builtin.file: + path: "{{ item }}" + state: absent + loop: "{{ old_certs['files'] | map(attribute='path') }}" - name: Copy static files ansible.builtin.copy: diff --git a/vars/main.yml b/vars/main.yml index ccc3f67..26a3867 100644 --- a/vars/main.yml +++ b/vars/main.yml @@ -63,7 +63,7 @@ _haproxy_pki_install_certificates: | {% set _ = _pki_install.append( { 'src': haproxy_user_ssl_cert | default(haproxy_pki_certs_path ~ _cert_basename ~ '.crt'), - 'dest': haproxy_ssl_cert_path ~ _cert_basename ~ '.crt', + 'dest': haproxy_ssl_temp_path ~ _cert_basename ~ '.crt', 'owner': 'root', 'group': 'root', 'mode': '0644' @@ -73,7 +73,7 @@ _haproxy_pki_install_certificates: | {% set _ = _pki_install.append( { 'src': haproxy_user_ssl_key | default(haproxy_pki_keys_path ~ _cert_basename ~ '.key.pem'), - 'dest': haproxy_ssl_cert_path ~ _cert_basename ~ '.key', + 'dest': haproxy_ssl_temp_path ~ _cert_basename ~ '.key', 'owner': 'root', 'group': 'root', 'mode': '0644' @@ -85,7 +85,7 @@ _haproxy_pki_install_certificates: | {% set _ = _pki_install.append( { 'src': haproxy_user_ssl_ca_cert | default(haproxy_pki_intermediate_cert_path), - 'dest': haproxy_ssl_cert_path ~ _cert_basename ~ '-ca.crt', + 'dest': haproxy_ssl_temp_path ~ _cert_basename ~ '-ca.crt', 'owner': 'root', 'group': 'root', 'mode': '0644'