diff --git a/molecule/elasticsearch_default/converge.yml b/molecule/elasticsearch_default/converge.yml index 1e836b59..fe22e907 100644 --- a/molecule/elasticsearch_default/converge.yml +++ b/molecule/elasticsearch_default/converge.yml @@ -13,6 +13,10 @@ elasticstack_release: "{{ lookup('env', 'ELASTIC_RELEASE') | int}}" elasticsearch_heap: "1" elasticstack_no_log: false + # Passwords with arbitrary special characters (space, single quote, $, backtick) to test + # that they reach the keystore (stdin) and certutil/openssl (argv) without mangling. + elasticsearch_bootstrap_pw: "Bp'$pa ss`5" + elasticsearch_tls_key_passphrase: "Es'$ke y`6" tasks: - name: Include Elastics repos role ansible.builtin.include_role: diff --git a/molecule/elasticstack_default/converge.yml b/molecule/elasticstack_default/converge.yml index 58119e39..9cb0fa04 100644 --- a/molecule/elasticstack_default/converge.yml +++ b/molecule/elasticstack_default/converge.yml @@ -17,6 +17,14 @@ elasticsearch_heap: "1" elasticstack_full_stack: true elasticstack_no_log: false + # Passphrases with arbitrary special characters (space, single quote, $, backtick) to test + # that they reach certutil/openssl/keystore without shell or shlex mangling. ca_pass and + # cert_pass are global (cert_pass feeds elasticsearch + kibana); logstash and beats have + # their own passphrase variables. + elasticstack_ca_pass: "Ca'$pa ss`1" + elasticstack_cert_pass: "Es'$ce rt`2" + logstash_tls_key_passphrase: "Ls'$pa ss`3" + beats_tls_key_passphrase: "Be'$pa ss`4" logstash_pipeline_unsafe_shutdown: true logstash_redis_password: "{{ lookup('ansible.builtin.password', '/tmp/redispassword', chars=['ascii_letters'], length=15) }}" redis_requirepass: "{{ logstash_redis_password }}" diff --git a/roles/beats/tasks/beats-security.yml b/roles/beats/tasks/beats-security.yml index c2191c32..22bf3f8b 100644 --- a/roles/beats/tasks/beats-security.yml +++ b/roles/beats/tasks/beats-security.yml @@ -121,21 +121,32 @@ - renew_ca - renew_beats_cert +# argv (a list) instead of a folded string: avoids shlex.split() so passphrases with +# arbitrary special characters (spaces, quotes, $, `, ...) are passed literally. - name: Create individual certificates for Beats - ansible.builtin.command: > - /usr/share/elasticsearch/bin/elasticsearch-certutil cert - --days {{ beats_cert_validity_period }} - --ca {{ elasticstack_ca_dir }}/elastic-stack-ca.p12 - --ca-pass {{ elasticstack_ca_pass }} - --name {{ ansible_hostname }} - --ip {{ ansible_default_ipv4.address | default(ansible_all_ipv4_addresses[0]) }} - --dns {{ ansible_hostname }},{{ ansible_fqdn }},{{ inventory_hostname }} - --pass {{ beats_tls_key_passphrase }} - --pem - --out {{ elasticstack_ca_dir }}/{{ ansible_hostname }}-beats.zip - delegate_to: "{{ elasticstack_ca_host }}" - args: + ansible.builtin.command: + argv: + - /usr/share/elasticsearch/bin/elasticsearch-certutil + - cert + - --days + - "{{ beats_cert_validity_period }}" + - --ca + - "{{ elasticstack_ca_dir }}/elastic-stack-ca.p12" + - --ca-pass + - "{{ elasticstack_ca_pass }}" + - --name + - "{{ ansible_hostname }}" + - --ip + - "{{ ansible_default_ipv4.address | default(ansible_all_ipv4_addresses[0]) }}" + - --dns + - "{{ ansible_hostname }},{{ ansible_fqdn }},{{ inventory_hostname }}" + - --pass + - "{{ beats_tls_key_passphrase }}" + - --pem + - --out + - "{{ elasticstack_ca_dir }}/{{ ansible_hostname }}-beats.zip" creates: "{{ elasticstack_ca_dir }}/{{ ansible_hostname }}-beats.zip" + delegate_to: "{{ elasticstack_ca_host }}" tags: - certificates - renew_ca diff --git a/roles/elasticsearch/tasks/elasticsearch-keystore.yml b/roles/elasticsearch/tasks/elasticsearch-keystore.yml index 31481fc8..2735528a 100644 --- a/roles/elasticsearch/tasks/elasticsearch-keystore.yml +++ b/roles/elasticsearch/tasks/elasticsearch-keystore.yml @@ -10,12 +10,14 @@ changed_when: false register: elasticsearch_keystore -- name: Set bootstrap password # noqa: risky-shell-pipe - ansible.builtin.shell: > - if test -n "$(ps -p $$ | grep bash)"; then set -o pipefail; fi; - echo "{{ elasticsearch_bootstrap_pw }}" | - /usr/share/elasticsearch/bin/elasticsearch-keystore - add -x 'bootstrap.password' +- name: Set bootstrap password + ansible.builtin.command: + argv: + - /usr/share/elasticsearch/bin/elasticsearch-keystore + - add + - -x + - bootstrap.password + stdin: "{{ elasticsearch_bootstrap_pw }}" when: "'bootstrap.password' not in elasticsearch_keystore.stdout_lines" changed_when: false no_log: true @@ -23,11 +25,12 @@ - Restart Elasticsearch ignore_errors: "{{ ansible_check_mode }}" -- name: Get xpack.security.http.ssl.keystore.secure_password # noqa: risky-shell-pipe - ansible.builtin.shell: > - if test -n "$(ps -p $$ | grep bash)"; then set -o pipefail; fi; - /usr/share/elasticsearch/bin/elasticsearch-keystore - show 'xpack.security.http.ssl.keystore.secure_password' +- name: Get xpack.security.http.ssl.keystore.secure_password + ansible.builtin.command: + argv: + - /usr/share/elasticsearch/bin/elasticsearch-keystore + - show + - xpack.security.http.ssl.keystore.secure_password when: - "'xpack.security.http.ssl.keystore.secure_password' in elasticsearch_keystore.stdout_lines" - elasticsearch_http_security @@ -36,12 +39,15 @@ no_log: true changed_when: false -- name: Set xpack.security.http.ssl.keystore.secure_password # noqa: risky-shell-pipe - ansible.builtin.shell: > - if test -n "$(ps -p $$ | grep bash)"; then set -o pipefail; fi; - echo "{{ elasticsearch_tls_key_passphrase }}" | - /usr/share/elasticsearch/bin/elasticsearch-keystore - add -f -x 'xpack.security.http.ssl.keystore.secure_password' +- name: Set xpack.security.http.ssl.keystore.secure_password + ansible.builtin.command: + argv: + - /usr/share/elasticsearch/bin/elasticsearch-keystore + - add + - -f + - -x + - xpack.security.http.ssl.keystore.secure_password + stdin: "{{ elasticsearch_tls_key_passphrase }}" changed_when: false no_log: true when: @@ -50,11 +56,12 @@ notify: - Restart Elasticsearch -- name: Remove xpack.security.http.ssl.keystore.secure_password # noqa: risky-shell-pipe - ansible.builtin.shell: > - if test -n "$(ps -p $$ | grep bash)"; then set -o pipefail; fi; - /usr/share/elasticsearch/bin/elasticsearch-keystore - remove 'xpack.security.http.ssl.keystore.secure_password' +- name: Remove xpack.security.http.ssl.keystore.secure_password + ansible.builtin.command: + argv: + - /usr/share/elasticsearch/bin/elasticsearch-keystore + - remove + - xpack.security.http.ssl.keystore.secure_password changed_when: false no_log: true when: @@ -63,11 +70,12 @@ notify: - Restart Elasticsearch -- name: Get xpack.security.http.ssl.truststore.secure_password # noqa: risky-shell-pipe - ansible.builtin.shell: > - if test -n "$(ps -p $$ | grep bash)"; then set -o pipefail; fi; - /usr/share/elasticsearch/bin/elasticsearch-keystore - show 'xpack.security.http.ssl.truststore.secure_password' +- name: Get xpack.security.http.ssl.truststore.secure_password + ansible.builtin.command: + argv: + - /usr/share/elasticsearch/bin/elasticsearch-keystore + - show + - xpack.security.http.ssl.truststore.secure_password when: - "'xpack.security.http.ssl.truststore.secure_password' in elasticsearch_keystore.stdout_lines" - elasticsearch_http_security @@ -76,12 +84,15 @@ no_log: true changed_when: false -- name: Set xpack.security.http.ssl.truststore.secure_password # noqa: risky-shell-pipe - ansible.builtin.shell: > - if test -n "$(ps -p $$ | grep bash)"; then set -o pipefail; fi; - echo "{{ elasticsearch_tls_key_passphrase }}" | - /usr/share/elasticsearch/bin/elasticsearch-keystore - add -f -x 'xpack.security.http.ssl.truststore.secure_password' +- name: Set xpack.security.http.ssl.truststore.secure_password + ansible.builtin.command: + argv: + - /usr/share/elasticsearch/bin/elasticsearch-keystore + - add + - -f + - -x + - xpack.security.http.ssl.truststore.secure_password + stdin: "{{ elasticsearch_tls_key_passphrase }}" changed_when: false no_log: true when: @@ -90,11 +101,12 @@ notify: - Restart Elasticsearch -- name: Remove xpack.security.http.ssl.truststore.secure_password # noqa: risky-shell-pipe - ansible.builtin.shell: > - if test -n "$(ps -p $$ | grep bash)"; then set -o pipefail; fi; - /usr/share/elasticsearch/bin/elasticsearch-keystore - remove 'xpack.security.http.ssl.truststore.secure_password' +- name: Remove xpack.security.http.ssl.truststore.secure_password + ansible.builtin.command: + argv: + - /usr/share/elasticsearch/bin/elasticsearch-keystore + - remove + - xpack.security.http.ssl.truststore.secure_password changed_when: false no_log: true when: @@ -103,11 +115,12 @@ notify: - Restart Elasticsearch -- name: Get xpack.security.transport.ssl.keystore.secure_password # noqa: risky-shell-pipe - ansible.builtin.shell: > - if test -n "$(ps -p $$ | grep bash)"; then set -o pipefail; fi; - /usr/share/elasticsearch/bin/elasticsearch-keystore - show 'xpack.security.transport.ssl.keystore.secure_password' +- name: Get xpack.security.transport.ssl.keystore.secure_password + ansible.builtin.command: + argv: + - /usr/share/elasticsearch/bin/elasticsearch-keystore + - show + - xpack.security.transport.ssl.keystore.secure_password when: - "'xpack.security.transport.ssl.keystore.secure_password' in elasticsearch_keystore.stdout_lines" - elasticsearch_security @@ -116,12 +129,15 @@ no_log: true changed_when: false -- name: Set xpack.security.transport.ssl.keystore.secure_password # noqa: risky-shell-pipe - ansible.builtin.shell: > - if test -n "$(ps -p $$ | grep bash)"; then set -o pipefail; fi; - echo "{{ elasticsearch_tls_key_passphrase }}" | - /usr/share/elasticsearch/bin/elasticsearch-keystore - add -f -x 'xpack.security.transport.ssl.keystore.secure_password' +- name: Set xpack.security.transport.ssl.keystore.secure_password + ansible.builtin.command: + argv: + - /usr/share/elasticsearch/bin/elasticsearch-keystore + - add + - -f + - -x + - xpack.security.transport.ssl.keystore.secure_password + stdin: "{{ elasticsearch_tls_key_passphrase }}" changed_when: false no_log: true when: @@ -130,11 +146,12 @@ notify: - Restart Elasticsearch -- name: Remove xpack.security.transport.ssl.keystore.secure_password # noqa: risky-shell-pipe - ansible.builtin.shell: > - if test -n "$(ps -p $$ | grep bash)"; then set -o pipefail; fi; - /usr/share/elasticsearch/bin/elasticsearch-keystore - remove 'xpack.security.transport.ssl.keystore.secure_password' +- name: Remove xpack.security.transport.ssl.keystore.secure_password + ansible.builtin.command: + argv: + - /usr/share/elasticsearch/bin/elasticsearch-keystore + - remove + - xpack.security.transport.ssl.keystore.secure_password changed_when: false no_log: true when: @@ -143,11 +160,12 @@ notify: - Restart Elasticsearch -- name: Get xpack.security.transport.ssl.truststore.secure_password # noqa: risky-shell-pipe - ansible.builtin.shell: > - if test -n "$(ps -p $$ | grep bash)"; then set -o pipefail; fi; - /usr/share/elasticsearch/bin/elasticsearch-keystore - show 'xpack.security.transport.ssl.truststore.secure_password' +- name: Get xpack.security.transport.ssl.truststore.secure_password + ansible.builtin.command: + argv: + - /usr/share/elasticsearch/bin/elasticsearch-keystore + - show + - xpack.security.transport.ssl.truststore.secure_password when: - "'xpack.security.transport.ssl.truststore.secure_password' in elasticsearch_keystore.stdout_lines" - elasticsearch_security @@ -156,12 +174,15 @@ no_log: true changed_when: false -- name: Set xpack.security.transport.ssl.truststore.secure_password # noqa: risky-shell-pipe - ansible.builtin.shell: > - if test -n "$(ps -p $$ | grep bash)"; then set -o pipefail; fi; - echo "{{ elasticsearch_tls_key_passphrase }}" | - /usr/share/elasticsearch/bin/elasticsearch-keystore - add -f -x 'xpack.security.transport.ssl.truststore.secure_password' +- name: Set xpack.security.transport.ssl.truststore.secure_password + ansible.builtin.command: + argv: + - /usr/share/elasticsearch/bin/elasticsearch-keystore + - add + - -f + - -x + - xpack.security.transport.ssl.truststore.secure_password + stdin: "{{ elasticsearch_tls_key_passphrase }}" changed_when: false no_log: true when: @@ -170,11 +191,12 @@ notify: - Restart Elasticsearch -- name: Remove xpack.security.transport.ssl.truststore.secure_password # noqa: risky-shell-pipe - ansible.builtin.shell: > - if test -n "$(ps -p $$ | grep bash)"; then set -o pipefail; fi; - /usr/share/elasticsearch/bin/elasticsearch-keystore - remove 'xpack.security.transport.ssl.truststore.secure_password' +- name: Remove xpack.security.transport.ssl.truststore.secure_password + ansible.builtin.command: + argv: + - /usr/share/elasticsearch/bin/elasticsearch-keystore + - remove + - xpack.security.transport.ssl.truststore.secure_password changed_when: false no_log: true when: diff --git a/roles/elasticsearch/tasks/elasticsearch-security.yml b/roles/elasticsearch/tasks/elasticsearch-security.yml index 69c185c6..9f62e517 100644 --- a/roles/elasticsearch/tasks/elasticsearch-security.yml +++ b/roles/elasticsearch/tasks/elasticsearch-security.yml @@ -228,40 +228,65 @@ - renew_ca - renew_es_cert block: + # Pass passphrases via argv (a list), not a folded shell string. A string command is + # tokenized by shlex.split() (shell-like word splitting and quote parsing), which mangles + # passphrases containing spaces or quotes. With argv every element is handed to the binary + # literally — no shell, no shlex — so arbitrary special characters work. - name: Configure ca on elasticstack_ca_host - ansible.builtin.command: > - /usr/share/elasticsearch/bin/elasticsearch-certutil ca - --ca-dn {{ elasticstack_ca_name }} - --days {{ elasticstack_ca_validity_period }} - --pass {{ elasticstack_ca_pass }} - --out {{ elasticstack_ca_dir }}/elastic-stack-ca.p12 - --silent - args: + ansible.builtin.command: + argv: + - /usr/share/elasticsearch/bin/elasticsearch-certutil + - ca + - --ca-dn + - "{{ elasticstack_ca_name }}" + - --days + - "{{ elasticstack_ca_validity_period }}" + - --pass + - "{{ elasticstack_ca_pass }}" + - --out + - "{{ elasticstack_ca_dir }}/elastic-stack-ca.p12" + - --silent creates: "{{ elasticstack_ca_dir }}/elastic-stack-ca.p12" no_log: "{{ elasticstack_no_log }}" - name: Create node certificates on elasticstack_ca_host - ansible.builtin.command: > - /usr/share/elasticsearch/bin/elasticsearch-certutil cert - --ca {{ elasticstack_ca_dir }}/elastic-stack-ca.p12 - --days {{ elasticsearch_cert_validity_period }} - --ca-pass {{ elasticstack_ca_pass }} - --name {{ hostvars[item].ansible_hostname }} - --ip {{ hostvars[item].ansible_default_ipv4.address | default(hostvars[item].ansible_all_ipv4_addresses[0]) }} - --dns {{ hostvars[item].ansible_hostname }},{{ hostvars[item].ansible_fqdn }},{{ hostvars[item].inventory_hostname }} - --pass {{ (hostvars[item].elasticsearch_tls_key_passphrase is defined) | ternary(hostvars[item].elasticsearch_tls_key_passphrase, elasticsearch_tls_key_passphrase) }} - --out {{ elasticstack_ca_dir }}/{{ hostvars[item].ansible_hostname }}.p12 + ansible.builtin.command: + argv: + - /usr/share/elasticsearch/bin/elasticsearch-certutil + - cert + - --ca + - "{{ elasticstack_ca_dir }}/elastic-stack-ca.p12" + - --days + - "{{ elasticsearch_cert_validity_period }}" + - --ca-pass + - "{{ elasticstack_ca_pass }}" + - --name + - "{{ hostvars[item].ansible_hostname }}" + - --ip + - "{{ hostvars[item].ansible_default_ipv4.address | default(hostvars[item].ansible_all_ipv4_addresses[0]) }}" + - --dns + - "{{ hostvars[item].ansible_hostname }},{{ hostvars[item].ansible_fqdn }},{{ hostvars[item].inventory_hostname }}" + - --pass + - "{{ (hostvars[item].elasticsearch_tls_key_passphrase is defined) | ternary(hostvars[item].elasticsearch_tls_key_passphrase, elasticsearch_tls_key_passphrase) }}" + - --out + - "{{ elasticstack_ca_dir }}/{{ hostvars[item].ansible_hostname }}.p12" + creates: "{{ elasticstack_ca_dir }}/{{ hostvars[item].ansible_hostname }}.p12" loop: "{{ groups[elasticstack_elasticsearch_group_name] }}" no_log: "{{ elasticstack_no_log }}" - args: - creates: "{{ elasticstack_ca_dir }}/{{ hostvars[item].ansible_hostname }}.p12" - name: Extract CA certificate on elasticstack_ca host - ansible.builtin.command: > - openssl pkcs12 -in {{ elasticstack_ca_dir }}/{{ ansible_hostname }}.p12 - -cacerts -nokeys -out {{ elasticstack_ca_dir }}/ca.crt - -password pass:{{ elasticsearch_tls_key_passphrase }} - args: + ansible.builtin.command: + argv: + - openssl + - pkcs12 + - -in + - "{{ elasticstack_ca_dir }}/{{ ansible_hostname }}.p12" + - -cacerts + - -nokeys + - -out + - "{{ elasticstack_ca_dir }}/ca.crt" + - -password + - "pass:{{ elasticsearch_tls_key_passphrase }}" creates: "{{ elasticstack_ca_dir }}/ca.crt" no_log: "{{ elasticstack_no_log }}" diff --git a/roles/kibana/tasks/kibana-security.yml b/roles/kibana/tasks/kibana-security.yml index db4479ed..d5a32209 100644 --- a/roles/kibana/tasks/kibana-security.yml +++ b/roles/kibana/tasks/kibana-security.yml @@ -163,21 +163,32 @@ - renew_ca - renew_kibana_cert +# argv (a list) instead of a folded string: avoids shlex.split() so passphrases with +# arbitrary special characters (spaces, quotes, $, `, ...) are passed literally. - name: Create individual certificates for Kibana - ansible.builtin.command: > - /usr/share/elasticsearch/bin/elasticsearch-certutil cert - --days {{ kibana_cert_validity_period }} - --ca {{ elasticstack_ca_dir }}/elastic-stack-ca.p12 - --ca-pass {{ elasticstack_ca_pass }} - --name {{ ansible_hostname }} - --ip {{ ansible_default_ipv4.address | default(ansible_all_ipv4_addresses[0]) }} - --dns {{ ansible_hostname }},{{ ansible_fqdn }},{{ inventory_hostname }} - --pass {{ kibana_tls_key_passphrase }} - --out {{ elasticstack_ca_dir }}/{{ ansible_hostname }}-kibana.p12 + ansible.builtin.command: + argv: + - /usr/share/elasticsearch/bin/elasticsearch-certutil + - cert + - --days + - "{{ kibana_cert_validity_period }}" + - --ca + - "{{ elasticstack_ca_dir }}/elastic-stack-ca.p12" + - --ca-pass + - "{{ elasticstack_ca_pass }}" + - --name + - "{{ ansible_hostname }}" + - --ip + - "{{ ansible_default_ipv4.address | default(ansible_all_ipv4_addresses[0]) }}" + - --dns + - "{{ ansible_hostname }},{{ ansible_fqdn }},{{ inventory_hostname }}" + - --pass + - "{{ kibana_tls_key_passphrase }}" + - --out + - "{{ elasticstack_ca_dir }}/{{ ansible_hostname }}-kibana.p12" + creates: "{{ elasticstack_ca_dir }}/{{ ansible_hostname }}-kibana.p12" delegate_to: "{{ elasticstack_ca_host }}" no_log: "{{ elasticstack_no_log }}" - args: - creates: "{{ elasticstack_ca_dir }}/{{ ansible_hostname }}-kibana.p12" tags: - certificates - renew_ca diff --git a/roles/logstash/tasks/logstash-security.yml b/roles/logstash/tasks/logstash-security.yml index 7e97208f..4a74a9d6 100644 --- a/roles/logstash/tasks/logstash-security.yml +++ b/roles/logstash/tasks/logstash-security.yml @@ -154,21 +154,32 @@ state: absent when: logstash_move_cert_zip_ansible_controller.changed +# argv (a list) instead of a folded string: avoids shlex.split() so passphrases with +# arbitrary special characters (spaces, quotes, $, `, ...) are passed literally. - name: Create individual certificates for Logstash - ansible.builtin.command: > - /usr/share/elasticsearch/bin/elasticsearch-certutil cert - --days {{ logstash_cert_validity_period }} - --ca {{ elasticstack_ca_dir }}/elastic-stack-ca.p12 - --ca-pass {{ elasticstack_ca_pass }} - --name {{ ansible_hostname }} - --ip {{ ansible_default_ipv4.address | default(ansible_all_ipv4_addresses[0]) }} - --dns {{ ansible_hostname }},{{ ansible_fqdn }},{{ inventory_hostname }} - --pass {{ logstash_tls_key_passphrase }} - --out {{ elasticstack_ca_dir }}/{{ ansible_hostname }}-ls.p12 + ansible.builtin.command: + argv: + - /usr/share/elasticsearch/bin/elasticsearch-certutil + - cert + - --days + - "{{ logstash_cert_validity_period }}" + - --ca + - "{{ elasticstack_ca_dir }}/elastic-stack-ca.p12" + - --ca-pass + - "{{ elasticstack_ca_pass }}" + - --name + - "{{ ansible_hostname }}" + - --ip + - "{{ ansible_default_ipv4.address | default(ansible_all_ipv4_addresses[0]) }}" + - --dns + - "{{ ansible_hostname }},{{ ansible_fqdn }},{{ inventory_hostname }}" + - --pass + - "{{ logstash_tls_key_passphrase }}" + - --out + - "{{ elasticstack_ca_dir }}/{{ ansible_hostname }}-ls.p12" + creates: "{{ elasticstack_ca_dir }}/{{ ansible_hostname }}-ls.p12" delegate_to: "{{ elasticstack_ca_host }}" no_log: "{{ elasticstack_no_log }}" - args: - creates: "{{ elasticstack_ca_dir }}/{{ ansible_hostname }}-ls.p12" tags: - certificates - renew_ca @@ -224,21 +235,30 @@ - renew_logstash_cert - name: Create individual PEM certificates for Logstash - ansible.builtin.command: > - /usr/share/elasticsearch/bin/elasticsearch-certutil cert - --days {{ logstash_cert_validity_period }} - --ca {{ elasticstack_ca_dir }}/elastic-stack-ca.p12 - --ca-pass {{ elasticstack_ca_pass }} - --name {{ ansible_hostname }} - --ip {{ ansible_default_ipv4.address }} - --dns {{ ansible_hostname }},{{ ansible_fqdn }},{{ inventory_hostname }} - --pass {{ logstash_tls_key_passphrase }} - --pem - --out {{ elasticstack_ca_dir }}/{{ ansible_hostname }}-ls.zip + ansible.builtin.command: + argv: + - /usr/share/elasticsearch/bin/elasticsearch-certutil + - cert + - --days + - "{{ logstash_cert_validity_period }}" + - --ca + - "{{ elasticstack_ca_dir }}/elastic-stack-ca.p12" + - --ca-pass + - "{{ elasticstack_ca_pass }}" + - --name + - "{{ ansible_hostname }}" + - --ip + - "{{ ansible_default_ipv4.address }}" + - --dns + - "{{ ansible_hostname }},{{ ansible_fqdn }},{{ inventory_hostname }}" + - --pass + - "{{ logstash_tls_key_passphrase }}" + - --pem + - --out + - "{{ elasticstack_ca_dir }}/{{ ansible_hostname }}-ls.zip" + creates: "{{ elasticstack_ca_dir }}/{{ ansible_hostname }}-ls.zip" delegate_to: "{{ elasticstack_ca_host }}" no_log: "{{ elasticstack_no_log }}" - args: - creates: "{{ elasticstack_ca_dir }}/{{ ansible_hostname }}-ls.zip" tags: - certificates - renew_ca @@ -298,14 +318,18 @@ - renew_logstash_cert - name: Create unencrypted Logstash compatible key - ansible.builtin.command: > - openssl pkcs8 - -in {{ logstash_certs_dir }}/{{ inventory_hostname }}.key - -topk8 - -passin pass:{{ logstash_tls_key_passphrase }} - -out {{ logstash_certs_dir }}/{{ inventory_hostname }}-pkcs8.key - -nocrypt - args: + ansible.builtin.command: + argv: + - openssl + - pkcs8 + - -in + - "{{ logstash_certs_dir }}/{{ inventory_hostname }}.key" + - -topk8 + - -passin + - "pass:{{ logstash_tls_key_passphrase }}" + - -out + - "{{ logstash_certs_dir }}/{{ inventory_hostname }}-pkcs8.key" + - -nocrypt creates: "{{ logstash_certs_dir }}/{{ inventory_hostname }}-pkcs8.key" no_log: "{{ elasticstack_no_log }}" tags: