From 92391f3d5297f7c876bfdc655b6410cdb46d789c Mon Sep 17 00:00:00 2001 From: Blallo Date: Sun, 24 Jan 2021 00:20:24 +0100 Subject: [PATCH 01/10] Update with community.crypto collection modules --- .gitignore | 2 + Vagrantfile | 35 +++++++++ ansible.cfg | 2 + certs/.gitkeep | 0 inventory.yml | 18 +++++ playbook.yml | 5 ++ requirements.yml | 3 + tasks/generate-ca-cert.yaml | 81 +++++++++++++++----- tasks/generate-client-cert.yaml | 129 ++++++++++++++++++++----------- tasks/generate-server-cert.yaml | 132 +++++++++++++++++++++++--------- tasks/main.yml | 31 ++++---- 11 files changed, 323 insertions(+), 115 deletions(-) create mode 100644 .gitignore create mode 100644 Vagrantfile create mode 100644 ansible.cfg create mode 100644 certs/.gitkeep create mode 100644 inventory.yml create mode 100644 playbook.yml create mode 100644 requirements.yml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b7b3dc2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/.vagrant/ +/certs/ diff --git a/Vagrantfile b/Vagrantfile new file mode 100644 index 0000000..3e9258c --- /dev/null +++ b/Vagrantfile @@ -0,0 +1,35 @@ +# This guide is optimized for Vagrant 1.7 and above. +# Although versions 1.6.x should behave very similarly, it is recommended +# to upgrade instead of disabling the requirement below. +Vagrant.require_version ">= 1.7.0" + +Vagrant.configure(2) do |config| + + config.vm.box = "debian/buster64" + config.vm.synced_folder ".", "/vagrant", disabled: true + # Disable the new default behavior introduced in Vagrant 1.7, to + # ensure that all Vagrant machines will use the same SSH key pair. + # See https://github.com/mitchellh/vagrant/issues/5005 + config.ssh.insert_key = false + + config.vm.provider :libvirt do |lv| + lv.cpus = 1 + lv.memory = 512 + end + + config.vm.define "srv1" do |m| + m.vm.hostname = "srv1" + m.vm.network :private_network, ip: "192.168.123.30", libvirt__dhcp_enabled: false + end + config.vm.define "srv2" do |m| + m.vm.hostname = "srv2" + m.vm.network :private_network, ip: "192.168.123.31", libvirt__dhcp_enabled: false + end + + config.vm.provision "ansible" do |ansible| + #ansible.become = true + ansible.verbose = "v" + ansible.playbook = "playbook.yml" + ansible.inventory_path = "inventory.yml" + end +end diff --git a/ansible.cfg b/ansible.cfg new file mode 100644 index 0000000..99ab541 --- /dev/null +++ b/ansible.cfg @@ -0,0 +1,2 @@ +[defaults] +roles_path = /root/.ansible/roles/:../ diff --git a/certs/.gitkeep b/certs/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/inventory.yml b/inventory.yml new file mode 100644 index 0000000..b897cb4 --- /dev/null +++ b/inventory.yml @@ -0,0 +1,18 @@ +--- +all: + hosts: + srv1: + ansible_host: 192.168.123.30 + srv2: + ansible_host: 192.168.123.31 + vars: + cert_dir: ./certs + generate_ca_cert: true + generate_client_cert: true + generate_server_cert: true + tls_ca_email: me@example.org + tls_ca_country: EU + tls_ca_state: Italy + tls_ca_locality: Rome + tls_ca_organization: Example Inc. + tls_ca_organizationalunit: SysAdmins diff --git a/playbook.yml b/playbook.yml new file mode 100644 index 0000000..5e1eecb --- /dev/null +++ b/playbook.yml @@ -0,0 +1,5 @@ +--- +- name: Run role + hosts: all + roles: + - role: generate-tls-certs diff --git a/requirements.yml b/requirements.yml new file mode 100644 index 0000000..e2b522d --- /dev/null +++ b/requirements.yml @@ -0,0 +1,3 @@ +--- +collections: + - community.crypto diff --git a/tasks/generate-ca-cert.yaml b/tasks/generate-ca-cert.yaml index 55819df..75d6d74 100644 --- a/tasks/generate-ca-cert.yaml +++ b/tasks/generate-ca-cert.yaml @@ -1,20 +1,65 @@ --- - - name: Generate CA private key - local_action: - module: openssl_privatekey - path: "{{cert_dir}}/{{tls_ca_key}}" - size: "{{tls_ca_key_size}}" - run_once: true +- name: Check if the CA private key exists + delegate_to: localhost + ansible.builtin.stat: + path: "{{ cert_dir }}/{{ tls_ca_key }}" + register: ca_key - - name: Generate self-signed cert for CA - local_action: - 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 +- name: Generate CA private key + delegate_to: localhost + community.crypto.openssl_privatekey: + path: "{{ cert_dir }}/{{ tls_ca_key }}" + size: "{{ tls_ca_key_size }}" + run_once: true + when: not ca_key.stat.exists + +- name: Check if the CA CSR exists + delegate_to: localhost + stat: + path: "{{ cert_dir }}/{{ tls_ca_csr }}" + register: ca_csr + +- name: Create CSR for CA + delegate_to: localhost + community.crypto.openssl_csr: + path: "{{ cert_dir }}/{{ tls_ca_csr }}" + privatekey_path: "{{ cert_dir }}/{{ tls_ca_key }}" + basic_constraints: + - "CA:TRUE" + common_name: "{{ tls_ca_commonname|default('') }}" + country_name: "{{ tls_ca_country|default('') }}" + state_or_province_name: "{{ tls_ca_state|default('') }}" + locality_name: "{{ tls_ca_locality|default('') }}" + organization_name: "{{ tls_ca_organization|default('') }}" + organizational_unit_name: "{{ tls_ca_organizationalunit|default('') }}" + email_address: "{{ tls_ca_email }}" + use_common_name_for_san: no + when: not ca_csr.stat.exists + +- name: Check if the CA cert exists + delegate_to: localhost + stat: + path: "{{ cert_dir }}/{{ tls_ca_cert }}" + register: ca_cert + +- name: Create and sign server cert for CA + delegate_to: localhost + community.crypto.x509_certificate: + path: "{{ cert_dir }}/{{ tls_ca_cert }}" + privatekey_path: "{{ cert_dir }}/{{ tls_ca_key }}" + csr_path: "{{ cert_dir }}/{{ tls_ca_csr }}" + selfsigned_not_after: "+{{ tls_ca_valid_days }}d" + provider: selfsigned + when: not ca_cert.stat.exists + register: ca_cert_file + +- name: Copy the CA certificate to the remote machine + copy: + src: "{{ cert_dir }}/{{ tls_ca_cert }}" + dest: /etc/ssl/certs/ + mode: 0644 + owner: root + group: root + force: yes + backup: yes + when: ca_cert_file.changed diff --git a/tasks/generate-client-cert.yaml b/tasks/generate-client-cert.yaml index 5eb10cc..1dd6e5e 100644 --- a/tasks/generate-client-cert.yaml +++ b/tasks/generate-client-cert.yaml @@ -1,46 +1,87 @@ --- +- name: Ensure the custom directories to host certificates are present + become: yes + file: + state: directory + recurse: yes + path: "/etc/ssl/{{ item.path }}" + mode: "{{ item.mode }}" + owner: root + group: root + loop: + - {path: local/certs, mode: "0755"} + - {path: local/private, mode: "0700"} - - name: Generate client private key - local_action: - module: openssl_privatekey - path: "{{cert_dir}}/{{tls_client_key}}" - size: "{{tls_client_key_size}}" - run_once: true - when: generate_client_cert - - - name: Generate CSR and key for client cert - local_action: - 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 - - - name: Add required extension for client authentication - local_action: - module: > - shell echo extendedKeyUsage = clientAuth >> {{cert_dir}}/{{tls_client_extfile}} - ignore_errors: true - run_once: true - when: generate_client_cert - - # @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 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 +- name: Check if the client private key exists + delegate_to: localhost + stat: + path: "{{ cert_dir }}/{{ tls_client_key }}" + register: client_key + +- name: Generate client private key + delegate_to: localhost + community.crypto.openssl_privatekey: + path: "{{ cert_dir }}/{{ tls_client_key }}" + size: "{{ tls_client_key_size}}" + when: + - not client_key.stat.exists + - generate_client_cert + register: client_key_file + +- name: Copy the key on the server + become: yes + copy: + src: "{{ cert_dir }}/{{ tls_client_key}}" + dest: /etc/ssl/local/certs/ + mode: 0644 + owner: root + group: root + when: client_key_file.changed + +- name: Check if the client CSR exists + delegate_to: localhost + stat: + path: "{{ cert_dir }}/{{ tls_client_csr }}" + register: client_csr + +- name: Generate CSR and key for client cert + delegate_to: localhost + community.crypto.openssl_csr: + path: "{{ cert_dir }}/{{ tls_client_csr }}" + privatekey_path: "{{ cert_dir }}/{{ tls_client_key }}" + common_name: "{{ tls_client_commonname }}" + extended_key_usage: + - clientAuth + when: + - not client_csr.stat.exists + - generate_client_cert + +- name: Check if the client cert exists + delegate_to: localhost + stat: + path: "{{ cert_dir }}/{{ tls_client_cert }}" + register: client_crt + +- name: Create and sign server cert request by CA + delegate_to: localhost + community.crypto.x509_certificate: + path: "{{ cert_dir }}/{{ tls_client_cert }}" + csr_path: "{{ cert_dir }}/{{ tls_client_csr }}" + ownca_not_after: "+{{ tls_client_valid_days }}d" + ownca_path: "{{ cert_dir }}/{{ tls_ca_cert }}" + ownca_privatekey_path: "{{ cert_dir }}/{{ tls_ca_key }}" + provider: ownca + when: + - not client_crt.stat.exists + - generate_client_cert + register: client_cert_file + +- name: Copy the certificate to the remote machine + become: yes + copy: + src: "{{ cert_dir }}/{{ tls_client_cert }}" + dest: /etc/ssl/local/private + mode: 0600 + owner: root + group: root + when: client_cert_file.changed diff --git a/tasks/generate-server-cert.yaml b/tasks/generate-server-cert.yaml index c35300f..5808241 100644 --- a/tasks/generate-server-cert.yaml +++ b/tasks/generate-server-cert.yaml @@ -1,38 +1,96 @@ --- - # Generate server cert - - name: Create CSR for server cert - local_action: - 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 - - - name: Generate certificate extensions file - local_action: - module: template - src: templates/server-cert-extfile.cnf.j2 - dest: "{{cert_dir}}/{{inventory_hostname_short}}-extfile.cnf" - when: - - generate_server_cert - - tls_server_enable_san - - - name: Sign server cert request by CA - local_action: - 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 +- name: Ensure the custom directories to host certificates are present + become: yes + file: + state: directory + recurse: yes + path: "/etc/ssl/{{ item.path }}" + mode: "{{ item.mode }}" + owner: root + group: root + loop: + - {path: local/certs, mode: "0755"} + - {path: local/private, mode: "0700"} + +- name: Check if the server private key exists + delegate_to: localhost + stat: + path: "{{ cert_dir }}/{{ inventory_hostname_short }}.key" + register: server_key + +- name: Create PEM private key for server + delegate_to: localhost + community.crypto.openssl_privatekey: + path: "{{ cert_dir }}/{{ inventory_hostname_short }}.key" + when: not server_key.stat.exists + register: server_key_file + +- name: Copy the key on the server + become: yes + copy: + src: "{{ cert_dir }}/{{ inventory_hostname_short }}.key" + dest: /etc/ssl/local/certs/ + mode: 0644 + owner: root + group: root + when: server_key_file.changed + +- name: Check if the server CSR exists + delegate_to: localhost + stat: + path: "{{ cert_dir }}/{{ inventory_hostname_short }}.csr" + register: server_csr + +- name: Create CSR for server cert + delegate_to: localhost + community.crypto.openssl_csr: + path: "{{ cert_dir }}/{{ inventory_hostname_short }}.csr" + privatekey_path: "{{ cert_dir }}/{{ inventory_hostname_short }}.key" + common_name: "{{ inventory_hostname_short }}" + when: + - not server_csr.stat.exists + - generate_server_cert + - not tls_server_enable_san + +- name: Create CSR for server cert + delegate_to: localhost + community.crypto.openssl_csr: + path: "{{ cert_dir }}/{{ inventory_hostname_short }}.csr" + privatekey_path: "{{ cert_dir }}/{{ inventory_hostname_short }}.key" + common_name: "{{inventory_hostname_short}}" + subject_alt_name: "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" + when: + - not server_csr.stat.exists + - generate_server_cert + - tls_server_enable_san + +- name: Check if the server cert exists + delegate_to: localhost + stat: + path: "{{ cert_dir }}/{{ inventory_hostname_short }}.pem" + register: server_crt + +- name: Create and sign server cert request by CA + delegate_to: localhost + community.crypto.x509_certificate: + path: "{{ cert_dir }}/{{ inventory_hostname_short }}.pem" + csr_path: "{{ cert_dir }}/{{ inventory_hostname_short }}.csr" + ownca_not_after: "+{{ tls_server_valid_days }}d" + ownca_path: "{{ cert_dir }}/{{ tls_ca_cert }}" + ownca_privatekey_path: "{{ cert_dir }}/{{ tls_ca_key }}" + provider: ownca + ignore_errors: true + when: + - not server_crt.stat.exists + - generate_server_cert + register: server_cert_file + +- name: Copy the certificate to the remote machine + become: yes + copy: + src: "{{ cert_dir }}/{{ inventory_hostname_short }}.pem" + dest: /etc/ssl/local/private + mode: 0600 + owner: root + group: root + when: server_cert_file.changed diff --git a/tasks/main.yml b/tasks/main.yml index 54579e6..9ea5934 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -1,20 +1,19 @@ --- # tasks file for generate-tls-certs +- name: Generate CA cert + include_tasks: generate-ca-cert.yaml + when: + - generate_tls_certs + - generate_ca_cert|bool - - name: Generate CA cert - import_tasks: generate-ca-cert.yaml - when: - - generate_tls_certs - - generate_ca_cert|bool +- name: Generate client cert + include_tasks: generate-client-cert.yaml + when: + - generate_tls_certs + - generate_client_cert|bool - - name: Generate client cert - import_tasks: generate-client-cert.yaml - when: - - generate_tls_certs - - generate_client_cert|bool - - - name: Generate server cert - import_tasks: generate-server-cert.yaml - when: - - generate_tls_certs - - generate_server_cert|bool +- name: Generate server cert + include_tasks: generate-server-cert.yaml + when: + - generate_tls_certs + - generate_server_cert|bool From bd82ad3751186f0682ce71b62e52466968161405 Mon Sep 17 00:00:00 2001 From: Blallo Date: Sun, 24 Jan 2021 00:32:01 +0100 Subject: [PATCH 02/10] Update README --- README.md | 106 +++++++++++++++++++++++++----------------------------- 1 file changed, 48 insertions(+), 58 deletions(-) diff --git a/README.md b/README.md index a87caab..6b7d8d3 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ Generates self-signed CA, client and server certificates. Runs locally on contro 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). +- Will not copy the files to the remote servers if the local files are unchanged Requirements @@ -19,68 +19,58 @@ See `defaults/main.yml` Dependencies ------------ -- Refer to [Ansible Crypto modules](http://docs.ansible.com/ansible/latest/modules/list_of_crypto_modules.html) +Install dependencies via -Example Playbook ----------------- -**generate-certs.yaml:** ``` ---- - -# ansible-playbook generate-certs.yaml -i localhost, -# ansible-playbook generate-certs.yaml -i inventory.yaml - -- hosts: all - - gather_facts: false - - tasks: - - include_vars: vars.yaml +$ ansible-galaxy collection install community.crypto +``` - - name: Generate certs - import_role: - name: generate-tls-certs +Example Playbook +---------------- -``` +The provided example `playbook.yml` targets two hosts (take a look at the +`Vagrantfile`). + +All the cryptographic relevant operations are performed on the host machine and +the resulting relevant files are `copy`ed to the remote target machine. + + - `playbook.yml` + ```yaml + --- + - name: Run role + hosts: all + roles: + - role: generate-tls-certs + ``` + + - `inventory.yml` + ```yaml + --- + all: + hosts: + srv1: + ansible_host: 192.168.123.30 + srv2: + ansible_host: 192.168.123.31 + vars: + cert_dir: ./certs + generate_ca_cert: true + generate_client_cert: true + generate_server_cert: true + tls_ca_email: me@example.org + tls_ca_country: EU + tls_ca_state: Italy + tls_ca_locality: Rome + tls_ca_organization: Example Inc. + tls_ca_organizationalunit: SysAdmins + ``` + +If you want to tinker, you can use `vagrant` with the provided `Vagrantfile`. +It assumes `vagrant-libvirt` is installed (along with `libvirt`, of course). + +Run it like this: -**vars.yaml:** ``` ---- - cert_dir: ./certs - generate_ca_cert: true - generate_client_cert: true - generate_server_cert: true - - # ------- - # CA CERT - # ------- - tls_ca_cert: my-ca.pem - tls_ca_csr: my-ca.csr - tls_ca_key: my-ca.key - tls_ca_country: CA - tls_ca_state: Ontario - tls_ca_locality: Toronto - tls_ca_organization: My Company Inc. - tls_ca_organizationalunit: IT - tls_ca_commonname: My Certificate Authority - - # ----------- - # CLIENT CERT - # ----------- - tls_client_cert: my-client.pem - tls_client_key: my-client.key - tls_client_csr: my-client.csr - tls_client_commonname: My Client - +$ vagrant up --provider=libvirt --provision ``` - - -License -------- -BSD - - -Author Information ------------------- -[EasyPath IT Solutions Inc.](https://www.easypath.ca) From 7104c3ed7daf7dd2edf1ab336aadbe4ce5441f40 Mon Sep 17 00:00:00 2001 From: Blallo Date: Sun, 24 Jan 2021 12:32:31 +0100 Subject: [PATCH 03/10] Remove now useless templates --- templates/server-cert-extfile.cnf.j2 | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 templates/server-cert-extfile.cnf.j2 diff --git a/templates/server-cert-extfile.cnf.j2 b/templates/server-cert-extfile.cnf.j2 deleted file mode 100644 index 5647878..0000000 --- a/templates/server-cert-extfile.cnf.j2 +++ /dev/null @@ -1,3 +0,0 @@ -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 From cf4d06adcc6c408317602d6ef78a8e35b2b6c485 Mon Sep 17 00:00:00 2001 From: Blallo Date: Sun, 24 Jan 2021 12:50:08 +0100 Subject: [PATCH 04/10] Optionally fill /etc/hosts --- README.md | 3 +++ defaults/main.yml | 5 +++++ inventory.yml | 1 + tasks/main.yml | 4 ++++ tasks/populate-etc-hosts.yaml | 10 ++++++++++ 5 files changed, 23 insertions(+) create mode 100644 tasks/populate-etc-hosts.yaml diff --git a/README.md b/README.md index 6b7d8d3..eca11cb 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,8 @@ Generates self-signed CA, client and server certificates. Runs locally on contro Notes: - Will not overwrite any files in output cert dir - Will not copy the files to the remote servers if the local files are unchanged +- Will optionally (see `populate_etc_hosts` variable) add to each machine's `/etc/hosts` + a line for each host in the inventory. Requirements @@ -64,6 +66,7 @@ the resulting relevant files are `copy`ed to the remote target machine. tls_ca_locality: Rome tls_ca_organization: Example Inc. tls_ca_organizationalunit: SysAdmins + populate_etc_hosts: yes ``` If you want to tinker, you can use `vagrant` with the provided `Vagrantfile`. diff --git a/defaults/main.yml b/defaults/main.yml index f2841f0..8fda26a 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -44,3 +44,8 @@ tls_server_valid_days: 730 tls_server_key_size: 4096 # Enable Subject Alternate Name (SAN) tls_server_enable_san: true + +# ------------------- +# POPULATE /etc/hosts +# ------------------- +populate_etc_hosts: false diff --git a/inventory.yml b/inventory.yml index b897cb4..b4ca4b4 100644 --- a/inventory.yml +++ b/inventory.yml @@ -16,3 +16,4 @@ all: tls_ca_locality: Rome tls_ca_organization: Example Inc. tls_ca_organizationalunit: SysAdmins + populate_etc_hosts: yes diff --git a/tasks/main.yml b/tasks/main.yml index 9ea5934..653c8cf 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -17,3 +17,7 @@ when: - generate_tls_certs - generate_server_cert|bool + +- name: Populate /etc/hosts with inventory's hosts + include_tasks: populate-etc-hosts.yaml + when: populate_etc_hosts|bool diff --git a/tasks/populate-etc-hosts.yaml b/tasks/populate-etc-hosts.yaml new file mode 100644 index 0000000..184d712 --- /dev/null +++ b/tasks/populate-etc-hosts.yaml @@ -0,0 +1,10 @@ +--- +- name: Add IP address of all hosts to all hosts + become: yes + lineinfile: + dest: /etc/hosts + regexp: '.*{{ item }}$' + line: "{{ hostvars[item].ansible_host }} {{item}}" + state: present + when: hostvars[item].ansible_host is defined + loop: "{{ groups.all }}" From a87a47a872126f39fab08718cdf8f3da88d989c4 Mon Sep 17 00:00:00 2001 From: Blallo Date: Sun, 24 Jan 2021 12:56:06 +0100 Subject: [PATCH 05/10] Remove unused default --- defaults/main.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/defaults/main.yml b/defaults/main.yml index 8fda26a..a460547 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -32,7 +32,6 @@ tls_client_key: client.key tls_client_csr: client.csr tls_client_key_size: 4096 tls_client_commonname: Client -tls_client_extfile: extfile-client.cnf # 2 years tls_client_valid_days: 730 From dbdafdf1adcfe1fb11d63f724a93887ce6179129 Mon Sep 17 00:00:00 2001 From: Blallo Date: Sun, 24 Jan 2021 13:07:02 +0100 Subject: [PATCH 06/10] Parametrize remote directories --- defaults/main.yml | 2 ++ tasks/generate-ca-cert.yaml | 2 +- tasks/generate-client-cert.yaml | 6 +++--- tasks/generate-server-cert.yaml | 6 +++--- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/defaults/main.yml b/defaults/main.yml index a460547..b87b9d1 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -3,6 +3,8 @@ generate_tls_certs: true # Do not put trailing slash "/" cert_dir: ./certs +remote_certs_dir: /etc/ssl +remote_ca_certs_dir: /etc/ssl/certs generate_ca_cert: false generate_client_cert: false generate_server_cert: false diff --git a/tasks/generate-ca-cert.yaml b/tasks/generate-ca-cert.yaml index 75d6d74..8c79920 100644 --- a/tasks/generate-ca-cert.yaml +++ b/tasks/generate-ca-cert.yaml @@ -56,7 +56,7 @@ - name: Copy the CA certificate to the remote machine copy: src: "{{ cert_dir }}/{{ tls_ca_cert }}" - dest: /etc/ssl/certs/ + dest: "{{ remote_ca_certs_dir }}" mode: 0644 owner: root group: root diff --git a/tasks/generate-client-cert.yaml b/tasks/generate-client-cert.yaml index 1dd6e5e..f1d7245 100644 --- a/tasks/generate-client-cert.yaml +++ b/tasks/generate-client-cert.yaml @@ -4,7 +4,7 @@ file: state: directory recurse: yes - path: "/etc/ssl/{{ item.path }}" + path: "{{ remote_certs_dir }}/{{ item.path }}" mode: "{{ item.mode }}" owner: root group: root @@ -32,7 +32,7 @@ become: yes copy: src: "{{ cert_dir }}/{{ tls_client_key}}" - dest: /etc/ssl/local/certs/ + dest: "{{ remote_certs_dir }}/local/certs/" mode: 0644 owner: root group: root @@ -80,7 +80,7 @@ become: yes copy: src: "{{ cert_dir }}/{{ tls_client_cert }}" - dest: /etc/ssl/local/private + dest: "{{ remote_certs_dir }}/local/private" mode: 0600 owner: root group: root diff --git a/tasks/generate-server-cert.yaml b/tasks/generate-server-cert.yaml index 5808241..70c4b00 100644 --- a/tasks/generate-server-cert.yaml +++ b/tasks/generate-server-cert.yaml @@ -4,7 +4,7 @@ file: state: directory recurse: yes - path: "/etc/ssl/{{ item.path }}" + path: "{{ remote_certs_dir }}/{{ item.path }}" mode: "{{ item.mode }}" owner: root group: root @@ -29,7 +29,7 @@ become: yes copy: src: "{{ cert_dir }}/{{ inventory_hostname_short }}.key" - dest: /etc/ssl/local/certs/ + dest: "{{ remote_certs_dir }}/local/certs/" mode: 0644 owner: root group: root @@ -89,7 +89,7 @@ become: yes copy: src: "{{ cert_dir }}/{{ inventory_hostname_short }}.pem" - dest: /etc/ssl/local/private + dest: "{{ remote_certs_dir }}/local/private" mode: 0600 owner: root group: root From f485128919ac476293042d2767c74734c1bb0678 Mon Sep 17 00:00:00 2001 From: Blallo Date: Sun, 24 Jan 2021 13:16:15 +0100 Subject: [PATCH 07/10] Add pseudo-namespace to variables --- README.md | 24 +++++++------- defaults/main.yml | 58 ++++++++++++++++----------------- inventory.yml | 22 ++++++------- tasks/generate-ca-cert.yaml | 40 +++++++++++------------ tasks/generate-client-cert.yaml | 36 ++++++++++---------- tasks/generate-server-cert.yaml | 46 +++++++++++++------------- tasks/main.yml | 14 ++++---- 7 files changed, 120 insertions(+), 120 deletions(-) diff --git a/README.md b/README.md index eca11cb..6413ba2 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ Generates self-signed CA, client and server certificates. Runs locally on contro Notes: - Will not overwrite any files in output cert dir - Will not copy the files to the remote servers if the local files are unchanged -- Will optionally (see `populate_etc_hosts` variable) add to each machine's `/etc/hosts` +- Will optionally (see `gen_tls_populate_etc_hosts` variable) add to each machine's `/etc/hosts` a line for each host in the inventory. @@ -56,17 +56,17 @@ the resulting relevant files are `copy`ed to the remote target machine. srv2: ansible_host: 192.168.123.31 vars: - cert_dir: ./certs - generate_ca_cert: true - generate_client_cert: true - generate_server_cert: true - tls_ca_email: me@example.org - tls_ca_country: EU - tls_ca_state: Italy - tls_ca_locality: Rome - tls_ca_organization: Example Inc. - tls_ca_organizationalunit: SysAdmins - populate_etc_hosts: yes + gen_tls_cert_dir: ./certs + gen_tls_generate_ca_cert: true + gen_tls_generate_client_cert: true + gen_tls_generate_server_cert: true + gen_tls_ca_email: me@example.org + gen_tls_ca_country: EU + gen_tls_ca_state: Italy + gen_tls_ca_locality: Rome + gen_tls_ca_organization: Example Inc. + gen_tls_ca_organizationalunit: SysAdmins + gen_tls_populate_etc_hosts: yes ``` If you want to tinker, you can use `vagrant` with the provided `Vagrantfile`. diff --git a/defaults/main.yml b/defaults/main.yml index b87b9d1..d975f0e 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -1,52 +1,52 @@ --- # defaults file for generate-tls-certs -generate_tls_certs: true +gen_tls_generate_certs: true # Do not put trailing slash "/" -cert_dir: ./certs -remote_certs_dir: /etc/ssl -remote_ca_certs_dir: /etc/ssl/certs -generate_ca_cert: false -generate_client_cert: false -generate_server_cert: false +gen_tls_cert_dir: ./certs +gen_tls_remote_certs_dir: /etc/ssl +gen_tls_remote_ca_certs_dir: /etc/ssl/certs +gen_tls_generate_ca_cert: false +gen_tls_generate_client_cert: false +gen_tls_generate_server_cert: false # ------- # CA CERT # ------- -tls_ca_cert: ca.pem -tls_ca_csr: ca.csr -tls_ca_key: ca.key -tls_ca_key_size: 4096 +gen_tls_ca_cert: ca.pem +gen_tls_ca_csr: ca.csr +gen_tls_ca_key: ca.key +gen_tls_ca_key_size: 4096 # 10 years -tls_ca_valid_days: 3650 -# tls_ca_country: -# tls_ca_state: -# tls_ca_locality: -# tls_ca_organization: -# tls_ca_organizationalunit: -tls_ca_commonname: Certificate Authority -#tls_ca_email: +gen_tls_ca_valid_days: 3650 +# gen_tls_ca_country: +# gen_tls_ca_state: +# gen_tls_ca_locality: +# gen_tls_ca_organization: +# gen_tls_ca_organizationalunit: +gen_tls_ca_commonname: Certificate Authority +#gen_tls_ca_email: # ----------- # CLIENT CERT # ----------- -tls_client_cert: client.pem -tls_client_key: client.key -tls_client_csr: client.csr -tls_client_key_size: 4096 -tls_client_commonname: Client +gen_tls_client_cert: client.pem +gen_tls_client_key: client.key +gen_tls_client_csr: client.csr +gen_tls_client_key_size: 4096 +gen_tls_client_commonname: Client # 2 years -tls_client_valid_days: 730 +gen_tls_client_valid_days: 730 # ----------- # SERVER CERT # ----------- # 2 years -tls_server_valid_days: 730 -tls_server_key_size: 4096 +gen_tls_server_valid_days: 730 +gen_tls_server_key_size: 4096 # Enable Subject Alternate Name (SAN) -tls_server_enable_san: true +gen_tls_server_enable_san: true # ------------------- # POPULATE /etc/hosts # ------------------- -populate_etc_hosts: false +gen_tls_populate_etc_hosts: false diff --git a/inventory.yml b/inventory.yml index b4ca4b4..d0b3a0e 100644 --- a/inventory.yml +++ b/inventory.yml @@ -6,14 +6,14 @@ all: srv2: ansible_host: 192.168.123.31 vars: - cert_dir: ./certs - generate_ca_cert: true - generate_client_cert: true - generate_server_cert: true - tls_ca_email: me@example.org - tls_ca_country: EU - tls_ca_state: Italy - tls_ca_locality: Rome - tls_ca_organization: Example Inc. - tls_ca_organizationalunit: SysAdmins - populate_etc_hosts: yes + gen_tls_cert_dir: ./certs + gen_tls_generate_ca_cert: true + gen_tls_generate_client_cert: true + gen_tls_generate_server_cert: true + gen_tls_ca_email: me@example.org + gen_tls_ca_country: EU + gen_tls_ca_state: Italy + gen_tls_ca_locality: Rome + gen_tls_ca_organization: Example Inc. + gen_tls_ca_organizationalunit: SysAdmins + gen_tls_populate_etc_hosts: yes diff --git a/tasks/generate-ca-cert.yaml b/tasks/generate-ca-cert.yaml index 8c79920..f61d719 100644 --- a/tasks/generate-ca-cert.yaml +++ b/tasks/generate-ca-cert.yaml @@ -2,61 +2,61 @@ - name: Check if the CA private key exists delegate_to: localhost ansible.builtin.stat: - path: "{{ cert_dir }}/{{ tls_ca_key }}" + path: "{{ gen_tls_cert_dir }}/{{ gen_tls_ca_key }}" register: ca_key - name: Generate CA private key delegate_to: localhost community.crypto.openssl_privatekey: - path: "{{ cert_dir }}/{{ tls_ca_key }}" - size: "{{ tls_ca_key_size }}" + path: "{{ gen_tls_cert_dir }}/{{ gen_tls_ca_key }}" + size: "{{ gen_tls_ca_key_size }}" run_once: true when: not ca_key.stat.exists - name: Check if the CA CSR exists delegate_to: localhost stat: - path: "{{ cert_dir }}/{{ tls_ca_csr }}" + path: "{{ gen_tls_cert_dir }}/{{ gen_tls_ca_csr }}" register: ca_csr - name: Create CSR for CA delegate_to: localhost community.crypto.openssl_csr: - path: "{{ cert_dir }}/{{ tls_ca_csr }}" - privatekey_path: "{{ cert_dir }}/{{ tls_ca_key }}" + path: "{{ gen_tls_cert_dir }}/{{ gen_tls_ca_csr }}" + privatekey_path: "{{ gen_tls_cert_dir }}/{{ gen_tls_ca_key }}" basic_constraints: - "CA:TRUE" - common_name: "{{ tls_ca_commonname|default('') }}" - country_name: "{{ tls_ca_country|default('') }}" - state_or_province_name: "{{ tls_ca_state|default('') }}" - locality_name: "{{ tls_ca_locality|default('') }}" - organization_name: "{{ tls_ca_organization|default('') }}" - organizational_unit_name: "{{ tls_ca_organizationalunit|default('') }}" - email_address: "{{ tls_ca_email }}" + common_name: "{{ gen_tls_ca_commonname|default('') }}" + country_name: "{{ gen_tls_ca_country|default('') }}" + state_or_province_name: "{{ gen_tls_ca_state|default('') }}" + locality_name: "{{ gen_tls_ca_locality|default('') }}" + organization_name: "{{ gen_tls_ca_organization|default('') }}" + organizational_unit_name: "{{ gen_tls_ca_organizationalunit|default('') }}" + email_address: "{{ gen_tls_ca_email }}" use_common_name_for_san: no when: not ca_csr.stat.exists - name: Check if the CA cert exists delegate_to: localhost stat: - path: "{{ cert_dir }}/{{ tls_ca_cert }}" + path: "{{ gen_tls_cert_dir }}/{{ gen_tls_ca_cert }}" register: ca_cert - name: Create and sign server cert for CA delegate_to: localhost community.crypto.x509_certificate: - path: "{{ cert_dir }}/{{ tls_ca_cert }}" - privatekey_path: "{{ cert_dir }}/{{ tls_ca_key }}" - csr_path: "{{ cert_dir }}/{{ tls_ca_csr }}" - selfsigned_not_after: "+{{ tls_ca_valid_days }}d" + path: "{{ gen_tls_cert_dir }}/{{ gen_tls_ca_cert }}" + privatekey_path: "{{ gen_tls_cert_dir }}/{{ gen_tls_ca_key }}" + csr_path: "{{ gen_tls_cert_dir }}/{{ gen_tls_ca_csr }}" + selfsigned_not_after: "+{{ gen_tls_ca_valid_days }}d" provider: selfsigned when: not ca_cert.stat.exists register: ca_cert_file - name: Copy the CA certificate to the remote machine copy: - src: "{{ cert_dir }}/{{ tls_ca_cert }}" - dest: "{{ remote_ca_certs_dir }}" + src: "{{ gen_tls_cert_dir }}/{{ gen_tls_ca_cert }}" + dest: "{{ gen_tls_remote_ca_certs_dir }}" mode: 0644 owner: root group: root diff --git a/tasks/generate-client-cert.yaml b/tasks/generate-client-cert.yaml index f1d7245..795e1cb 100644 --- a/tasks/generate-client-cert.yaml +++ b/tasks/generate-client-cert.yaml @@ -4,7 +4,7 @@ file: state: directory recurse: yes - path: "{{ remote_certs_dir }}/{{ item.path }}" + path: "{{ gen_tls_remote_certs_dir }}/{{ item.path }}" mode: "{{ item.mode }}" owner: root group: root @@ -15,14 +15,14 @@ - name: Check if the client private key exists delegate_to: localhost stat: - path: "{{ cert_dir }}/{{ tls_client_key }}" + path: "{{ gen_tls_cert_dir }}/{{ gen_tls_client_key }}" register: client_key - name: Generate client private key delegate_to: localhost community.crypto.openssl_privatekey: - path: "{{ cert_dir }}/{{ tls_client_key }}" - size: "{{ tls_client_key_size}}" + path: "{{ gen_tls_cert_dir }}/{{ gen_tls_client_key }}" + size: "{{ gen_tls_client_key_size}}" when: - not client_key.stat.exists - generate_client_cert @@ -31,8 +31,8 @@ - name: Copy the key on the server become: yes copy: - src: "{{ cert_dir }}/{{ tls_client_key}}" - dest: "{{ remote_certs_dir }}/local/certs/" + src: "{{ gen_tls_cert_dir }}/{{ gen_tls_client_key}}" + dest: "{{ gen_tls_remote_certs_dir }}/local/certs/" mode: 0644 owner: root group: root @@ -41,15 +41,15 @@ - name: Check if the client CSR exists delegate_to: localhost stat: - path: "{{ cert_dir }}/{{ tls_client_csr }}" + path: "{{ gen_tls_cert_dir }}/{{ gen_tls_client_csr }}" register: client_csr - name: Generate CSR and key for client cert delegate_to: localhost community.crypto.openssl_csr: - path: "{{ cert_dir }}/{{ tls_client_csr }}" - privatekey_path: "{{ cert_dir }}/{{ tls_client_key }}" - common_name: "{{ tls_client_commonname }}" + path: "{{ gen_tls_cert_dir }}/{{ gen_tls_client_csr }}" + privatekey_path: "{{ gen_tls_cert_dir }}/{{ gen_tls_client_key }}" + common_name: "{{ gen_tls_client_commonname }}" extended_key_usage: - clientAuth when: @@ -59,17 +59,17 @@ - name: Check if the client cert exists delegate_to: localhost stat: - path: "{{ cert_dir }}/{{ tls_client_cert }}" + path: "{{ gen_tls_cert_dir }}/{{ gen_tls_client_cert }}" register: client_crt - name: Create and sign server cert request by CA delegate_to: localhost community.crypto.x509_certificate: - path: "{{ cert_dir }}/{{ tls_client_cert }}" - csr_path: "{{ cert_dir }}/{{ tls_client_csr }}" - ownca_not_after: "+{{ tls_client_valid_days }}d" - ownca_path: "{{ cert_dir }}/{{ tls_ca_cert }}" - ownca_privatekey_path: "{{ cert_dir }}/{{ tls_ca_key }}" + path: "{{ gen_tls_cert_dir }}/{{ gen_tls_client_cert }}" + csr_path: "{{ gen_tls_cert_dir }}/{{ gen_tls_client_csr }}" + ownca_not_after: "+{{ gen_tls_client_valid_days }}d" + ownca_path: "{{ gen_tls_cert_dir }}/{{ gen_tls_ca_cert }}" + ownca_privatekey_path: "{{ gen_tls_cert_dir }}/{{ gen_tls_ca_key }}" provider: ownca when: - not client_crt.stat.exists @@ -79,8 +79,8 @@ - name: Copy the certificate to the remote machine become: yes copy: - src: "{{ cert_dir }}/{{ tls_client_cert }}" - dest: "{{ remote_certs_dir }}/local/private" + src: "{{ gen_tls_cert_dir }}/{{ gen_tls_client_cert }}" + dest: "{{ gen_tls_remote_certs_dir }}/local/private" mode: 0600 owner: root group: root diff --git a/tasks/generate-server-cert.yaml b/tasks/generate-server-cert.yaml index 70c4b00..025ae36 100644 --- a/tasks/generate-server-cert.yaml +++ b/tasks/generate-server-cert.yaml @@ -4,7 +4,7 @@ file: state: directory recurse: yes - path: "{{ remote_certs_dir }}/{{ item.path }}" + path: "{{ gen_tls_remote_certs_dir }}/{{ item.path }}" mode: "{{ item.mode }}" owner: root group: root @@ -15,21 +15,21 @@ - name: Check if the server private key exists delegate_to: localhost stat: - path: "{{ cert_dir }}/{{ inventory_hostname_short }}.key" + path: "{{ gen_tls_cert_dir }}/{{ inventory_hostname_short }}.key" register: server_key - name: Create PEM private key for server delegate_to: localhost community.crypto.openssl_privatekey: - path: "{{ cert_dir }}/{{ inventory_hostname_short }}.key" + path: "{{ gen_tls_cert_dir }}/{{ inventory_hostname_short }}.key" when: not server_key.stat.exists register: server_key_file - name: Copy the key on the server become: yes copy: - src: "{{ cert_dir }}/{{ inventory_hostname_short }}.key" - dest: "{{ remote_certs_dir }}/local/certs/" + src: "{{ gen_tls_cert_dir }}/{{ inventory_hostname_short }}.key" + dest: "{{ gen_tls_remote_certs_dir }}/local/certs/" mode: 0644 owner: root group: root @@ -38,58 +38,58 @@ - name: Check if the server CSR exists delegate_to: localhost stat: - path: "{{ cert_dir }}/{{ inventory_hostname_short }}.csr" + path: "{{ gen_tls_cert_dir }}/{{ inventory_hostname_short }}.csr" register: server_csr - name: Create CSR for server cert delegate_to: localhost community.crypto.openssl_csr: - path: "{{ cert_dir }}/{{ inventory_hostname_short }}.csr" - privatekey_path: "{{ cert_dir }}/{{ inventory_hostname_short }}.key" + path: "{{ gen_tls_cert_dir }}/{{ inventory_hostname_short }}.csr" + privatekey_path: "{{ gen_tls_cert_dir }}/{{ inventory_hostname_short }}.key" common_name: "{{ inventory_hostname_short }}" when: - not server_csr.stat.exists - - generate_server_cert - - not tls_server_enable_san + - gen_tls_generate_server_cert + - not gen_tls_server_enable_san - name: Create CSR for server cert delegate_to: localhost community.crypto.openssl_csr: - path: "{{ cert_dir }}/{{ inventory_hostname_short }}.csr" - privatekey_path: "{{ cert_dir }}/{{ inventory_hostname_short }}.key" + path: "{{ gen_tls_cert_dir }}/{{ inventory_hostname_short }}.csr" + privatekey_path: "{{ gen_tls_cert_dir }}/{{ inventory_hostname_short }}.key" common_name: "{{inventory_hostname_short}}" subject_alt_name: "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" when: - not server_csr.stat.exists - - generate_server_cert - - tls_server_enable_san + - gen_tls_generate_server_cert + - gen_tls_server_enable_san - name: Check if the server cert exists delegate_to: localhost stat: - path: "{{ cert_dir }}/{{ inventory_hostname_short }}.pem" + path: "{{ gen_tls_cert_dir }}/{{ inventory_hostname_short }}.pem" register: server_crt - name: Create and sign server cert request by CA delegate_to: localhost community.crypto.x509_certificate: - path: "{{ cert_dir }}/{{ inventory_hostname_short }}.pem" - csr_path: "{{ cert_dir }}/{{ inventory_hostname_short }}.csr" - ownca_not_after: "+{{ tls_server_valid_days }}d" - ownca_path: "{{ cert_dir }}/{{ tls_ca_cert }}" - ownca_privatekey_path: "{{ cert_dir }}/{{ tls_ca_key }}" + path: "{{ gen_tls_cert_dir }}/{{ inventory_hostname_short }}.pem" + csr_path: "{{ gen_tls_cert_dir }}/{{ inventory_hostname_short }}.csr" + ownca_not_after: "+{{ gen_tls_server_valid_days }}d" + ownca_path: "{{ gen_tls_cert_dir }}/{{ gen_tls_ca_cert }}" + ownca_privatekey_path: "{{ gen_tls_cert_dir }}/{{ gen_tls_ca_key }}" provider: ownca ignore_errors: true when: - not server_crt.stat.exists - - generate_server_cert + - gen_tls_generate_server_cert register: server_cert_file - name: Copy the certificate to the remote machine become: yes copy: - src: "{{ cert_dir }}/{{ inventory_hostname_short }}.pem" - dest: "{{ remote_certs_dir }}/local/private" + src: "{{ gen_tls_cert_dir }}/{{ inventory_hostname_short }}.pem" + dest: "{{ gen_tls_remote_certs_dir }}/local/private" mode: 0600 owner: root group: root diff --git a/tasks/main.yml b/tasks/main.yml index 653c8cf..9e3a078 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -3,21 +3,21 @@ - name: Generate CA cert include_tasks: generate-ca-cert.yaml when: - - generate_tls_certs - - generate_ca_cert|bool + - gen_tls_generate_certs + - gen_tls_generate_ca_cert|bool - name: Generate client cert include_tasks: generate-client-cert.yaml when: - - generate_tls_certs - - generate_client_cert|bool + - gen_tls_generate_certs + - gen_tls_generate_client_cert|bool - name: Generate server cert include_tasks: generate-server-cert.yaml when: - - generate_tls_certs - - generate_server_cert|bool + - gen_tls_generate_certs + - gen_tls_generate_server_cert|bool - name: Populate /etc/hosts with inventory's hosts include_tasks: populate-etc-hosts.yaml - when: populate_etc_hosts|bool + when: gen_tls_populate_etc_hosts|bool From 0bcb4b89b6f1282cd93e816aef0713c324109936 Mon Sep 17 00:00:00 2001 From: Blallo Date: Sun, 24 Jan 2021 18:30:36 +0100 Subject: [PATCH 08/10] Optional tld When updating /etc/hosts to add the hosts in the inventory, also add the name postfixed with a configurable tld. --- defaults/main.yml | 1 + inventory.yml | 1 + tasks/generate-server-cert.yaml | 2 +- tasks/populate-etc-hosts.yaml | 2 +- 4 files changed, 4 insertions(+), 2 deletions(-) diff --git a/defaults/main.yml b/defaults/main.yml index d975f0e..5fb192b 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -50,3 +50,4 @@ gen_tls_server_enable_san: true # POPULATE /etc/hosts # ------------------- gen_tls_populate_etc_hosts: false +# gen_tls_tld: diff --git a/inventory.yml b/inventory.yml index d0b3a0e..bfdf34b 100644 --- a/inventory.yml +++ b/inventory.yml @@ -17,3 +17,4 @@ all: gen_tls_ca_organization: Example Inc. gen_tls_ca_organizationalunit: SysAdmins gen_tls_populate_etc_hosts: yes + gen_tls_tld: example diff --git a/tasks/generate-server-cert.yaml b/tasks/generate-server-cert.yaml index 025ae36..88ba6a7 100644 --- a/tasks/generate-server-cert.yaml +++ b/tasks/generate-server-cert.yaml @@ -58,7 +58,7 @@ path: "{{ gen_tls_cert_dir }}/{{ inventory_hostname_short }}.csr" privatekey_path: "{{ gen_tls_cert_dir }}/{{ inventory_hostname_short }}.key" common_name: "{{inventory_hostname_short}}" - subject_alt_name: "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" + subject_alt_name: "{% if gen_tls_tld is defined %}DNS:{{ inventory_hostname_short }}.{{ gen_tls_tld }},{% endif %}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" when: - not server_csr.stat.exists - gen_tls_generate_server_cert diff --git a/tasks/populate-etc-hosts.yaml b/tasks/populate-etc-hosts.yaml index 184d712..9d9d626 100644 --- a/tasks/populate-etc-hosts.yaml +++ b/tasks/populate-etc-hosts.yaml @@ -4,7 +4,7 @@ lineinfile: dest: /etc/hosts regexp: '.*{{ item }}$' - line: "{{ hostvars[item].ansible_host }} {{item}}" + line: "{{ hostvars[item].ansible_host }} {{item}}{% if gen_tls_tld is defined %} {{ item }}.{{ gen_tls_tld }}{% endif %}" state: present when: hostvars[item].ansible_host is defined loop: "{{ groups.all }}" From 21b16fd264aa9386a903aa1238e7705769888d60 Mon Sep 17 00:00:00 2001 From: Blallo Date: Sun, 24 Jan 2021 18:42:51 +0100 Subject: [PATCH 09/10] Fix wrong remote directories --- tasks/generate-client-cert.yaml | 4 ++-- tasks/generate-server-cert.yaml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tasks/generate-client-cert.yaml b/tasks/generate-client-cert.yaml index 795e1cb..01ea601 100644 --- a/tasks/generate-client-cert.yaml +++ b/tasks/generate-client-cert.yaml @@ -32,7 +32,7 @@ become: yes copy: src: "{{ gen_tls_cert_dir }}/{{ gen_tls_client_key}}" - dest: "{{ gen_tls_remote_certs_dir }}/local/certs/" + dest: "{{ gen_tls_remote_certs_dir }}/local/private/" mode: 0644 owner: root group: root @@ -80,7 +80,7 @@ become: yes copy: src: "{{ gen_tls_cert_dir }}/{{ gen_tls_client_cert }}" - dest: "{{ gen_tls_remote_certs_dir }}/local/private" + dest: "{{ gen_tls_remote_certs_dir }}/local/certs/" mode: 0600 owner: root group: root diff --git a/tasks/generate-server-cert.yaml b/tasks/generate-server-cert.yaml index 88ba6a7..b83e828 100644 --- a/tasks/generate-server-cert.yaml +++ b/tasks/generate-server-cert.yaml @@ -29,7 +29,7 @@ become: yes copy: src: "{{ gen_tls_cert_dir }}/{{ inventory_hostname_short }}.key" - dest: "{{ gen_tls_remote_certs_dir }}/local/certs/" + dest: "{{ gen_tls_remote_certs_dir }}/local/private/" mode: 0644 owner: root group: root @@ -89,7 +89,7 @@ become: yes copy: src: "{{ gen_tls_cert_dir }}/{{ inventory_hostname_short }}.pem" - dest: "{{ gen_tls_remote_certs_dir }}/local/private" + dest: "{{ gen_tls_remote_certs_dir }}/local/certs" mode: 0600 owner: root group: root From 426803e260f6a2fa12cd026320378c9340138835 Mon Sep 17 00:00:00 2001 From: Blallo Date: Sun, 24 Jan 2021 22:37:47 +0100 Subject: [PATCH 10/10] Change CA cert format and add force copy option The certificate form of the CA has to be crt to be sure it is manageable by the Debian update-ca-certificates executable. Also, added option to force the copy of the certificates, also if the local files did not change. --- defaults/main.yml | 3 ++- tasks/generate-client-cert.yaml | 4 ++-- tasks/generate-server-cert.yaml | 4 ++-- tasks/main.yml | 6 ++++++ tasks/update-debian-ca.yaml | 8 ++++++++ 5 files changed, 20 insertions(+), 5 deletions(-) create mode 100644 tasks/update-debian-ca.yaml diff --git a/defaults/main.yml b/defaults/main.yml index 5fb192b..f22a598 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -8,11 +8,12 @@ gen_tls_remote_ca_certs_dir: /etc/ssl/certs gen_tls_generate_ca_cert: false gen_tls_generate_client_cert: false gen_tls_generate_server_cert: false +gen_tls_force_copy: false # ------- # CA CERT # ------- -gen_tls_ca_cert: ca.pem +gen_tls_ca_cert: ca.crt gen_tls_ca_csr: ca.csr gen_tls_ca_key: ca.key gen_tls_ca_key_size: 4096 diff --git a/tasks/generate-client-cert.yaml b/tasks/generate-client-cert.yaml index 01ea601..c1c55cd 100644 --- a/tasks/generate-client-cert.yaml +++ b/tasks/generate-client-cert.yaml @@ -36,7 +36,7 @@ mode: 0644 owner: root group: root - when: client_key_file.changed + when: client_key_file.changed or gen_tls_force_copy - name: Check if the client CSR exists delegate_to: localhost @@ -84,4 +84,4 @@ mode: 0600 owner: root group: root - when: client_cert_file.changed + when: client_cert_file.changed or gen_tls_force_copy diff --git a/tasks/generate-server-cert.yaml b/tasks/generate-server-cert.yaml index b83e828..fb00a90 100644 --- a/tasks/generate-server-cert.yaml +++ b/tasks/generate-server-cert.yaml @@ -33,7 +33,7 @@ mode: 0644 owner: root group: root - when: server_key_file.changed + when: server_key_file.changed or gen_tls_force_copy - name: Check if the server CSR exists delegate_to: localhost @@ -93,4 +93,4 @@ mode: 0600 owner: root group: root - when: server_cert_file.changed + when: server_cert_file.changed or gen_tls_force_copy diff --git a/tasks/main.yml b/tasks/main.yml index 9e3a078..8e25606 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -21,3 +21,9 @@ - name: Populate /etc/hosts with inventory's hosts include_tasks: populate-etc-hosts.yaml when: gen_tls_populate_etc_hosts|bool + +- name: Update system CA on Debian + include_tasks: update-debian-ca.yaml + when: + - gen_tls_generate_certs + - ansible_os_family == "Debian" diff --git a/tasks/update-debian-ca.yaml b/tasks/update-debian-ca.yaml new file mode 100644 index 0000000..184562b --- /dev/null +++ b/tasks/update-debian-ca.yaml @@ -0,0 +1,8 @@ +--- +- name: Copy the CA certificate to directory for system CA update + become: yes + shell: "cp {{ gen_tls_remote_ca_certs_dir }}/{{ gen_tls_ca_cert }} /usr/local/share/ca-certificates" + +- name: Update the system CA + become: yes + shell: /usr/sbin/update-ca-certificates