From 9bf495b79c260a91f30c24c760e5662aa85434d4 Mon Sep 17 00:00:00 2001 From: Aman Date: Fri, 17 Aug 2018 09:03:27 -0400 Subject: [PATCH] Fixed overwriting of certs when re-running playbook --- README.md | 8 +++++--- tasks/generate-ca-cert.yaml | 9 +++++++-- tasks/generate-client-cert.yaml | 18 ++++++++++++++---- tasks/generate-server-cert.yaml | 24 +++++++++++++++++------- templates/server-cert-extfile.cnf.j2 | 2 +- 5 files changed, 44 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 94027b5..a87caab 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,10 @@ Generate TLS certificates ========================= -Generates self-signed CA, client and server certificates. Runs locally on control machine. **Note:** Ansible crypto modules do not support self-signed certs, using `shell` command instead as required. +Generates self-signed CA, client and server certificates. Runs locally on control machine. -**WARNING: re-running this role in the same output folder will overwrite any existing certs and keys!** +Notes: +- Will not overwrite any files in output cert dir +- Ansible crypto modules do not support signing certs with own CA yet, using `shell` command instead. Should be resolved in Ansible 2.7 using the [ownca provider](https://github.com/ansible/ansible/commit/b61b113fb9e3fcfcb25f4a8aaabad618e3209ce1). Requirements @@ -37,7 +39,7 @@ Example Playbook - include_vars: vars.yaml - name: Generate certs - import_role: + import_role: name: generate-tls-certs ``` diff --git a/tasks/generate-ca-cert.yaml b/tasks/generate-ca-cert.yaml index 2c21fcc..55819df 100644 --- a/tasks/generate-ca-cert.yaml +++ b/tasks/generate-ca-cert.yaml @@ -8,8 +8,13 @@ - name: Generate self-signed cert for CA local_action: - module: > - shell openssl req -x509 -new -days {{tls_ca_valid_days}} -sha256 -nodes -key {{cert_dir}}/{{tls_ca_key}} -out {{cert_dir}}/{{tls_ca_cert}} + module: | + shell if [ ! -e {{cert_dir}}/{{tls_ca_cert}} ] + then + openssl req -x509 -new -days {{tls_ca_valid_days}} -sha256 -nodes -key {{cert_dir}}/{{tls_ca_key}} -out {{cert_dir}}/{{tls_ca_cert}} \ -subj "{% if tls_ca_country is defined%}/C={{tls_ca_country}}{% endif %}{% if tls_ca_state is defined%}/ST={{tls_ca_state}}{% endif %}{% if tls_ca_locality is defined %}/L={{tls_ca_locality}}{% endif %}{% if tls_ca_organization is defined %}/O={{tls_ca_organization}}{% endif %}{% if tls_ca_organizationalunit is defined %}/OU={{tls_ca_organizationalunit}}{% endif %}/CN={{tls_ca_commonname}}{% if tls_ca_email is defined %}/emailAddress={{tls_ca_email}}{% endif %}" + fi + args: + executable: /bin/bash ignore_errors: true run_once: true diff --git a/tasks/generate-client-cert.yaml b/tasks/generate-client-cert.yaml index 079f1c9..5eb10cc 100644 --- a/tasks/generate-client-cert.yaml +++ b/tasks/generate-client-cert.yaml @@ -10,9 +10,14 @@ - name: Generate CSR and key for client cert local_action: - module: > - shell openssl req -newkey rsa:{{tls_client_key_size}} -nodes -subj "/CN={{tls_client_commonname}}" + module: | + shell if [ ! -e {{cert_dir}}/{{tls_client_csr}} ] + then + openssl req -newkey rsa:{{tls_client_key_size}} -nodes -subj "/CN={{tls_client_commonname}}" \ -keyout "{{cert_dir}}/{{tls_client_key}}" -out "{{cert_dir}}/{{tls_client_csr}}" + fi + args: + executable: /bin/bash ignore_errors: true run_once: true when: generate_client_cert @@ -28,9 +33,14 @@ # @AB TODO: using OpenSSL CA serial file does not always generate unique serial when running playbook against multiple hosts - name: Sign client cert request with CA local_action: - module: > - shell openssl x509 -req -sha256 -days {{tls_client_valid_days}} -CA {{cert_dir}}/{{tls_ca_cert}} -CAkey {{cert_dir}}/{{tls_ca_key}} + module: | + shell if [ ! -e {{cert_dir}}/{{tls_client_cert}} ] + then + openssl x509 -req -sha256 -days {{tls_client_valid_days}} -CA {{cert_dir}}/{{tls_ca_cert}} -CAkey {{cert_dir}}/{{tls_ca_key}} \ -set_serial {{ 999999999 | random }} -in {{cert_dir}}/{{tls_client_csr}} -out {{cert_dir}}/{{tls_client_cert}} -extfile {{cert_dir}}/{{tls_client_extfile}} + fi + args: + executable: /bin/bash ignore_errors: true run_once: true when: generate_client_cert diff --git a/tasks/generate-server-cert.yaml b/tasks/generate-server-cert.yaml index 75c47b3..c35300f 100644 --- a/tasks/generate-server-cert.yaml +++ b/tasks/generate-server-cert.yaml @@ -2,9 +2,14 @@ # Generate server cert - name: Create CSR for server cert local_action: - module: > - shell openssl req -newkey rsa:{{tls_server_key_size}} -nodes -subj "/CN={{inventory_hostname}}" + module: | + shell if [ ! -e {{cert_dir}}/{{inventory_hostname_short}}.csr ] + then + openssl req -newkey rsa:{{tls_server_key_size}} -nodes -subj "/CN={{inventory_hostname}}" \ -keyout "{{cert_dir}}/{{inventory_hostname_short}}.key" -out "{{cert_dir}}/{{inventory_hostname_short}}.csr" + fi + args: + executable: /bin/bash ignore_errors: true when: generate_server_cert @@ -19,10 +24,15 @@ - name: Sign server cert request by CA local_action: - module: > - shell openssl x509 -req -sha256 -days {{tls_server_valid_days}} - -CA "{{cert_dir}}/{{tls_ca_cert}}" -CAkey "{{cert_dir}}/{{tls_ca_key}}" -set_serial {{ 999999999 | random }} - -in "{{cert_dir}}/{{inventory_hostname_short}}.csr" -out "{{cert_dir}}/{{inventory_hostname_short}}.pem" - {% if tls_server_enable_san %}-extfile "{{cert_dir}}/{{inventory_hostname_short}}-extfile.cnf"{% endif %} + module: | + shell if [ ! -e {{cert_dir}}/{{inventory_hostname_short}}.pem ] + then + openssl x509 -req -sha256 -days {{tls_server_valid_days}} \ + -CA "{{cert_dir}}/{{tls_ca_cert}}" -CAkey "{{cert_dir}}/{{tls_ca_key}}" -set_serial {{ 999999999 | random }} \ + -in "{{cert_dir}}/{{inventory_hostname_short}}.csr" -out "{{cert_dir}}/{{inventory_hostname_short}}.pem" {% if tls_server_enable_san %}-extfile "{{cert_dir}}/{{inventory_hostname_short}}-extfile.cnf"{% endif %} + + fi + args: + executable: /bin/bash ignore_errors: true when: generate_server_cert diff --git a/templates/server-cert-extfile.cnf.j2 b/templates/server-cert-extfile.cnf.j2 index ed77463..5647878 100644 --- a/templates/server-cert-extfile.cnf.j2 +++ b/templates/server-cert-extfile.cnf.j2 @@ -1,3 +1,3 @@ -subjectAltName = DNS:{{inventory_hostname}},DNS:{{inventory_hostname_short}},IP:{{(alt_interface_ip is defined) | ternary(alt_interface_ip, ansible_host)}},IP:0.0.0.0,IP:127.0.0.1 +subjectAltName = DNS:{{inventory_hostname}},DNS:{{inventory_hostname_short}},IP:{{(alt_interface_ip is defined) | ternary(alt_interface_ip, ansible_default_ipv4.address)}},IP:0.0.0.0,IP:127.0.0.1 extendedKeyUsage = serverAuth