commit c06c4aac08caa6e3b107dc230cb3d0cec8bf04e6 Author: ace Date: Mon Aug 22 17:32:32 2022 +0300 first commit diff --git a/README.md b/README.md new file mode 100644 index 0000000..2b31eaa --- /dev/null +++ b/README.md @@ -0,0 +1,36 @@ +Inventory example: + + cacert_ca_name: "kojiCA" + cacert_ca_copy_to: + - { host: "dev-1", path: "/opt/koji/certs" } + cacert_ca_trust_anchors_update: True + + cacert_certs: + - name: kojiadmin + dest: + - { host: "dev-1", path: "/opt/koji/certs" } + - { host: "dev-1", name: "client", path: "/opt/koji/certs", concat: "crt" } + - name: koji.lan + dest: + - { host: "dev-1", path: "/opt/koji/certs" } + - { host: "dev-1", path: "/etc/haproxy/ssl", concat: "pem" } + - name: koji-hub.lan + subject_alt_names: + - koji-files.lan + dest: + - { host: "dev-1", path: "/opt/koji/certs" } + - { host: "dev-1", path: "/etc/haproxy/ssl", concat: "pem" } + - name: koji-web.lan + dest: + - { host: "dev-1", path: "/opt/koji/certs" } + - { host: "dev-1", path: "/etc/haproxy/ssl", concat: "pem" } + - { host: "dev-1", path: "/opt/koji/certs", concat: "pem" } + - name: kojibuilder1.lan + dest: + - { host: "kojibuilder1.lan", path: "/opt/koji/certs" } + - { host: "kojibuilder1.lan", path: "/opt/koji/certs", concat: "pem" } + - name: kojira.lan + dest: + - { host: "dev-1", path: "/opt/koji/certs" } + - { host: "dev-1", path: "/opt/koji/certs", concat: "pem" } + diff --git a/defaults/main.yaml b/defaults/main.yaml new file mode 100644 index 0000000..b23d6cc --- /dev/null +++ b/defaults/main.yaml @@ -0,0 +1,16 @@ +cacert_ssl_gen_path: "/tmp/cacert" +cacert_ca_name: "myCA" +cacert_ca_trust_anchors_update: False + +#cacert_ca_copy_to: +# - { host: "host-1", path: "/tmp" } +# +#cacert_certs: +# - name: example1.com +# dest: +# - { host: "host-1", path: "/tmp" } +# - { host: "host-1", name: "newname", path: "/tmp", concat: "pem" } +# - name: example2.com +# dest: +# - { host: "host-1", path: "/tmp" } + diff --git a/tasks/ca.yaml b/tasks/ca.yaml new file mode 100644 index 0000000..7852c49 --- /dev/null +++ b/tasks/ca.yaml @@ -0,0 +1,67 @@ +- name: Create CA {{ cacert_ca_name }} + block: + - name: Generate an OpenSSL private CA key with the default values (4096 bits, RSA) + community.crypto.openssl_privatekey: + path: "{{ cacert_ssl_gen_path }}/{{ cacert_ca_name }}.key" + register: cacert_ca_key_gen + + - name: Generate an OpenSSL Certificate Signing Request + community.crypto.openssl_csr: + path: "{{ cacert_ssl_gen_path }}/{{ cacert_ca_name }}.csr" + privatekey_path: "{{ cacert_ssl_gen_path }}/{{ cacert_ca_name }}.key" + use_common_name_for_san: false + basic_constraints: + - 'CA:TRUE' + basic_constraints_critical: yes + key_usage: + - keyCertSign + key_usage_critical: true + common_name: "{{ cacert_ca_name }}" + register: cacert_ca_csr + + - name: Generate a Self Signed OpenSSL CA certificate + community.crypto.x509_certificate: + path: "{{ cacert_ssl_gen_path }}/{{ cacert_ca_name }}.crt" + csr_path: "{{ cacert_ssl_gen_path }}/{{ cacert_ca_name }}.csr" + privatekey_path: "{{ cacert_ssl_gen_path }}/{{ cacert_ca_name }}.key" + provider: selfsigned + register: cacert_ca_cert_gen + +- name: Distribute CA + become: true + block: + - name: CA and cert | Check if dest dir exist on remote hosts + file: + name: "{{ item.path }}" + state: directory + delegate_to: "{{ item.host }}" + loop: "{{ cacert_ca_copy_to }}" + when: + - cacert_ca_copy_to is defined + + - name: Put CA OpenSSL cert + copy: + src: "{{ cacert_ssl_gen_path }}/{{ cacert_ca_name }}.crt" + dest: "{{ item.path }}/{{ cacert_ca_name }}.crt" + delegate_to: "{{ item.host }}" + loop: "{{ cacert_ca_copy_to }}" + when: + - cacert_ca_copy_to is defined + + - name: Put CA OpenSSL cert to PKI + copy: + src: "{{ cacert_ssl_gen_path }}/{{ cacert_ca_name }}.crt" + dest: "/etc/pki/ca-trust/source/anchors/{{ cacert_ca_name }}.crt" + when: + - cacert_ca_trust_anchors_update + register: ca_trust_anchors + delegate_to: "{{ item.host }}" + loop: "{{ cacert_ca_copy_to }}" + + - name: Update CA trust + shell: update-ca-trust extract + when: + - ca_trust_anchors.changed + - cacert_ca_trust_anchors_update + delegate_to: "{{ item.host }}" + loop: "{{ cacert_ca_copy_to }}" diff --git a/tasks/certs.yaml b/tasks/certs.yaml new file mode 100644 index 0000000..4388d4c --- /dev/null +++ b/tasks/certs.yaml @@ -0,0 +1,108 @@ +- name: CA and cert | Check if dest dir exist on remote hosts + become: true + file: + name: "{{ dest.path }}" + state: directory + delegate_to: "{{ dest.host }}" + loop: "{{ item.dest }}" + loop_control: + loop_var: dest + +- name: CA and certs | Generate clients certs and keys + block: + - name: Generate an OpenSSL private client key with the default values (4096 bits, RSA) + community.crypto.openssl_privatekey: + path: "{{ cacert_ssl_gen_path }}/{{ item.name }}.key" + when: cacert_cert is not defined + register: cacert_client_key_gen + + - name: Generate subject_alt_ips + set_fact: + client_subject_alt_ips: "{{ item.subject_alt_ips | map('regex_replace', '^', 'IP:') | list }}" + when: item.subject_alt_ips is defined + + - name: Generate subject_alt_names + set_fact: + client_subject_alt_names: "{{ item.subject_alt_names | map('regex_replace', '^', 'DNS:') | list }}" + when: item.subject_alt_names is defined + + - name: Generate an OpenSSL Certificate Signing Request for client + community.crypto.openssl_csr: + path: "{{ cacert_ssl_gen_path }}/{{ item.name }}.csr" + privatekey_path: "{{ cacert_ssl_gen_path }}/{{ item.name }}.key" + common_name: "{{ item.name }}" + register: cacert_client_csr + when: + - item.subject_alt_names is not defined + - item.subject_alt_ips is not defined + + - name: Generate an OpenSSL Certificate Signing Request for client with subject_alt_name + community.crypto.openssl_csr: + path: "{{ cacert_ssl_gen_path }}/{{ item.name }}.csr" + privatekey_path: "{{ cacert_ssl_gen_path }}/{{ item.name }}.key" + common_name: "{{ item.name }}" + subject_alt_name: "{{ ((client_subject_alt_ips | default([])) + (client_subject_alt_names | default([]) + (['DNS:' ~ item.name]))) }}" + register: cacert_client_csr + when: item.subject_alt_names is defined or item.subject_alt_ips is defined + + - name: Generate an OpenSSL certificate for client signed with your own CA certificate + community.crypto.x509_certificate: + path: "{{ cacert_ssl_gen_path }}/{{ item.name }}.crt" + csr_path: "{{ cacert_ssl_gen_path }}/{{ item.name }}.csr" + ownca_path: "{{ cacert_ssl_gen_path }}/{{ cacert_ca_name }}.crt" + ownca_privatekey_path: "{{ cacert_ssl_gen_path }}/{{ cacert_ca_name }}.key" + provider: ownca + register: cacert_client_cert + + - name: Get {{ item.name }} OpenSSL crt and key content + ansible.builtin.shell: | + cat {{ cacert_ssl_gen_path }}/{{ item.name }}.{crt,key} + register: concated_crt_key + changed_when: false + + - name: Concatenate and save {{ item.name }} OpenSSL crt and key to single file + copy: + content: "{{ concated_crt_key.stdout }}" + dest: "{{ cacert_ssl_gen_path }}/{{ dest.name | default(item.name) }}.{{ dest.concat }}" + loop: "{{ item.dest }}" + loop_control: + loop_var: dest + when: + - dest.concat is defined + +- name: Distribute client certs + become: true + block: + - name: Write {{ item.name }} OpenSSL key + copy: + src: "{{ cacert_ssl_gen_path }}/{{ item.name }}.key" + dest: "{{ dest.path }}/{{ dest.name | default(item.name) }}.key" + mode: 0600 + delegate_to: "{{ dest.host }}" + loop: "{{ item.dest }}" + loop_control: + loop_var: dest + when: + - dest.concat is not defined + + - name: Write {{ item.name }} OpenSSL crt + copy: + src: "{{ cacert_ssl_gen_path }}/{{ item.name }}.crt" + dest: "{{ dest.path }}/{{ dest.name | default(item.name) }}.crt" + delegate_to: "{{ dest.host }}" + loop: "{{ item.dest }}" + loop_control: + loop_var: dest + when: + - dest.concat is not defined + + - name: Write concatenated {{ item.name }} OpenSSL crt and key + copy: + src: "{{ cacert_ssl_gen_path }}/{{ dest.name | default(item.name) }}.{{ dest.concat }}" + dest: "{{ dest.path }}/{{ dest.name | default(item.name) }}.{{ dest.concat }}" + delegate_to: "{{ dest.host }}" + loop: "{{ item.dest }}" + loop_control: + loop_var: dest + when: + - dest.concat is defined diff --git a/tasks/main.yaml b/tasks/main.yaml new file mode 100644 index 0000000..f784227 --- /dev/null +++ b/tasks/main.yaml @@ -0,0 +1,13 @@ +- name: CA and certs | Check if ssl gen dir exist + file: + name: "{{ cacert_ssl_gen_path }}" + state: directory + +- name: CA and certs | Include CA creation + include_tasks: ca.yaml + when: "inventory_hostname in groups.cacert_ca" + +- name: CA and certs | Include certs creation + include_tasks: certs.yaml + loop: "{{ cacert_certs }}" + when: "inventory_hostname in groups.cacert_ca"