From 0aed35fbcef6919a78c8dac7aef538ef21bb9466 Mon Sep 17 00:00:00 2001 From: Vitaliy Kukharik Date: Wed, 18 Dec 2024 13:21:04 +0500 Subject: [PATCH] tls_certificate role improvements --- automation/deploy_pgcluster.yml | 3 ++ automation/roles/pgbouncer/tasks/main.yml | 11 ----- .../roles/tls_certificate/tasks/main.yml | 44 +++++++++++-------- automation/vars/main.yml | 17 ++++--- 4 files changed, 40 insertions(+), 35 deletions(-) diff --git a/automation/deploy_pgcluster.yml b/automation/deploy_pgcluster.yml index 0968f1fa6..cf2aed8b8 100644 --- a/automation/deploy_pgcluster.yml +++ b/automation/deploy_pgcluster.yml @@ -356,6 +356,9 @@ - role: cron + - role: tls_certificate + when: tls_cert_generate|bool + - role: pgbouncer when: pgbouncer_install|bool diff --git a/automation/roles/pgbouncer/tasks/main.yml b/automation/roles/pgbouncer/tasks/main.yml index 1d962c494..cd2fb08fe 100644 --- a/automation/roles/pgbouncer/tasks/main.yml +++ b/automation/roles/pgbouncer/tasks/main.yml @@ -124,17 +124,6 @@ label: "{{ 'pgbouncer' if idx == 0 else 'pgbouncer-%d' % (idx + 1) }}" tags: pgbouncer_logrotate, pgbouncer -- name: Generate TLS certificate... - ansible.builtin.import_role: - name: tls_certificate - tasks_from: main - vars: - tls_title: "PostgreSQL & PGBouncer" - tls_privatekey_path: "{{ pgbouncer_conf_dir }}/server.key" - tls_cert_path: "{{ pgbouncer_conf_dir }}/server.crt" - tls_owner: "postgres" - when: (pgbouncer_server_tls_sslmode | default('disable') != 'disable') or ((postgresql_parameters | selectattr('option', 'equalto', 'ssl') | map(attribute='value') | first | default('off')) == 'on') - - name: Configure pgbouncer.ini ansible.builtin.template: src: templates/pgbouncer.ini.j2 diff --git a/automation/roles/tls_certificate/tasks/main.yml b/automation/roles/tls_certificate/tasks/main.yml index 02e634d73..135af83d2 100644 --- a/automation/roles/tls_certificate/tasks/main.yml +++ b/automation/roles/tls_certificate/tasks/main.yml @@ -1,22 +1,30 @@ --- -- name: Generate private TLS key for {{ tls_title }} - community.crypto.openssl_privatekey: - path: "{{ tls_privatekey_path }}" - size: "4096" - -- name: Set the owner of the private TLS key {{ tls_privatekey_path }} to {{ tls_owner }} +- name: "Ensure TLS directories exist" ansible.builtin.file: - path: "{{ tls_privatekey_path }}" - owner: "{{ tls_owner }}" - group: "{{ tls_owner }}" - mode: "0400" + path: "{{ item }}" + state: directory + owner: "{{ tls_owner | default('postgres') }}" + group: "{{ tls_owner | default('postgres') }}" + mode: "0750" + loop: + - "{{ tls_privatekey_path | default('/etc/tls/server.key') | dirname }}" + - "{{ tls_cert_path | default('/etc/tls/server.crt') | dirname }}" + +- name: "Generate private TLS key {{ tls_privatekey_path | default('/etc/tls/server.key') }}" + community.crypto.openssl_privatekey: + path: "{{ tls_privatekey_path | default('/etc/tls/server.key') }}" + owner: "{{ tls_owner | default('postgres') }}" + group: "{{ tls_owner | default('postgres') }}" + mode: "{{ tls_privatekey_mode | default('0400') }}" + size: "{{ tls_privatekey_size | default(4096) }}" + type: "{{ tls_privatekey_type | default('RSA') }}" -- name: Generate self-signed TLS certificate for {{ tls_title }} +- name: "Generate self-signed TLS certificate {{ tls_cert_path | default('/etc/tls/server.crt') }}" community.crypto.x509_certificate: - path: "{{ tls_cert_path }}" - privatekey_path: "{{ tls_privatekey_path }}" - owner: "{{ tls_owner }}" - group: "{{ tls_owner }}" - mode: "0644" - provider: selfsigned - entrust_not_after: "+1000d" + path: "{{ tls_cert_path | default('/etc/tls/server.crt') }}" + privatekey_path: "{{ tls_privatekey_path | default('/etc/tls/server.key') }}" + owner: "{{ tls_owner | default('postgres') }}" + group: "{{ tls_owner | default('postgres') }}" + mode: "{{ tls_cert_mode | default('0644') }}" + provider: "{{ tls_cert_provider | default('selfsigned') }}" + entrust_not_after: "{{ tls_cert_entrust_not_after | default('+3650d') }}" diff --git a/automation/vars/main.yml b/automation/vars/main.yml index a2a5ca04b..cddb53db6 100644 --- a/automation/vars/main.yml +++ b/automation/vars/main.yml @@ -174,6 +174,11 @@ consul_services: # - { http: "http://{{ inventory_hostname }}:{{ patroni_restapi_port }}/async?lag={{ patroni_maximum_lag_on_replica }}", interval: "2s" } # - { args: ["systemctl", "status", "pgbouncer"], interval: "5s" } +# TLS certificate (for PostgreSQL & PGBouncer) +tls_cert_generate: true +tls_cert_path: "{{ postgresql_home_dir }}/tls/server.crt" +tls_privatekey_path: "{{ postgresql_home_dir }}/tls/server.key" +tls_owner: "postgres" # PostgreSQL variables postgresql_version: 17 @@ -236,8 +241,8 @@ postgresql_parameters: - { option: "superuser_reserved_connections", value: "5" } - { option: "password_encryption", value: "{{ postgresql_password_encryption_algorithm }}" } - { option: "ssl", value: "on"} - - { option: "ssl_cert_file", value: "{{ pgbouncer_conf_dir }}/server.crt"} - - { option: "ssl_key_file", value: "{{ pgbouncer_conf_dir }}/server.key"} + - { option: "ssl_cert_file", value: "{{ tls_cert_path }}"} + - { option: "ssl_key_file", value: "{{ tls_privatekey_path }}"} - { option: "ssl_min_protocol_version", value: "TLSv1.2"} - { option: "max_locks_per_transaction", value: "512" } - { option: "max_prepared_transactions", value: "0" } @@ -371,16 +376,16 @@ pgbouncer_auth_username: pgbouncer # user who can query the database via the use pgbouncer_auth_password: "" # If not defined, a password will be generated automatically during deployment pgbouncer_auth_dbname: "postgres" pgbouncer_client_tls_sslmode: "require" -pgbouncer_client_tls_key_file: "{{ pgbouncer_conf_dir }}/server.key" -pgbouncer_client_tls_cert_file: "{{ pgbouncer_conf_dir }}/server.crt" +pgbouncer_client_tls_key_file: "{{ tls_privatekey_path }}" +pgbouncer_client_tls_cert_file: "{{ tls_cert_path }}" pgbouncer_client_tls_ca_file: "" pgbouncer_client_tls_protocols: "secure" # allowed values: tlsv1.0, tlsv1.1, tlsv1.2, tlsv1.3, all, secure (tlsv1.2,tlsv1.3) pgbouncer_client_tls_ciphers: "secure" # allowed values: default, secure, fast, normal, all (not recommended) pgbouncer_server_tls_sslmode: "require" pgbouncer_server_tls_protocols: "secure" pgbouncer_server_tls_ciphers: "secure" -pgbouncer_server_tls_cert_file: "{{ pgbouncer_conf_dir }}/server.crt" -pgbouncer_server_tls_key_file: "{{ pgbouncer_conf_dir }}/server.key" +pgbouncer_server_tls_cert_file: "{{ tls_cert_path }}" +pgbouncer_server_tls_key_file: "{{ tls_privatekey_path }}" pgbouncer_server_tls_ca_file: "" pgbouncer_pools: